tons of cursor-shit cleaning, finished implementing cnxId in observer
This commit is contained in:
+18
-42
@@ -14,10 +14,11 @@ export class gpsServer {
|
|||||||
|
|
||||||
constructor(configHelper, allRediscnx, debug) {
|
constructor(configHelper, allRediscnx, debug) {
|
||||||
this.configHelper = configHelper
|
this.configHelper = configHelper
|
||||||
this.gpsConfig = configHelper.config
|
this.rootConfig = configHelper.config
|
||||||
|
this.gpsConfig = configHelper.config.gps ?? {}
|
||||||
this.allRediscnx = allRediscnx
|
this.allRediscnx = allRediscnx
|
||||||
this.debug = debug
|
this.debug = debug
|
||||||
this.accessRights = new AccesRights(this.gpsConfig, debug)
|
this.accessRights = new AccesRights(this.rootConfig, debug)
|
||||||
this.agents = new Map()
|
this.agents = new Map()
|
||||||
this.registry = new CollisionRegistry()
|
this.registry = new CollisionRegistry()
|
||||||
this.arenaCnx = null
|
this.arenaCnx = null
|
||||||
@@ -33,33 +34,6 @@ export class gpsServer {
|
|||||||
this.ignoredChangeCount = 0
|
this.ignoredChangeCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
getGpsSettings() {
|
|
||||||
const gps = this.gpsConfig.gps ?? {}
|
|
||||||
return({
|
|
||||||
nearMissDistance: gps.nearMissDistance ?? 1,
|
|
||||||
prismTimeHeight: gps.prismTimeHeight ?? 60,
|
|
||||||
collisionTickMs: gps.collisionTickMs ?? 100,
|
|
||||||
prismRefreshLeadSeconds: gps.prismRefreshLeadSeconds ?? 1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getLifecycleSettings() {
|
|
||||||
const gps = this.gpsConfig.gps ?? {}
|
|
||||||
return({
|
|
||||||
arenaChannel: gps.lifecycle?.arenaChannel ?? 'arena:lifecycle',
|
|
||||||
godsReadyChannel: gps.lifecycle?.godsReadyChannel ?? 'arena:gods:ready',
|
|
||||||
senderId: gps.senderId ?? 'gps',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getArenaStorageSettings() {
|
|
||||||
const gps = this.gpsConfig.gps ?? {}
|
|
||||||
return({
|
|
||||||
agentHashKey: gps.arenaStorage?.agentHashKey ?? 'arena:agents:[UID]',
|
|
||||||
agentsIndexKey: gps.arenaStorage?.agentsIndexKey ?? 'arena:agents',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
isLive() {
|
isLive() {
|
||||||
return(this.state === SimState.LIVE)
|
return(this.state === SimState.LIVE)
|
||||||
}
|
}
|
||||||
@@ -103,7 +77,7 @@ export class gpsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initAgentStore() {
|
initAgentStore() {
|
||||||
const gpsStorage = this.gpsConfig.gps?.GPSstorage
|
const gpsStorage = this.gpsConfig.GPSstorage
|
||||||
if(gpsStorage && this.systemCnx) {
|
if(gpsStorage && this.systemCnx) {
|
||||||
this.agentStore = new AgentStore(this.systemCnx, gpsStorage, this.debug)
|
this.agentStore = new AgentStore(this.systemCnx, gpsStorage, this.debug)
|
||||||
}
|
}
|
||||||
@@ -114,7 +88,10 @@ export class gpsServer {
|
|||||||
this.arenaCnxs.push(cnx)
|
this.arenaCnxs.push(cnx)
|
||||||
if(!this.arenaCnx || cnx.redisConfig.role === 'primary') {
|
if(!this.arenaCnx || cnx.redisConfig.role === 'primary') {
|
||||||
this.arenaCnx = cnx
|
this.arenaCnx = cnx
|
||||||
this.arenaLoader = new ArenaAgentLoader(cnx, this.getArenaStorageSettings(), this.debug)
|
const arenaStorage = this.gpsConfig.arenaStorage
|
||||||
|
if(arenaStorage) {
|
||||||
|
this.arenaLoader = new ArenaAgentLoader(cnx, arenaStorage, this.debug)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,7 +171,7 @@ export class gpsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runInitialPairScan() {
|
runInitialPairScan() {
|
||||||
const { nearMissDistance, prismTimeHeight } = this.getGpsSettings()
|
const { nearMissDistance, prismTimeHeight } = this.gpsConfig
|
||||||
const ids = [...this.agents.keys()]
|
const ids = [...this.agents.keys()]
|
||||||
for(let i = 0; i < ids.length; i++) {
|
for(let i = 0; i < ids.length; i++) {
|
||||||
for(let j = i + 1; j < ids.length; j++) {
|
for(let j = i + 1; j < ids.length; j++) {
|
||||||
@@ -213,10 +190,9 @@ export class gpsServer {
|
|||||||
|
|
||||||
async publishReadyToStart(result) {
|
async publishReadyToStart(result) {
|
||||||
if(!this.arenaCnx) return
|
if(!this.arenaCnx) return
|
||||||
const { godsReadyChannel, senderId } = this.getLifecycleSettings()
|
await this.arenaCnx.redisPublish(this.gpsConfig.lifecycle.godsReadyChannel, {
|
||||||
await this.arenaCnx.redisPublish(godsReadyChannel, {
|
|
||||||
eventType: 'readyToStart',
|
eventType: 'readyToStart',
|
||||||
sender: senderId,
|
sender: this.gpsConfig.senderId,
|
||||||
payload: {
|
payload: {
|
||||||
success: result.success,
|
success: result.success,
|
||||||
simulationId: this.simulationId,
|
simulationId: this.simulationId,
|
||||||
@@ -370,7 +346,7 @@ export class gpsServer {
|
|||||||
const agent = this.agents.get(agentId)
|
const agent = this.agents.get(agentId)
|
||||||
if(!agent) return(false)
|
if(!agent) return(false)
|
||||||
|
|
||||||
const { prismTimeHeight, prismRefreshLeadSeconds } = this.getGpsSettings()
|
const { prismTimeHeight, prismRefreshLeadSeconds } = this.gpsConfig
|
||||||
const now = this.now()
|
const now = this.now()
|
||||||
if(!needsPrismRefresh(agent, now, prismTimeHeight, prismRefreshLeadSeconds)) return(false)
|
if(!needsPrismRefresh(agent, now, prismTimeHeight, prismRefreshLeadSeconds)) return(false)
|
||||||
|
|
||||||
@@ -390,7 +366,7 @@ export class gpsServer {
|
|||||||
const changed = this.agents.get(changedAgentId)
|
const changed = this.agents.get(changedAgentId)
|
||||||
if(!changed) return([])
|
if(!changed) return([])
|
||||||
|
|
||||||
const { nearMissDistance, prismTimeHeight } = this.getGpsSettings()
|
const { nearMissDistance, prismTimeHeight } = this.gpsConfig
|
||||||
const now = this.now()
|
const now = this.now()
|
||||||
const hits = []
|
const hits = []
|
||||||
for(const [otherId, other] of this.agents) {
|
for(const [otherId, other] of this.agents) {
|
||||||
@@ -459,14 +435,14 @@ export class gpsServer {
|
|||||||
|
|
||||||
async publishProximityBatch(targetAgentId, pairs) {
|
async publishProximityBatch(targetAgentId, pairs) {
|
||||||
if(!this.arenaCnx || !pairs.length) return
|
if(!this.arenaCnx || !pairs.length) return
|
||||||
const chan = this.arenaCnx.config.gps.collisionsChannel.replace(/\[UID\]/g, targetAgentId)
|
const chan = this.gpsConfig.collisionsChannel.replace(/\[UID\]/g, targetAgentId)
|
||||||
await this.arenaCnx.redisPublish(chan, {
|
await this.arenaCnx.redisPublish(chan, {
|
||||||
eventType: 'proximity',
|
eventType: 'proximity',
|
||||||
payload: {
|
payload: {
|
||||||
pairs,
|
pairs,
|
||||||
simulationId: this.simulationId,
|
simulationId: this.simulationId,
|
||||||
},
|
},
|
||||||
sender: this.getLifecycleSettings().senderId,
|
sender: this.gpsConfig.senderId,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,12 +467,12 @@ export class gpsServer {
|
|||||||
|
|
||||||
async reloadAccessRights() {
|
async reloadAccessRights() {
|
||||||
await this.configHelper.refreshAccessRights()
|
await this.configHelper.refreshAccessRights()
|
||||||
this.gpsConfig.accessRights = this.configHelper.config.accessRights
|
this.rootConfig.accessRights = this.configHelper.config.accessRights
|
||||||
this.accessRights.refreshAccessRights(this.gpsConfig)
|
this.accessRights.refreshAccessRights(this.rootConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccessRights() {
|
getAccessRights() {
|
||||||
return(this.gpsConfig.accessRights)
|
return(this.rootConfig.accessRights)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
export const eventHandlers = {
|
export const eventHandlers = {
|
||||||
'arena:agents:*': {
|
'arena:agents:*': {
|
||||||
change(msg, chan) {
|
change(msg, chan, sender, cnxId) {
|
||||||
const agentId = msg.sender
|
const agentId = msg.sender
|
||||||
if(!agentId || typeof(agentId) !== 'string') {
|
if(!agentId || typeof(agentId) !== 'string') {
|
||||||
console.warn(`[${this.redisId}] Agent event without sender`)
|
console.warn(`[${this.redisId}] Agent event without sender`)
|
||||||
@@ -15,7 +15,7 @@ export const eventHandlers = {
|
|||||||
const newPosition = msg.payload?.newPosition ?? null
|
const newPosition = msg.payload?.newPosition ?? null
|
||||||
this.gpsSrv?.onVectorChange(agentId, newVector, newPosition)
|
this.gpsSrv?.onVectorChange(agentId, newVector, newPosition)
|
||||||
},
|
},
|
||||||
remove(msg, chan) {
|
remove(msg, chan, sender, cnxId) {
|
||||||
const agentId = msg.sender
|
const agentId = msg.sender
|
||||||
if(!agentId || typeof(agentId) !== 'string') {
|
if(!agentId || typeof(agentId) !== 'string') {
|
||||||
console.warn(`[${this.redisId}] Agent event without sender`)
|
console.warn(`[${this.redisId}] Agent event without sender`)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const dispatchMessage = createDispatchMessage({
|
|||||||
eventHandlers,
|
eventHandlers,
|
||||||
actionRules(redisCnx) {
|
actionRules(redisCnx) {
|
||||||
const gps = redisCnx.config.gps ?? {}
|
const gps = redisCnx.config.gps ?? {}
|
||||||
const arenaChannel = gps.bus?.arena?.actionsChannel
|
const arenaChannel = gps.arenaActionsChannel
|
||||||
return({
|
return({
|
||||||
channels: arenaChannel ? [arenaChannel] : [],
|
channels: arenaChannel ? [arenaChannel] : [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
export function construct(redisCnx) {
|
export function construct(redisCnx) {
|
||||||
const tickMs = redisCnx.gpsSrv?.getGpsSettings().collisionTickMs ?? 100
|
const tickMs = redisCnx.gpsSrv?.gpsConfig.collisionTickMs ?? 100
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
redisCnx.gpsSrv?.tickArena()
|
redisCnx.gpsSrv?.tickArena()
|
||||||
}, tickMs)
|
}, tickMs)
|
||||||
@@ -8,7 +8,7 @@ export function construct(redisCnx) {
|
|||||||
|
|
||||||
export const eventHandlers = {
|
export const eventHandlers = {
|
||||||
'arena:lifecycle': {
|
'arena:lifecycle': {
|
||||||
onYourMarks(msg, chan) {
|
onYourMarks(msg, chan, sender, cnxId) {
|
||||||
const srv = this.gpsSrv
|
const srv = this.gpsSrv
|
||||||
if(!srv) return
|
if(!srv) return
|
||||||
srv.onYourMarks(msg.payload ?? {}).catch(err => {
|
srv.onYourMarks(msg.payload ?? {}).catch(err => {
|
||||||
@@ -16,16 +16,16 @@ export const eventHandlers = {
|
|||||||
srv.publishReadyToStart({ success: false, err: err.message ?? 'onYourMarks failed' })
|
srv.publishReadyToStart({ success: false, err: err.message ?? 'onYourMarks failed' })
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
bigBang(msg, chan) {
|
bigBang(msg, chan, sender, cnxId) {
|
||||||
this.gpsSrv?.onBigBang(msg.payload ?? {})
|
this.gpsSrv?.onBigBang(msg.payload ?? {})
|
||||||
},
|
},
|
||||||
simulationPaused(msg, chan) {
|
simulationPaused(msg, chan, sender, cnxId) {
|
||||||
this.gpsSrv?.onSimulationPaused(msg.payload ?? {})
|
this.gpsSrv?.onSimulationPaused(msg.payload ?? {})
|
||||||
},
|
},
|
||||||
simulationResumed(msg, chan) {
|
simulationResumed(msg, chan, sender, cnxId) {
|
||||||
this.gpsSrv?.onSimulationResumed(msg.payload ?? {})
|
this.gpsSrv?.onSimulationResumed(msg.payload ?? {})
|
||||||
},
|
},
|
||||||
simulationStopped(msg, chan) {
|
simulationStopped(msg, chan, sender, cnxId) {
|
||||||
const srv = this.gpsSrv
|
const srv = this.gpsSrv
|
||||||
if(!srv) return
|
if(!srv) return
|
||||||
srv.onSimulationStopped(msg.payload ?? {}).catch(err => {
|
srv.onSimulationStopped(msg.payload ?? {}).catch(err => {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const dispatchMessage = createDispatchMessage({
|
|||||||
actionRules(redisCnx) {
|
actionRules(redisCnx) {
|
||||||
const gps = redisCnx.config.gps ?? {}
|
const gps = redisCnx.config.gps ?? {}
|
||||||
return({
|
return({
|
||||||
channels: [gps.gpsActionsChannel].filter(Boolean),
|
channels: [gps.ActionsChannel].filter(Boolean),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ import { replyToAction } from '../../../bus/publishActionReply.js'
|
|||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
|
|
||||||
async action_TIME(action, payload, reqid, sender, roles) {
|
async action_TIME(action, payload, reqid, sender, cnxId, roles) {
|
||||||
replyToAction(this, {
|
replyToAction(this, {
|
||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: {
|
payload: {
|
||||||
gpsTime: new Date().toISOString(),
|
gpsTime: new Date().toISOString(),
|
||||||
@@ -15,16 +16,17 @@ export const actions = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async action_RELOADCONFIG(action, payload, reqid, sender, roles) {
|
async action_RELOADCONFIG(action, payload, reqid, sender, cnxId, roles) {
|
||||||
this.reloadAccessRights()
|
this.reloadAccessRights()
|
||||||
replyToAction(this, { action, reqid, sender, success: true })
|
replyToAction(this, { action, reqid, sender, cnxId, success: true })
|
||||||
},
|
},
|
||||||
|
|
||||||
async action_GETCONFIG(action, payload, reqid, sender, roles) {
|
async action_GETCONFIG(action, payload, reqid, sender, cnxId, roles) {
|
||||||
replyToAction(this, {
|
replyToAction(this, {
|
||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: this.getAccessRights(),
|
payload: this.getAccessRights(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const dispatchMessage = createDispatchMessage({
|
|||||||
eventHandlers,
|
eventHandlers,
|
||||||
actionRules(redisCnx) {
|
actionRules(redisCnx) {
|
||||||
const maestro = redisCnx.config.maestro ?? {}
|
const maestro = redisCnx.config.maestro ?? {}
|
||||||
const arenaChannel = maestro.bus?.arena?.actionsChannel
|
const arenaChannel = maestro.arenaActionsChannel
|
||||||
return({
|
return({
|
||||||
channels: arenaChannel ? [arenaChannel] : [],
|
channels: arenaChannel ? [arenaChannel] : [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
export const eventHandlers = {
|
export const eventHandlers = {
|
||||||
'arena:gods:ready': {
|
'arena:gods:ready': {
|
||||||
readyToStart(msg, chan) {
|
readyToStart(msg, chan, sender, cnxId) {
|
||||||
if(!this.maestroSrv) return
|
if(!this.maestroSrv) return
|
||||||
this.maestroSrv.handlePrepareAck(msg, chan)
|
this.maestroSrv.handlePrepareAck(msg, chan)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const dispatchMessage = createDispatchMessage({
|
|||||||
actionRules(redisCnx) {
|
actionRules(redisCnx) {
|
||||||
const maestro = redisCnx.config.maestro ?? {}
|
const maestro = redisCnx.config.maestro ?? {}
|
||||||
return({
|
return({
|
||||||
channels: [maestro.maestroActionsChannel].filter(Boolean),
|
channels: [maestro.ActionsChannel].filter(Boolean),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,20 +3,20 @@ import { isValidUuid } from '../../simRepository.js'
|
|||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
|
|
||||||
async action_STARTSIMULATION(action, payload, reqid, sender, roles) {
|
async action_STARTSIMULATION(action, payload, reqid, sender, cnxId, roles) {
|
||||||
if(!isValidUuid(sender)) {
|
if(!isValidUuid(sender)) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Missing or invalid sender (user UUID)' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing or invalid sender (user UUID)' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!payload?.simulationUuid) {
|
if(!payload?.simulationUuid) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Missing simulationUuid' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing simulationUuid' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.maestroSrv.startSimulation(sender, payload)
|
const result = await this.maestroSrv.startSimulation(sender, payload)
|
||||||
if(!result.ok) {
|
if(!result.ok) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: result.err })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: result.err })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ export const actions = {
|
|||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: {
|
payload: {
|
||||||
simulationId: result.simulationId,
|
simulationId: result.simulationId,
|
||||||
@@ -36,20 +37,20 @@ export const actions = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async action_PAUSESIMULATION(action, payload, reqid, sender, roles) {
|
async action_PAUSESIMULATION(action, payload, reqid, sender, cnxId, roles) {
|
||||||
if(!isValidUuid(sender)) {
|
if(!isValidUuid(sender)) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Missing or invalid sender (user UUID)' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing or invalid sender (user UUID)' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!payload?.simulationUuid) {
|
if(!payload?.simulationUuid) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Missing simulationUuid' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing simulationUuid' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.maestroSrv.pauseSimulation(sender, payload)
|
const result = await this.maestroSrv.pauseSimulation(sender, payload)
|
||||||
if(!result.ok) {
|
if(!result.ok) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: result.err })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: result.err })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ export const actions = {
|
|||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: {
|
payload: {
|
||||||
simulationId: result.simulationId,
|
simulationId: result.simulationId,
|
||||||
@@ -65,20 +67,20 @@ export const actions = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async action_STOPSIMULATION(action, payload, reqid, sender, roles) {
|
async action_STOPSIMULATION(action, payload, reqid, sender, cnxId, roles) {
|
||||||
if(!isValidUuid(sender)) {
|
if(!isValidUuid(sender)) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Missing or invalid sender (user UUID)' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing or invalid sender (user UUID)' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!payload?.simulationUuid) {
|
if(!payload?.simulationUuid) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Missing simulationUuid' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing simulationUuid' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.maestroSrv.stopSimulation(sender, payload)
|
const result = await this.maestroSrv.stopSimulation(sender, payload)
|
||||||
if(!result.ok) {
|
if(!result.ok) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: result.err })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: result.err })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,20 +88,21 @@ export const actions = {
|
|||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: { simulationId: result.simulationId },
|
payload: { simulationId: result.simulationId },
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async action_GETSIMULATIONSSTATUS(action, payload, reqid, sender, roles) {
|
async action_GETSIMULATIONSSTATUS(action, payload, reqid, sender, cnxId, roles) {
|
||||||
if(!isValidUuid(sender)) {
|
if(!isValidUuid(sender)) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Missing or invalid sender (user UUID)' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing or invalid sender (user UUID)' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.maestroSrv.getSimulationsStatus(sender)
|
const result = await this.maestroSrv.getSimulationsStatus(sender)
|
||||||
if(!result.ok) {
|
if(!result.ok) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: result.err })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: result.err })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +110,7 @@ export const actions = {
|
|||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: result.simulations,
|
payload: result.simulations,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,16 +2,17 @@ import { replyToAction } from '../../../bus/publishActionReply.js'
|
|||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
|
|
||||||
async action_RELOADCONFIG(action, payload, reqid, sender, roles) {
|
async action_RELOADCONFIG(action, payload, reqid, sender, cnxId, roles) {
|
||||||
this.reloadAccessRights()
|
this.reloadAccessRights()
|
||||||
replyToAction(this, { action, reqid, sender, success: true })
|
replyToAction(this, { action, reqid, sender, cnxId, success: true })
|
||||||
},
|
},
|
||||||
|
|
||||||
async action_GETCONFIG(action, payload, reqid, sender, roles) {
|
async action_GETCONFIG(action, payload, reqid, sender, cnxId, roles) {
|
||||||
replyToAction(this, {
|
replyToAction(this, {
|
||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: this.getAccessRights(),
|
payload: this.getAccessRights(),
|
||||||
})
|
})
|
||||||
|
|||||||
+18
-38
@@ -10,10 +10,12 @@ export class maestroServer {
|
|||||||
|
|
||||||
constructor(configHelper, allRediscnx, debug) {
|
constructor(configHelper, allRediscnx, debug) {
|
||||||
this.configHelper = configHelper
|
this.configHelper = configHelper
|
||||||
this.maestroConfig = configHelper.config
|
this.rootConfig = configHelper.config
|
||||||
|
this.maestroConfig = configHelper.config.maestro ?? {}
|
||||||
|
this.gpsConfig = configHelper.config.gps ?? {}
|
||||||
this.allRediscnx = allRediscnx
|
this.allRediscnx = allRediscnx
|
||||||
this.debug = debug
|
this.debug = debug
|
||||||
this.accessRights = new AccesRights(this.maestroConfig, debug)
|
this.accessRights = new AccesRights(this.rootConfig, debug)
|
||||||
this.arenaCnx = null
|
this.arenaCnx = null
|
||||||
this.arenaCnxs = []
|
this.arenaCnxs = []
|
||||||
this.systemCnx = null
|
this.systemCnx = null
|
||||||
@@ -31,26 +33,6 @@ export class maestroServer {
|
|||||||
this.pausedAt = null
|
this.pausedAt = null
|
||||||
}
|
}
|
||||||
|
|
||||||
getMaestroSettings() {
|
|
||||||
const maestro = this.maestroConfig.maestro ?? {}
|
|
||||||
return({
|
|
||||||
senderId: maestro.senderId ?? 'maestro',
|
|
||||||
lifecycle: {
|
|
||||||
arenaChannel: maestro.lifecycle?.arenaChannel ?? 'arena:lifecycle',
|
|
||||||
prepareAckChannel: maestro.lifecycle?.godsReadyChannel ?? 'arena:gods:ready',
|
|
||||||
},
|
|
||||||
readyTimeoutMs: maestro.readyTimeoutMs ?? 30000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getArenaStorageSettings() {
|
|
||||||
const gps = this.maestroConfig.gps ?? {}
|
|
||||||
return({
|
|
||||||
agentHashKey: gps.arenaStorage?.agentHashKey ?? 'arena:agents:[UID]',
|
|
||||||
agentsIndexKey: gps.arenaStorage?.agentsIndexKey ?? 'arena:agents',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
isIdle() {
|
isIdle() {
|
||||||
return(this.orchestrationState === MaestroState.IDLE)
|
return(this.orchestrationState === MaestroState.IDLE)
|
||||||
}
|
}
|
||||||
@@ -72,7 +54,7 @@ export class maestroServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
const mysqlCfg = this.maestroConfig.mysql
|
const mysqlCfg = this.rootConfig.mysql
|
||||||
if(!mysqlCfg) {
|
if(!mysqlCfg) {
|
||||||
console.error('[Maestro] Missing mysql config')
|
console.error('[Maestro] Missing mysql config')
|
||||||
return(false)
|
return(false)
|
||||||
@@ -84,10 +66,11 @@ export class maestroServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refreshArenaGroom() {
|
refreshArenaGroom() {
|
||||||
if(this.arenaCnx) {
|
const arenaStorage = this.gpsConfig.arenaStorage
|
||||||
|
if(this.arenaCnx && arenaStorage) {
|
||||||
this.arenaGroom = new ArenaGroom(
|
this.arenaGroom = new ArenaGroom(
|
||||||
this.arenaCnx,
|
this.arenaCnx,
|
||||||
this.getArenaStorageSettings(),
|
arenaStorage,
|
||||||
this.debug
|
this.debug
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -95,10 +78,9 @@ export class maestroServer {
|
|||||||
|
|
||||||
refreshPrepareQuorum() {
|
refreshPrepareQuorum() {
|
||||||
if(!this.arenaCnx) return
|
if(!this.arenaCnx) return
|
||||||
const { lifecycle, readyTimeoutMs } = this.getMaestroSettings()
|
|
||||||
this.prepareQuorum = new PrepareQuorum({
|
this.prepareQuorum = new PrepareQuorum({
|
||||||
ackChannel: lifecycle.prepareAckChannel,
|
ackChannel: this.maestroConfig.lifecycle.godsReadyChannel,
|
||||||
timeoutMs: readyTimeoutMs,
|
timeoutMs: this.maestroConfig.readyTimeoutMs,
|
||||||
matchesChan: this.arenaCnx.matchesChan.bind(this.arenaCnx),
|
matchesChan: this.arenaCnx.matchesChan.bind(this.arenaCnx),
|
||||||
debug: this.debug,
|
debug: this.debug,
|
||||||
})
|
})
|
||||||
@@ -144,11 +126,10 @@ export class maestroServer {
|
|||||||
|
|
||||||
async publishLifecycle(eventType, payload, state = null) {
|
async publishLifecycle(eventType, payload, state = null) {
|
||||||
if(!this.arenaCnx) throw(new Error('No arena Redis connection'))
|
if(!this.arenaCnx) throw(new Error('No arena Redis connection'))
|
||||||
const { arenaChannel, senderId } = this.getMaestroSettings().lifecycle
|
|
||||||
const resolvedState = state ?? this.orchestrationStateFor(payload?.simulationId ?? this.simulationId)
|
const resolvedState = state ?? this.orchestrationStateFor(payload?.simulationId ?? this.simulationId)
|
||||||
await this.arenaCnx.redisPublish(arenaChannel, {
|
await this.arenaCnx.redisPublish(this.maestroConfig.lifecycle.arenaChannel, {
|
||||||
eventType,
|
eventType,
|
||||||
sender: senderId,
|
sender: this.maestroConfig.senderId,
|
||||||
payload,
|
payload,
|
||||||
})
|
})
|
||||||
await this.publishSystemLifecycle(eventType, payload, resolvedState)
|
await this.publishSystemLifecycle(eventType, payload, resolvedState)
|
||||||
@@ -164,9 +145,8 @@ export class maestroServer {
|
|||||||
const ownersResult = await this.simRepo.listSimulationOwnerUuids(simulationId)
|
const ownersResult = await this.simRepo.listSimulationOwnerUuids(simulationId)
|
||||||
if(!ownersResult.ok || !ownersResult.ownerUuids.length) return
|
if(!ownersResult.ok || !ownersResult.ownerUuids.length) return
|
||||||
|
|
||||||
const maestro = this.maestroConfig.maestro ?? {}
|
const channelTemplate = this.maestroConfig.systemLifecycleChannel
|
||||||
const channelTemplate = maestro.systemLifecycleChannel ?? 'system:maestro:lifecycle:[UID]'
|
const senderId = this.maestroConfig.senderId
|
||||||
const senderId = maestro.senderId ?? 'maestro'
|
|
||||||
const msg = {
|
const msg = {
|
||||||
eventType,
|
eventType,
|
||||||
sender: senderId,
|
sender: senderId,
|
||||||
@@ -219,7 +199,7 @@ export class maestroServer {
|
|||||||
infraId,
|
infraId,
|
||||||
}
|
}
|
||||||
|
|
||||||
const expectedParticipants = buildPrepareQuorum(this.agentIds, this.maestroConfig)
|
const expectedParticipants = buildPrepareQuorum(this.agentIds, this.rootConfig)
|
||||||
const readyWait = this.prepareQuorum.begin(expectedParticipants, this.simulationId)
|
const readyWait = this.prepareQuorum.begin(expectedParticipants, this.simulationId)
|
||||||
|
|
||||||
await this.publishLifecycle('onYourMarks', lifecyclePayload)
|
await this.publishLifecycle('onYourMarks', lifecyclePayload)
|
||||||
@@ -410,12 +390,12 @@ export class maestroServer {
|
|||||||
|
|
||||||
async reloadAccessRights() {
|
async reloadAccessRights() {
|
||||||
await this.configHelper.refreshAccessRights()
|
await this.configHelper.refreshAccessRights()
|
||||||
this.maestroConfig.accessRights = this.configHelper.config.accessRights
|
this.rootConfig.accessRights = this.configHelper.config.accessRights
|
||||||
this.accessRights.refreshAccessRights(this.maestroConfig)
|
this.accessRights.refreshAccessRights(this.rootConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccessRights() {
|
getAccessRights() {
|
||||||
return(this.maestroConfig.accessRights)
|
return(this.rootConfig.accessRights)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const dispatchMessage = createDispatchMessage({
|
|||||||
eventHandlers,
|
eventHandlers,
|
||||||
actionRules(redisCnx) {
|
actionRules(redisCnx) {
|
||||||
const observer = redisCnx.config.observer ?? {}
|
const observer = redisCnx.config.observer ?? {}
|
||||||
const arenaChannel = observer.bus?.arena?.actionsChannel
|
const arenaChannel = observer.arenaActionsChannel
|
||||||
return({
|
return({
|
||||||
channels: arenaChannel ? [arenaChannel] : [],
|
channels: arenaChannel ? [arenaChannel] : [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
|
|
||||||
export const eventHandlers = {
|
export const eventHandlers = {
|
||||||
'arena:lifecycle': {
|
'arena:lifecycle': {
|
||||||
onYourMarks(msg, chan) {
|
onYourMarks(msg, chan, sender, cnxId) {
|
||||||
this.observerSrv?.onYourMarks()
|
this.observerSrv?.onYourMarks()
|
||||||
},
|
},
|
||||||
bigBang(msg, chan) {
|
bigBang(msg, chan, sender, cnxId) {
|
||||||
this.observerSrv?.onBigBang()
|
this.observerSrv?.onBigBang()
|
||||||
},
|
},
|
||||||
simulationStopped(msg, chan) {
|
simulationStopped(msg, chan, sender, cnxId) {
|
||||||
this.observerSrv?.onSimulationStopped(msg.payload ?? {})
|
this.observerSrv?.onSimulationStopped(msg.payload ?? {})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const dispatchMessage = createDispatchMessage({
|
|||||||
actionRules(redisCnx) {
|
actionRules(redisCnx) {
|
||||||
const observer = redisCnx.config.observer ?? {}
|
const observer = redisCnx.config.observer ?? {}
|
||||||
return({
|
return({
|
||||||
channels: [observer.observerActionsChannel].filter(Boolean),
|
channels: [observer.ActionsChannel].filter(Boolean),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,66 +4,66 @@ import { Frustum } from '../../frustum.js'
|
|||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
|
|
||||||
async action_GETAGENTPOSITION(action, payload, reqid, sender, roles) {
|
async action_GETAGENTPOSITION(action, payload, reqid, sender, cnxId, roles) {
|
||||||
const reader = this.observerSrv.gpsStorageReader
|
const reader = this.observerSrv.gpsStorageReader
|
||||||
if(!reader) {
|
if(!reader) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'GPS storage reader not ready' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'GPS storage reader not ready' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.observerSrv.isLive()) {
|
if(!this.observerSrv.isLive()) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Simulation not live' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Simulation not live' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const agentId = payload?.agentId
|
const agentId = payload?.agentId
|
||||||
if(!agentId || typeof(agentId) !== 'string') {
|
if(!agentId || typeof(agentId) !== 'string') {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Missing or invalid agentId' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing or invalid agentId' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const at = parseSimTime(payload, () => this.observerSrv.now())
|
const at = parseSimTime(payload, () => this.observerSrv.now())
|
||||||
if(at === null) {
|
if(at === null) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Invalid simulation time' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Invalid simulation time' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const agent = await reader.getAgentPosition(agentId, at)
|
const agent = await reader.getAgentPosition(agentId, at)
|
||||||
if(!agent) {
|
if(!agent) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: `Unknown agent: ${agentId}` })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: `Unknown agent: ${agentId}` })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
replyToAction(this, { action, reqid, sender, success: true, payload: { agent } })
|
replyToAction(this, { action, reqid, sender, cnxId, success: true, payload: { agent } })
|
||||||
},
|
},
|
||||||
|
|
||||||
async action_GETAGENTSINFRUSTUM(action, payload, reqid, sender, roles) {
|
async action_GETAGENTSINFRUSTUM(action, payload, reqid, sender, cnxId, roles) {
|
||||||
const registry = this.observerSrv.requestorRegistry
|
const registry = this.observerSrv.requestorRegistry
|
||||||
if(!registry) {
|
if(!registry) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Requestor registry not ready' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Requestor registry not ready' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.observerSrv.isLive()) {
|
if(!this.observerSrv.isLive()) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Simulation not live' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Simulation not live' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const frustum = Frustum.fromPlanes(payload?.planes)
|
const frustum = Frustum.fromPlanes(payload?.planes)
|
||||||
if(!frustum) {
|
if(!frustum) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Missing or invalid frustum planes (expected 6)' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing or invalid frustum planes (expected 6)' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const at = parseSimTime(payload, () => this.observerSrv.now())
|
const at = parseSimTime(payload, () => this.observerSrv.now())
|
||||||
if(at === null) {
|
if(at === null) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Invalid simulation time' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Invalid simulation time' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await registry.evaluateOnce({ frustum, t: at })
|
const result = await registry.evaluateOnce({ frustum, t: at })
|
||||||
if(!result.ok) {
|
if(!result.ok) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: result.err })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: result.err })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +71,7 @@ export const actions = {
|
|||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: {
|
payload: {
|
||||||
agents: result.agents,
|
agents: result.agents,
|
||||||
@@ -79,24 +80,29 @@ export const actions = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async action_SUBSCRIBEFRUSTUM(action, payload, reqid, sender, roles) {
|
async action_SUBSCRIBEFRUSTUM(action, payload, reqid, sender, cnxId, roles) {
|
||||||
const registry = this.observerSrv.requestorRegistry
|
const registry = this.observerSrv.requestorRegistry
|
||||||
if(!registry) {
|
if(!registry) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Requestor registry not ready' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Requestor registry not ready' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.observerSrv.isLive()) {
|
if(!this.observerSrv.isLive()) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Simulation not live' })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Simulation not live' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await registry.subscribeFrustum(sender, {
|
if(!cnxId || typeof(cnxId) !== 'string') {
|
||||||
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: 'Missing or invalid cnxId' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await registry.subscribeFrustum(cnxId, {
|
||||||
planes: payload?.planes,
|
planes: payload?.planes,
|
||||||
frequency: payload?.frequency,
|
frequency: payload?.frequency,
|
||||||
})
|
})
|
||||||
if(!result.ok) {
|
if(!result.ok) {
|
||||||
replyToAction(this, { action, reqid, sender, success: false, err: result.err })
|
replyToAction(this, { action, reqid, sender, cnxId, success: false, err: result.err })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +110,7 @@ export const actions = {
|
|||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: {
|
payload: {
|
||||||
frequency: result.frequency,
|
frequency: result.frequency,
|
||||||
|
|||||||
@@ -2,16 +2,17 @@ import { replyToAction } from '../../../bus/publishActionReply.js'
|
|||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
|
|
||||||
async action_RELOADCONFIG(action, payload, reqid, sender, roles) {
|
async action_RELOADCONFIG(action, payload, reqid, sender, cnxId, roles) {
|
||||||
this.reloadAccessRights()
|
this.reloadAccessRights()
|
||||||
replyToAction(this, { action, reqid, sender, success: true })
|
replyToAction(this, { action, reqid, sender, cnxId, success: true })
|
||||||
},
|
},
|
||||||
|
|
||||||
async action_GETCONFIG(action, payload, reqid, sender, roles) {
|
async action_GETCONFIG(action, payload, reqid, sender, cnxId, roles) {
|
||||||
replyToAction(this, {
|
replyToAction(this, {
|
||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: true,
|
success: true,
|
||||||
payload: this.getAccessRights(),
|
payload: this.getAccessRights(),
|
||||||
})
|
})
|
||||||
|
|||||||
+13
-29
@@ -7,10 +7,12 @@ export class observerServer {
|
|||||||
|
|
||||||
constructor(configHelper, allRediscnx, debug) {
|
constructor(configHelper, allRediscnx, debug) {
|
||||||
this.configHelper = configHelper
|
this.configHelper = configHelper
|
||||||
this.observerConfig = configHelper.config
|
this.rootConfig = configHelper.config
|
||||||
|
this.observerConfig = configHelper.config.observer ?? {}
|
||||||
|
this.gpsConfig = configHelper.config.gps ?? {}
|
||||||
this.allRediscnx = allRediscnx
|
this.allRediscnx = allRediscnx
|
||||||
this.debug = debug
|
this.debug = debug
|
||||||
this.accessRights = new AccesRights(this.observerConfig, debug)
|
this.accessRights = new AccesRights(this.rootConfig, debug)
|
||||||
this.arenaCnx = null
|
this.arenaCnx = null
|
||||||
this.arenaCnxs = []
|
this.arenaCnxs = []
|
||||||
this.systemCnx = null
|
this.systemCnx = null
|
||||||
@@ -20,27 +22,8 @@ export class observerServer {
|
|||||||
this.bigBangEpoch = null
|
this.bigBangEpoch = null
|
||||||
}
|
}
|
||||||
|
|
||||||
getObserverSettings() {
|
|
||||||
const observer = this.observerConfig.observer ?? {}
|
|
||||||
return({
|
|
||||||
senderId: observer.senderId ?? 'observer',
|
|
||||||
scanIntervalMs: observer.scanIntervalMs ?? 300,
|
|
||||||
frustumEventsChannel: observer.observerFrustumEventsChannel
|
|
||||||
?? 'system:observer:subscribed[UID]:agents',
|
|
||||||
lifecycle: {
|
|
||||||
arenaChannel: observer.lifecycle?.arenaChannel ?? 'arena:lifecycle',
|
|
||||||
godsReadyChannel: observer.lifecycle?.godsReadyChannel ?? 'arena:gods:ready',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getGpsStorageSettings() {
|
|
||||||
const gps = this.observerConfig.gps ?? {}
|
|
||||||
return(gps.GPSstorage ?? null)
|
|
||||||
}
|
|
||||||
|
|
||||||
initGpsStorageReader() {
|
initGpsStorageReader() {
|
||||||
const gpsStorage = this.getGpsStorageSettings()
|
const gpsStorage = this.gpsConfig.GPSstorage
|
||||||
if(gpsStorage && this.systemCnx) {
|
if(gpsStorage && this.systemCnx) {
|
||||||
this.gpsStorageReader = new GpsStorageReader(this.systemCnx, gpsStorage, this.debug)
|
this.gpsStorageReader = new GpsStorageReader(this.systemCnx, gpsStorage, this.debug)
|
||||||
this.initRequestorRegistry()
|
this.initRequestorRegistry()
|
||||||
@@ -49,7 +32,7 @@ export class observerServer {
|
|||||||
|
|
||||||
initRequestorRegistry() {
|
initRequestorRegistry() {
|
||||||
if(!this.gpsStorageReader || this.requestorRegistry) return
|
if(!this.gpsStorageReader || this.requestorRegistry) return
|
||||||
const { scanIntervalMs } = this.getObserverSettings()
|
const { scanIntervalMs } = this.observerConfig
|
||||||
this.requestorRegistry = new RequestorRegistry(
|
this.requestorRegistry = new RequestorRegistry(
|
||||||
this.gpsStorageReader,
|
this.gpsStorageReader,
|
||||||
() => this.now(),
|
() => this.now(),
|
||||||
@@ -67,9 +50,9 @@ export class observerServer {
|
|||||||
if(!this.systemCnx || !subscriberId) return
|
if(!this.systemCnx || !subscriberId) return
|
||||||
if(!Array.isArray(agents) || !agents.length) return
|
if(!Array.isArray(agents) || !agents.length) return
|
||||||
|
|
||||||
const { frustumEventsChannel } = this.getObserverSettings()
|
const chan = this.observerConfig.FrustumEventsChannel
|
||||||
const chan = frustumEventsChannel.replace(/\[UID\]/g, subscriberId)
|
.replace(/\[CUID\]/g, subscriberId)
|
||||||
const senderId = this.getObserverSettings().senderId
|
const senderId = this.observerConfig.senderId
|
||||||
|
|
||||||
for(const agent of agents) {
|
for(const agent of agents) {
|
||||||
if(!agent?.id || !agent?.position) continue
|
if(!agent?.id || !agent?.position) continue
|
||||||
@@ -77,6 +60,7 @@ export class observerServer {
|
|||||||
await this.systemCnx.redisPublish(chan, {
|
await this.systemCnx.redisPublish(chan, {
|
||||||
eventType: 'move',
|
eventType: 'move',
|
||||||
sender: senderId,
|
sender: senderId,
|
||||||
|
cnxId: this.systemCnx.cnxId,
|
||||||
payload: {
|
payload: {
|
||||||
aid: agent.id,
|
aid: agent.id,
|
||||||
coords: {
|
coords: {
|
||||||
@@ -147,12 +131,12 @@ export class observerServer {
|
|||||||
|
|
||||||
async reloadAccessRights() {
|
async reloadAccessRights() {
|
||||||
await this.configHelper.refreshAccessRights()
|
await this.configHelper.refreshAccessRights()
|
||||||
this.observerConfig.accessRights = this.configHelper.config.accessRights
|
this.rootConfig.accessRights = this.configHelper.config.accessRights
|
||||||
this.accessRights.refreshAccessRights(this.observerConfig)
|
this.accessRights.refreshAccessRights(this.rootConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccessRights() {
|
getAccessRights() {
|
||||||
return(this.observerConfig.accessRights)
|
return(this.rootConfig.accessRights)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -27,14 +27,17 @@ export function assembleHandlers(modules) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createDispatchMessage({ eventHandlers, actionRules }) {
|
export function createDispatchMessage({ eventHandlers, eventRules, actionRules }) {
|
||||||
return(async function dispatchMessage(redisCnx, msg, chan) {
|
return(async function dispatchMessage(redisCnx, msg, chan) {
|
||||||
if(msg.action && msg.eventType) {
|
if(msg.action && msg.eventType) {
|
||||||
console.warn(`[${redisCnx.redisId}] Message has both action and eventType on ${chan}`)
|
console.warn(`[${redisCnx.redisId}] Message has both action and eventType on ${chan}`)
|
||||||
return(false)
|
return(false)
|
||||||
}
|
}
|
||||||
if(msg.action) return(dispatchActions(redisCnx, msg, chan, actionRules(redisCnx)))
|
if(msg.action) return(dispatchActions(redisCnx, msg, chan, actionRules(redisCnx)))
|
||||||
if(msg.eventType) return(dispatchEvents(redisCnx, msg, chan, eventHandlers))
|
if(msg.eventType) {
|
||||||
|
const handlers = eventRules ? eventRules(redisCnx) : eventHandlers
|
||||||
|
return(dispatchEvents(redisCnx, msg, chan, handlers))
|
||||||
|
}
|
||||||
return(false)
|
return(false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export async function dispatchActions(redisCnx, msg, chan, rules) {
|
|||||||
|
|
||||||
const action = msg.action
|
const action = msg.action
|
||||||
const sender = msg.sender ?? null
|
const sender = msg.sender ?? null
|
||||||
|
const cnxId = msg.cnxId ?? null
|
||||||
const reqid = ('reqid' in msg) ? msg.reqid.substr(0, 50) : null
|
const reqid = ('reqid' in msg) ? msg.reqid.substr(0, 50) : null
|
||||||
const roles = Array.isArray(msg.roles) ? msg.roles : ['*']
|
const roles = Array.isArray(msg.roles) ? msg.roles : ['*']
|
||||||
|
|
||||||
@@ -21,8 +22,9 @@ export async function dispatchActions(redisCnx, msg, chan, rules) {
|
|||||||
if(!sender) return(true)
|
if(!sender) return(true)
|
||||||
replyToAction(redisCnx, {
|
replyToAction(redisCnx, {
|
||||||
action,
|
action,
|
||||||
reqid,
|
|
||||||
sender,
|
sender,
|
||||||
|
reqid,
|
||||||
|
cnxId,
|
||||||
success: false,
|
success: false,
|
||||||
err: 'Missing or invalid action',
|
err: 'Missing or invalid action',
|
||||||
})
|
})
|
||||||
@@ -39,6 +41,7 @@ export async function dispatchActions(redisCnx, msg, chan, rules) {
|
|||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: false,
|
success: false,
|
||||||
err: 'Unauthorized action !',
|
err: 'Unauthorized action !',
|
||||||
})
|
})
|
||||||
@@ -51,6 +54,7 @@ export async function dispatchActions(redisCnx, msg, chan, rules) {
|
|||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: false,
|
success: false,
|
||||||
err: `Unknown action: ${action}`,
|
err: `Unknown action: ${action}`,
|
||||||
})
|
})
|
||||||
@@ -62,13 +66,14 @@ export async function dispatchActions(redisCnx, msg, chan, rules) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await handler.call(redisCnx, action, ('payload' in msg) ? msg.payload : null, reqid, sender, roles)
|
await handler.call(redisCnx, action, ('payload' in msg) ? msg.payload : null, reqid, sender, cnxId, roles)
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.error(`[${redisCnx.redisId}] Action ${action} failed:`, err)
|
console.error(`[${redisCnx.redisId}] Action ${action} failed:`, err)
|
||||||
replyToAction(redisCnx, {
|
replyToAction(redisCnx, {
|
||||||
action,
|
action,
|
||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
|
cnxId,
|
||||||
success: false,
|
success: false,
|
||||||
err: err.message ?? `${action} failed`,
|
err: err.message ?? `${action} failed`,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
export function dispatchEvents(redisCnx, msg, chan, eventHandlers) {
|
export function dispatchEvents(redisCnx, msg, chan, eventHandlers) {
|
||||||
const eventType = msg.eventType
|
const eventType = msg.eventType
|
||||||
|
const sender = msg.sender ?? null
|
||||||
|
const cnxId = msg.cnxId ?? null
|
||||||
if(!eventType || typeof(eventType) !== 'string') return(false)
|
if(!eventType || typeof(eventType) !== 'string') return(false)
|
||||||
|
|
||||||
let handled = false
|
let handled = false
|
||||||
@@ -13,7 +15,7 @@ export function dispatchEvents(redisCnx, msg, chan, eventHandlers) {
|
|||||||
|
|
||||||
for(const handle of handlers) {
|
for(const handle of handlers) {
|
||||||
try {
|
try {
|
||||||
handle.call(redisCnx, msg, chan)
|
handle.call(redisCnx, msg, chan, sender, cnxId)
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.error(
|
console.error(
|
||||||
`[${redisCnx.redisId}] Event ${eventType} on ${chan} failed:`,
|
`[${redisCnx.redisId}] Event ${eventType} on ${chan} failed:`,
|
||||||
|
|||||||
@@ -3,12 +3,9 @@ export function busReplyRoute(daemonBlock, meshName) {
|
|||||||
if(!daemonBlock?.senderId) return(null)
|
if(!daemonBlock?.senderId) return(null)
|
||||||
|
|
||||||
const onArena = meshName === 'arena'
|
const onArena = meshName === 'arena'
|
||||||
const systemReply = daemonBlock.maestroActionsReply
|
|
||||||
?? daemonBlock.gpsActionsReply
|
|
||||||
?? daemonBlock.observerActionsReply
|
|
||||||
const actionsReply = onArena
|
const actionsReply = onArena
|
||||||
? (daemonBlock.bus?.arena?.actionsReply ?? systemReply)
|
? (daemonBlock.bus?.arena?.actionsReply ?? daemonBlock.ActionsReply)
|
||||||
: systemReply
|
: daemonBlock.ActionsReply
|
||||||
|
|
||||||
if(!actionsReply) return(null)
|
if(!actionsReply) return(null)
|
||||||
|
|
||||||
@@ -25,12 +22,13 @@ export function publishActionReply(redisCnx, options) {
|
|||||||
sender,
|
sender,
|
||||||
reply,
|
reply,
|
||||||
replyChannel,
|
replyChannel,
|
||||||
senderId,
|
|
||||||
} = options
|
} = options
|
||||||
reply.action = action
|
reply.action = action
|
||||||
reply.sender = senderId
|
reply.sender = redisCnx.senderId
|
||||||
|
reply.cnxId = redisCnx.cnxId
|
||||||
if(reqid) reply.reqid = reqid
|
if(reqid) reply.reqid = reqid
|
||||||
const chan = replyChannel.replace(/\[UID\]/g, sender)
|
const chan = replyChannel.replace(/\[UID\]/g, sender)
|
||||||
|
.replace(/\[CUID\]/g, redisCnx.cnxId)
|
||||||
redisCnx.redisPublish(chan, reply)
|
redisCnx.redisPublish(chan, reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,13 +41,11 @@ export function replyToAction(redisCnx, options) {
|
|||||||
payload,
|
payload,
|
||||||
err,
|
err,
|
||||||
replyChannel,
|
replyChannel,
|
||||||
senderId,
|
|
||||||
} = options
|
} = options
|
||||||
|
|
||||||
const routeReplyChannel = replyChannel ?? redisCnx.actionsReply
|
const routeReplyChannel = replyChannel ?? redisCnx.actionsReply
|
||||||
const routeSenderId = senderId ?? redisCnx.senderId
|
|
||||||
|
|
||||||
if(!routeReplyChannel || !routeSenderId) {
|
if(!routeReplyChannel) {
|
||||||
console.error(`[${redisCnx.redisId}] Cannot resolve action reply route`)
|
console.error(`[${redisCnx.redisId}] Cannot resolve action reply route`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -63,7 +59,6 @@ export function replyToAction(redisCnx, options) {
|
|||||||
reqid,
|
reqid,
|
||||||
sender,
|
sender,
|
||||||
replyChannel: routeReplyChannel,
|
replyChannel: routeReplyChannel,
|
||||||
senderId: routeSenderId,
|
|
||||||
reply,
|
reply,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-12
@@ -29,8 +29,10 @@
|
|||||||
],
|
],
|
||||||
"gps": {
|
"gps": {
|
||||||
"primordialDaemon": true,
|
"primordialDaemon": true,
|
||||||
"gpsActionsChannel": "system:requests:gps",
|
"ActionsChannel": "system:requests:gps",
|
||||||
"gpsActionsReply": "system:replies:[UID]",
|
"ActionsReply": "system:replies:[UID]",
|
||||||
|
"arenaActionsChannel": "arena:requests:[UID]",
|
||||||
|
"arenaActionsReply": "arena:replies:[UID]",
|
||||||
"GPSstorage": {
|
"GPSstorage": {
|
||||||
"agentHashKey": "system:gps:agent:[UID]",
|
"agentHashKey": "system:gps:agent:[UID]",
|
||||||
"agentsIndexKey": "system:gps:agents",
|
"agentsIndexKey": "system:gps:agents",
|
||||||
@@ -54,8 +56,10 @@
|
|||||||
"prismRefreshLeadSeconds": 1
|
"prismRefreshLeadSeconds": 1
|
||||||
},
|
},
|
||||||
"maestro": {
|
"maestro": {
|
||||||
"maestroActionsChannel": "system:requests:maestro",
|
"ActionsChannel": "system:requests:maestro",
|
||||||
"maestroActionsReply": "system:replies:[UID]",
|
"ActionsReply": "system:replies:[UID]",
|
||||||
|
"arenaActionsChannel": "arena:requests:[UID]",
|
||||||
|
"arenaActionsReply": "arena:replies:[UID]",
|
||||||
"senderId": "maestro",
|
"senderId": "maestro",
|
||||||
"lifecycle": {
|
"lifecycle": {
|
||||||
"arenaChannel": "arena:lifecycle",
|
"arenaChannel": "arena:lifecycle",
|
||||||
@@ -64,16 +68,13 @@
|
|||||||
"systemLifecycleChannel": "system:maestro:lifecycle:[UID]",
|
"systemLifecycleChannel": "system:maestro:lifecycle:[UID]",
|
||||||
"readyTimeoutMs": 30000
|
"readyTimeoutMs": 30000
|
||||||
},
|
},
|
||||||
"mysql": {
|
|
||||||
"socketPath": "/var/run/mysqld/mysqld.sock",
|
|
||||||
"guiDatabase": "p42GUI",
|
|
||||||
"simDatabase": "p42SIM"
|
|
||||||
},
|
|
||||||
"observer": {
|
"observer": {
|
||||||
"primordialDaemon": false,
|
"primordialDaemon": false,
|
||||||
"observerActionsChannel": "system:requests:observer",
|
"ActionsChannel": "system:requests:observer",
|
||||||
"observerActionsReply": "system:replies:[UID]",
|
"ActionsReply": "system:replies:[UID]",
|
||||||
"observerFrustumEventsChannel": "system:observer:subscribed[UID]:agents",
|
"arenaActionsChannel": "arena:requests:[UID]",
|
||||||
|
"arenaActionsReply": "arena:replies:[UID]",
|
||||||
|
"FrustumEventsChannel": "system:observer:subscribed[CUID]:agents",
|
||||||
"senderId": "observer",
|
"senderId": "observer",
|
||||||
"scanIntervalMs": 300,
|
"scanIntervalMs": 300,
|
||||||
"lifecycle": {
|
"lifecycle": {
|
||||||
@@ -110,5 +111,10 @@
|
|||||||
"basePrefix": "messageBus:"
|
"basePrefix": "messageBus:"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"mysql": {
|
||||||
|
"socketPath": "/var/run/mysqld/mysqld.sock",
|
||||||
|
"guiDatabase": "p42GUI",
|
||||||
|
"simDatabase": "p42SIM"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-13
@@ -61,8 +61,10 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"primordialDaemon": { "type": "boolean" },
|
"primordialDaemon": { "type": "boolean" },
|
||||||
"gpsActionsChannel": { "type": "string" },
|
"ActionsChannel": { "type": "string" },
|
||||||
"gpsActionsReply": { "type": "string" },
|
"ActionsReply": { "type": "string" },
|
||||||
|
"arenaActionsChannel": { "type": "string" },
|
||||||
|
"arenaActionsReply": { "type": "string" },
|
||||||
"GPSstorage": {
|
"GPSstorage": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -108,8 +110,10 @@
|
|||||||
"prismRefreshLeadSeconds": { "type": "number", "minimum": 0 }
|
"prismRefreshLeadSeconds": { "type": "number", "minimum": 0 }
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"gpsActionsChannel",
|
"ActionsChannel",
|
||||||
"gpsActionsReply",
|
"ActionsReply",
|
||||||
|
"arenaActionsChannel",
|
||||||
|
"arenaActionsReply",
|
||||||
"GPSstorage",
|
"GPSstorage",
|
||||||
"agentVectorChangeChannel",
|
"agentVectorChangeChannel",
|
||||||
"collisionsChannel"
|
"collisionsChannel"
|
||||||
@@ -118,8 +122,10 @@
|
|||||||
"maestro": {
|
"maestro": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"maestroActionsChannel": { "type": "string" },
|
"ActionsChannel": { "type": "string" },
|
||||||
"maestroActionsReply": { "type": "string" },
|
"ActionsReply": { "type": "string" },
|
||||||
|
"arenaActionsChannel": { "type": "string" },
|
||||||
|
"arenaActionsReply": { "type": "string" },
|
||||||
"senderId": { "type": "string" },
|
"senderId": { "type": "string" },
|
||||||
"lifecycle": {
|
"lifecycle": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -135,8 +141,10 @@
|
|||||||
"readyTimeoutMs": { "type": "integer", "minimum": 1000 }
|
"readyTimeoutMs": { "type": "integer", "minimum": 1000 }
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"maestroActionsChannel",
|
"ActionsChannel",
|
||||||
"maestroActionsReply"
|
"ActionsReply",
|
||||||
|
"arenaActionsChannel",
|
||||||
|
"arenaActionsReply"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mysql": {
|
"mysql": {
|
||||||
@@ -155,9 +163,11 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"primordialDaemon": { "type": "boolean" },
|
"primordialDaemon": { "type": "boolean" },
|
||||||
"observerActionsChannel": { "type": "string" },
|
"ActionsChannel": { "type": "string" },
|
||||||
"observerActionsReply": { "type": "string" },
|
"ActionsReply": { "type": "string" },
|
||||||
"observerFrustumEventsChannel": { "type": "string" },
|
"arenaActionsChannel": { "type": "string" },
|
||||||
|
"arenaActionsReply": { "type": "string" },
|
||||||
|
"FrustumEventsChannel": { "type": "string" },
|
||||||
"senderId": { "type": "string" },
|
"senderId": { "type": "string" },
|
||||||
"scanIntervalMs": { "type": "integer", "minimum": 50 },
|
"scanIntervalMs": { "type": "integer", "minimum": 50 },
|
||||||
"lifecycle": {
|
"lifecycle": {
|
||||||
@@ -173,8 +183,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"observerActionsChannel",
|
"ActionsChannel",
|
||||||
"observerActionsReply"
|
"ActionsReply",
|
||||||
|
"FrustumEventsChannel",
|
||||||
|
"arenaActionsChannel",
|
||||||
|
"arenaActionsReply"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"systemMesh": {
|
"systemMesh": {
|
||||||
|
|||||||
+18
-12
@@ -29,8 +29,10 @@
|
|||||||
],
|
],
|
||||||
"gps": {
|
"gps": {
|
||||||
"primordialDaemon": true,
|
"primordialDaemon": true,
|
||||||
"gpsActionsChannel": "system:requests:gps",
|
"ActionsChannel": "system:requests:gps",
|
||||||
"gpsActionsReply": "system:replies:[UID]",
|
"ActionsReply": "system:replies:[UID]",
|
||||||
|
"arenaActionsChannel": "arena:requests:[UID]",
|
||||||
|
"arenaActionsReply": "arena:replies:[UID]",
|
||||||
"GPSstorage": {
|
"GPSstorage": {
|
||||||
"agentHashKey": "system:gps:agent:[UID]",
|
"agentHashKey": "system:gps:agent:[UID]",
|
||||||
"agentsIndexKey": "system:gps:agents",
|
"agentsIndexKey": "system:gps:agents",
|
||||||
@@ -54,8 +56,10 @@
|
|||||||
"prismRefreshLeadSeconds": 1
|
"prismRefreshLeadSeconds": 1
|
||||||
},
|
},
|
||||||
"maestro": {
|
"maestro": {
|
||||||
"maestroActionsChannel": "system:requests:maestro",
|
"ActionsChannel": "system:requests:maestro",
|
||||||
"maestroActionsReply": "system:replies:[UID]",
|
"ActionsReply": "system:replies:[UID]",
|
||||||
|
"arenaActionsChannel": "arena:requests:[UID]",
|
||||||
|
"arenaActionsReply": "arena:replies:[UID]",
|
||||||
"senderId": "maestro",
|
"senderId": "maestro",
|
||||||
"lifecycle": {
|
"lifecycle": {
|
||||||
"arenaChannel": "arena:lifecycle",
|
"arenaChannel": "arena:lifecycle",
|
||||||
@@ -64,16 +68,13 @@
|
|||||||
"systemLifecycleChannel": "system:maestro:lifecycle:[UID]",
|
"systemLifecycleChannel": "system:maestro:lifecycle:[UID]",
|
||||||
"readyTimeoutMs": 30000
|
"readyTimeoutMs": 30000
|
||||||
},
|
},
|
||||||
"mysql": {
|
|
||||||
"socketPath": "/var/run/mysqld/mysqld.sock",
|
|
||||||
"guiDatabase": "test_p42GUI",
|
|
||||||
"simDatabase": "test_p42SIM"
|
|
||||||
},
|
|
||||||
"observer": {
|
"observer": {
|
||||||
"primordialDaemon": false,
|
"primordialDaemon": false,
|
||||||
"observerActionsChannel": "system:requests:observer",
|
"ActionsChannel": "system:requests:observer",
|
||||||
"observerActionsReply": "system:replies:[UID]",
|
"ActionsReply": "system:replies:[UID]",
|
||||||
"observerFrustumEventsChannel": "system:observer:subscribed[UID]:agents",
|
"FrustumEventsChannel": "system:observer:subscribed[CUID]:agents",
|
||||||
|
"arenaActionsChannel": "arena:requests:[UID]",
|
||||||
|
"arenaActionsReply": "arena:replies:[UID]",
|
||||||
"senderId": "observer",
|
"senderId": "observer",
|
||||||
"scanIntervalMs": 300,
|
"scanIntervalMs": 300,
|
||||||
"lifecycle": {
|
"lifecycle": {
|
||||||
@@ -110,5 +111,10 @@
|
|||||||
"basePrefix": "messageBus:"
|
"basePrefix": "messageBus:"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"mysql": {
|
||||||
|
"socketPath": "/var/run/mysqld/mysqld.sock",
|
||||||
|
"guiDatabase": "test_p42GUI",
|
||||||
|
"simDatabase": "test_p42SIM"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import redis from 'redis'
|
import redis from 'redis'
|
||||||
|
import os from 'node:os'
|
||||||
|
|
||||||
export class RedisConnexion {
|
export class RedisConnexion {
|
||||||
|
|
||||||
@@ -12,6 +13,8 @@ export class RedisConnexion {
|
|||||||
this.senderId = options.senderId ?? null
|
this.senderId = options.senderId ?? null
|
||||||
this.actionsReply = options.actionsReply ?? null
|
this.actionsReply = options.actionsReply ?? null
|
||||||
|
|
||||||
|
this.cnxId = os.hostname() + ':' + process.pid + ':' + Date.now() + ':' + Math.random().toString(36).substring(2, 15)
|
||||||
|
|
||||||
if(this.meshModule?.actionHandlers) Object.assign(this, this.meshModule.actionHandlers)
|
if(this.meshModule?.actionHandlers) Object.assign(this, this.meshModule.actionHandlers)
|
||||||
this.afterLogin = this.meshModule?.afterLogin ?? []
|
this.afterLogin = this.meshModule?.afterLogin ?? []
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ export async function run(ctx) {
|
|||||||
const lifecycleWait = waitForLifecycleEvent(ctx, 'onYourMarks', argv.timeout)
|
const lifecycleWait = waitForLifecycleEvent(ctx, 'onYourMarks', argv.timeout)
|
||||||
|
|
||||||
const reqid = `maestro1-${Date.now()}`
|
const reqid = `maestro1-${Date.now()}`
|
||||||
const actionsChan = config.maestro.maestroActionsChannel
|
const actionsChan = config.maestro.ActionsChannel
|
||||||
|
|
||||||
log('action', `Publishing STARTSIMULATION on ${actionsChan} (reqid=${reqid})...`)
|
log('action', `Publishing STARTSIMULATION on ${actionsChan} (reqid=${reqid})...`)
|
||||||
await systemCnx.redisPublish(actionsChan, {
|
await systemCnx.redisPublish(actionsChan, {
|
||||||
|
|||||||
Reference in New Issue
Block a user