Remote Backends Implemented

This commit is contained in:
Luis Fernando Molina committed 2020-04-22 13:57:41 +02:00
1 parent eac4c47e2e
commit 5f0664fa81
11 files changed
+211 -63

No files matched your search

-2
View File
@@ -130,8 +130,6 @@ function newCanvas () {
animation.initialize()
thisObject.animation = animation
/* Low Level Infraestructure First */
animation.addCallBackFunction('System Event Handler Physics', eventsServerClient.physics)
/* Spcaces Physics */
animation.addCallBackFunction('CockpitSpace Physics', thisObject.cockpitSpace.physics)
+3
View File
@@ -151,6 +151,8 @@ function newPlottersManager () {
if (host === undefined) { host = 'localhost' }
if (webPort === undefined) { webPort = window.location.port }
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(layer.networkNode.id)
storage.initialize(
dataMine,
bot,
@@ -162,6 +164,7 @@ function newPlottersManager () {
timeFrame,
host,
webPort,
eventsServerClient,
onProductStorageInitialized
)
@@ -7,26 +7,15 @@ function newSessionFunctions () {
return thisObject
function runSession (node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, callBackFunction) {
/* We can not run a sessionif its parent process is not running. Less if it does not have a parent. */
if (node.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be able to run.')
if (validations(node) !== true) {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
if (node.payload.parentNode.payload.uiObject.isRunning !== true) {
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be running to be able to run.')
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id)
if (node.payload.referenceParent === undefined) {
node.payload.uiObject.setErrorMessage('Session needs to reference a Trading System.')
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
node.payload.uiObject.run(callBackFunction)
node.payload.uiObject.run(eventsServerClient, callBackFunction)
let key = node.name + '-' + node.type + '-' + node.id
@@ -77,9 +66,65 @@ function newSessionFunctions () {
}
function stopSession (node, functionLibraryProtocolNode, callBackFunction) {
if (validations(node) !== true) {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id)
let key = node.name + '-' + node.type + '-' + node.id
eventsServerClient.raiseEvent(key, 'Stop Session')
node.payload.uiObject.stop(callBackFunction)
}
function validations (node) {
if (node.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be able to run.')
return
}
if (node.payload.parentNode.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Session needs to be inside a Trading Process Instance.')
return
}
if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Session needs to be inside a Task.')
return
}
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Session needs to be inside a Task Manager.')
return
}
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Session needs to be inside Exchange Tasks.')
return
}
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Session needs to be inside a Testing or Production Environment.')
return
}
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Session needs to be inside a Network Node.')
return
}
if (node.payload.parentNode.payload.uiObject.isRunning !== true) {
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be running.')
return
}
if (node.payload.referenceParent === undefined) {
node.payload.uiObject.setErrorMessage('Session needs to reference a Trading System.')
return
}
return true
}
}
@@ -13,19 +13,17 @@ function newTaskFunctions () {
return thisObject
function runTask (node, functionLibraryProtocolNode, callBackFunction) {
/* Check if it is possible to Run or not */
if (node.bot === undefined) {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
if (node.bot.processes.length === 0) {
if (validations(node) !== true) {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id)
for (let i = 0; i < node.bot.processes.length; i++) {
let process = node.bot.processes[i]
process.payload.uiObject.run()
process.payload.uiObject.run(eventsServerClient)
}
let lightingPath = '->Task->' +
@@ -72,11 +70,19 @@ function newTaskFunctions () {
return
}
node.payload.uiObject.run(callBackFunction)
node.payload.uiObject.run(eventsServerClient, callBackFunction)
eventsServerClient.raiseEvent('Task Manager', 'Run Task', event)
}
function stopTask (node, functionLibraryProtocolNode, callBackFunction) {
if (validations(node) !== true) {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id)
let event = {
taskId: node.id,
taskName: node.name
@@ -94,6 +100,38 @@ function newTaskFunctions () {
}
}
function validations (node) {
if (node.bot === undefined) {
node.payload.uiObject.setErrorMessage('Task needs to have a Bot Instance.')
return
}
if (node.bot.processes.length === 0) {
node.payload.uiObject.setErrorMessage('Task Bot Instance needs to have al least once Process Instance.')
return
}
if (node.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Task needs to be inside a Task Manager.')
return
}
if (node.payload.parentNode.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Task needs to be inside Exchange Tasks.')
return
}
if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Task needs to be inside a Testing or Production Environment or a Data Mining node.')
return
}
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
node.payload.uiObject.setErrorMessage('Task needs to be inside a Network Node.')
return
}
return true
}
function runAllTasks (taskManager, functionLibraryProtocolNode) {
for (let i = 0; i < taskManager.tasks.length; i++) {
let node = taskManager.tasks[i]
+48
View File
@@ -10,6 +10,7 @@ function newWorkspace () {
container: undefined,
enabled: false,
nodeChildren: undefined,
eventsServerClients: new Map(),
save: saveWorkspace,
getHierarchyHeads: getHierarchyHeads,
getNodeThatIsOnFocus: getNodeThatIsOnFocus,
@@ -93,6 +94,7 @@ function newWorkspace () {
thisObject.workspaceNode = JSON.parse(savedWorkspace)
}
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode)
setupEventsServerClients()
thisObject.enabled = true
setInterval(saveWorkspace, 60000)
@@ -101,6 +103,38 @@ function newWorkspace () {
}
}
function setupEventsServerClients () {
for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) {
let rootNode = thisObject.workspaceNode.rootNodes[i]
if (rootNode.type === 'Network') {
for (let j = 0; j < rootNode.networkNodes.length; j++) {
let networkNode = rootNode.networkNodes[j]
let host
let webSocketsPort
/* At this point the node does not have the payload property yet, that is why we have to do this manually */
try {
let code = JSON.parse(networkNode.code)
host = code.host
webSocketsPort = code.webSocketsPort
} catch (err) {
console.log('[ERROR] networkNode ' + networkNode.name + ' has an invalid configuration. Cannot know the host name and webSocketsPort.')
return
}
if (host === undefined) { host = 'localhost' }
if (webSocketsPort === undefined) { webSocketsPort = '8080' }
let eventsServerClient = newEventsServerClient(host, webSocketsPort)
eventsServerClient.initialize()
thisObject.eventsServerClients.set(networkNode.id, eventsServerClient)
}
}
}
}
function chainDetachNode (node) {
functionLibraryChainAttachDetach.chainDetachNode(node, thisObject.workspaceNode.rootNodes)
}
@@ -130,6 +164,19 @@ function newWorkspace () {
}
function physics () {
eventsServerClientsPhysics()
replacingWorkspacePhysics()
}
function eventsServerClientsPhysics () {
thisObject.eventsServerClients.forEach(applyPhysics)
function applyPhysics (eventServerClient) {
eventServerClient.physics()
}
}
function replacingWorkspacePhysics () {
if (thisObject.enabled !== true) { return }
if (workingAtTask > 0) {
@@ -151,6 +198,7 @@ function newWorkspace () {
break
case 4:
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode, true)
setupEventsServerClients()
workingAtTask++
break
case 5:
+10 -10
View File
@@ -1,5 +1,5 @@
function newEventsServerClient () {
function newEventsServerClient (host, port) {
/* Web Sockets Connection */
const MODULE_NAME = 'System Event Handler'
@@ -8,7 +8,7 @@ function newEventsServerClient () {
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
const WEB_SOCKETS_URL = 'ws://localhost:8080'
const WEB_SOCKETS_URL = 'ws://' + host + ':' + port + ''
let WEB_SOCKETS_CONNECTION
let thisObject = {
@@ -56,12 +56,7 @@ function newEventsServerClient () {
responseWaiters.set(command.callerId, responseCallBack)
}
if (WEB_SOCKETS_CONNECTION.readyState === 1) {
// 1 means connected and ready.
sendToWebSocketServer(command)
} else {
console.log('WebSocket message could not be sent because the connection was not ready. Message = ' + JSON.stringify(command))
}
sendToWebSocketServer(command)
}
function sendToWebSocketServer (command) {
@@ -72,7 +67,12 @@ function newEventsServerClient () {
commandsSentByTimestamp.set(stringNonce, timestamp)
let messageToWebSocketServer = 'Web Browser' + '|*|' + stringNonce + '|*|' + JSON.stringify(command)
WEB_SOCKETS_CONNECTION.send(messageToWebSocketServer)
if (WEB_SOCKETS_CONNECTION.readyState === 1) {
WEB_SOCKETS_CONNECTION.send(messageToWebSocketServer)
} else {
console.log('WebSocket message could not be sent because the connection was not ready. Will retry soon. Message = ' + JSON.stringify(command))
}
}
function createEventHandler (eventHandlerName, callerId, responseCallBack) {
@@ -153,7 +153,7 @@ function newEventsServerClient () {
}
if (thisObject.isConnected() !== true) {
canvas.cockpitSpace.setStatus('Connection with the local backend lost. Please check that all localhost servers are running.', 100, canvas.cockpitSpace.statusTypes.WARNING)
canvas.cockpitSpace.setStatus('Connecting with ' + host + '. Please hold on until the connection can be stablished.', 100, canvas.cockpitSpace.statusTypes.WARNING)
} else {
retryCommandsPhysics()
}
+15 -7
View File
@@ -22,27 +22,35 @@ function newCircularProgressBar () {
thisObject.container.frame.position.y = 0
let opacityCounters = []
let eventSubscriptionIdHeartbeat
let needToDrawRing = true
let eventsServerClient
return thisObject
function finalize () {
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
if (eventSubscriptionIdHeartbeat !== undefined) {
eventsServerClient.stopListening(key, eventSubscriptionIdHeartbeat)
}
finalizeEventsServerClient()
thisObject.container = undefined
thisObject.payload = undefined
thisObject.fitFunction = undefined
}
function initialize (payload) {
function finalizeEventsServerClient () {
if (eventsServerClient !== undefined) {
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
if (eventSubscriptionIdHeartbeat !== undefined) {
eventsServerClient.stopListening(key, eventSubscriptionIdHeartbeat)
}
}
}
function initialize (payload, pEventsServerClient) {
thisObject.payload = payload
finalizeEventsServerClient()
eventsServerClient = pEventsServerClient
for (let i = 0; i < 60; i++) {
opacityCounters.push(0)
}
+21 -10
View File
@@ -117,17 +117,12 @@ function newUiObject () {
let referenceLineCounter = 0
let chainLineCounter = 0
let eventsServerClient
return thisObject
function finalize () {
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
if (eventSubscriptionIdOnRunning !== undefined) {
eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject')
}
if (eventSubscriptionIdOnStopped !== undefined) {
eventsServerClient.stopListening(key, eventSubscriptionIdOnStopped, 'UiObject')
}
finalizeEventsServerClient()
thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId)
thisObject.container.eventHandler.stopListening(selfNotFocusEventSubscriptionId)
@@ -173,6 +168,19 @@ function newUiObject () {
onRunningCallBackFunction = undefined
}
function finalizeEventsServerClient () {
if (eventsServerClient !== undefined) {
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
if (eventSubscriptionIdOnRunning !== undefined) {
eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject')
}
if (eventSubscriptionIdOnStopped !== undefined) {
eventsServerClient.stopListening(key, eventSubscriptionIdOnStopped, 'UiObject')
}
}
}
function initialize (payload, menuItemsInitialValues) {
thisObject.payload = payload
@@ -750,14 +758,17 @@ function newUiObject () {
}
}
function run (callBackFunction) {
function run (pEventsServerClient, callBackFunction) {
finalizeEventsServerClient()
eventsServerClient = pEventsServerClient
/* We setup the circular progress bar. */
if (thisObject.circularProgressBar !== undefined) {
thisObject.circularProgressBar.finalize()
}
thisObject.circularProgressBar = newCircularProgressBar()
thisObject.circularProgressBar.initialize(thisObject.payload)
thisObject.circularProgressBar.initialize(thisObject.payload, eventsServerClient)
thisObject.circularProgressBar.fitFunction = thisObject.fitFunction
thisObject.circularProgressBar.container = thisObject.container
+2 -2
View File
@@ -154,9 +154,9 @@ function newLayer () {
let lightingPath =
'->Layer->' +
'Data Product->Single Market Data->Exchange Data Products->' +
'Session Independent Data->Session Based Data->' +
'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' +
'Data Storage->Network Node->' +
'Session Reference->Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
'Market->Market Base Asset->Asset->' +
'Market Quoted Asset->Asset->' +
'Exchange Markets->Crypto Exchange->' +
+1 -4
View File
@@ -1,6 +1,5 @@
let canvas
let markets
let eventsServerClient
let APP_SCHEMA_MAP = new Map()
let APP_SCHEMA_ARRAY = []
@@ -23,9 +22,7 @@ function newDashboard () {
function start () {
try {
setBrowserEvents()
eventsServerClient = newEventsServerClient()
eventsServerClient.initialize(setUpAppSchema)
setUpAppSchema()
function setUpAppSchema () {
APP_SCHEMA_ARRAY = getAppSchema()
+5 -5
View File
@@ -74,7 +74,7 @@ function newProductStorage (name) {
}
}
function initialize (dataMine, bot, session, product, exchange, market, pDatetime, pTimeFrame, host, port, callBackFunction) {
function initialize (dataMine, bot, session, product, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, callBackFunction) {
try {
datetime = pDatetime
timeFrame = pTimeFrame
@@ -90,7 +90,7 @@ function newProductStorage (name) {
dataSetsToLoad++
let marketFiles = newMarketFiles()
marketFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, onMarketFileReady)
marketFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onMarketFileReady)
thisObject.marketFiles.push(marketFiles)
}
break
@@ -99,7 +99,7 @@ function newProductStorage (name) {
dataSetsToLoad++
let dailyFiles = newDailyFiles()
dailyFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, pDatetime, pTimeFrame, host, port, onDailyFileReady)
dailyFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, onDailyFileReady)
thisObject.dailyFiles.push(dailyFiles)
}
break
@@ -108,7 +108,7 @@ function newProductStorage (name) {
dataSetsToLoad++
let singleFile = newSingleFile()
singleFile.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, onSingleFileReady)
singleFile.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onSingleFileReady)
thisObject.singleFile.push(singleFile)
}
break
@@ -117,7 +117,7 @@ function newProductStorage (name) {
dataSetsToLoad++
let fileSequences = newFileSequence()
fileSequences.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, onFileSequenceReady)
fileSequences.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onFileSequenceReady)
thisObject.fileSequences.push(fileSequences)
}
break