Status of Network Clients working
This commit is contained in:
1 parent
411a8ca2d7
commit
759ff66c9e
6 files changed
+217
-115
No files matched your search
@@ -1,17 +1,17 @@
|
||||
|
||||
process.on('uncaughtException', function (err) {
|
||||
if (err.message.indexOf("EADDRINUSE") > 0) {
|
||||
console.log("A Superalgos Backend Server cannot be started. Reason: the port " + port + " is already in use by another application.")
|
||||
console.log("A Superalgos Client cannot be started. Reason: the port " + port + " is already in use by another application.")
|
||||
return
|
||||
}
|
||||
console.log('[ERROR] Backend Server -> server -> uncaughtException -> err.message = ' + err.message)
|
||||
console.log('[ERROR] Backend Server -> server -> uncaughtException -> err.stack = ' + err.stack)
|
||||
console.log('[ERROR] Client -> client-> uncaughtException -> err.message = ' + err.message)
|
||||
console.log('[ERROR] Client -> client-> uncaughtException -> err.stack = ' + err.stack)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('[ERROR] Backend Server -> server -> unhandledRejection -> reason = ' + JSON.stringify(reason))
|
||||
console.log('[ERROR] Backend Server -> server -> unhandledRejection -> p = ' + JSON.stringify(p))
|
||||
console.log('[ERROR] Client -> client-> unhandledRejection -> reason = ' + JSON.stringify(reason))
|
||||
console.log('[ERROR] Client -> client-> unhandledRejection -> p = ' + JSON.stringify(p))
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
@@ -131,6 +131,6 @@ try {
|
||||
|
||||
|
||||
} catch (err) {
|
||||
console.log('[ERROR] Client -> Task Manager -> server -> Error = ' + err.stack)
|
||||
console.log('[ERROR] Client -> Error = ' + err.stack)
|
||||
}
|
||||
|
||||
+49
-3
@@ -91,6 +91,46 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
|
||||
|
||||
switch (requestParameters[1]) {
|
||||
|
||||
case 'WEB3':
|
||||
{
|
||||
getBody(processRequest)
|
||||
|
||||
async function processRequest(body) {
|
||||
try {
|
||||
let params = JSON.parse(body)
|
||||
|
||||
switch (params.method) {
|
||||
case 'getNetworkClientStatus': {
|
||||
|
||||
let status = await WEB3_SERVER.getNetworkClientStatus(
|
||||
params.host,
|
||||
params.port,
|
||||
params.interface
|
||||
)
|
||||
|
||||
respondWithContent(JSON.stringify(status), response)
|
||||
return
|
||||
}
|
||||
default: {
|
||||
respondWithContent(JSON.stringify({ error: 'Method ' + params.method + ' is invalid.' }), response)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] httpInterface -> WEB3s -> Method call produced an error.') }
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] httpInterface -> WEB3s -> err.stack = ' + err.stack) }
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] httpInterface -> WEB3s -> Params Received = ' + body) }
|
||||
|
||||
let error = {
|
||||
result: 'Fail Because',
|
||||
message: err.message,
|
||||
stack: err.stack
|
||||
}
|
||||
respondWithContent(JSON.stringify(error), response)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case 'CCXT':
|
||||
{
|
||||
getBody(processRequest)
|
||||
@@ -482,7 +522,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
|
||||
|
||||
function onDirRead(err, fileList) {
|
||||
if (err) {
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[WARN] Error reading a directory content. filePath = ' + dirPath) }
|
||||
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
|
||||
return
|
||||
} else {
|
||||
@@ -501,6 +541,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
|
||||
}
|
||||
} catch (err) {
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] err.stack = ' + err.stack) }
|
||||
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
|
||||
return
|
||||
}
|
||||
@@ -515,7 +556,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
|
||||
|
||||
function onDirRead(err, fileList) {
|
||||
if (err) {
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[WARN] Error reading a directory content. filePath = ' + dirPath) }
|
||||
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
|
||||
return
|
||||
} else {
|
||||
@@ -531,6 +572,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
|
||||
}
|
||||
} catch (err) {
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] err.stack = ' + err.stack) }
|
||||
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
|
||||
return
|
||||
}
|
||||
@@ -647,6 +689,8 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('[ERROR] Error reading a directory content. filePath = ' + path)
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] err.stack = ' + err.stack) }
|
||||
|
||||
console.log(err.stack)
|
||||
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
|
||||
return
|
||||
@@ -728,7 +772,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
|
||||
|
||||
function onDirRead(err, fileList) {
|
||||
if (err) {
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[WARN] Error reading a directory content. filePath = ' + dirPath) }
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log(err.stack) }
|
||||
return
|
||||
} else {
|
||||
@@ -747,6 +791,8 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
|
||||
}
|
||||
} catch (err) {
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
|
||||
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] err.stack = ' + err.stack) }
|
||||
|
||||
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
|
||||
return
|
||||
}
|
||||
|
||||
+57
-3
@@ -3,15 +3,19 @@ exports.newWeb3Server = function newWeb3Server() {
|
||||
const MODULE = "Web3 Server"
|
||||
|
||||
let thisObject = {
|
||||
getNetworkClientStatus: getNetworkClientStatus,
|
||||
initialize: initialize,
|
||||
finalize: finalize,
|
||||
run: run
|
||||
}
|
||||
|
||||
const Web3 = require('web3');
|
||||
let web3Map = new Map()
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize() {
|
||||
|
||||
web3Map = undefined
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
@@ -19,6 +23,56 @@ exports.newWeb3Server = function newWeb3Server() {
|
||||
}
|
||||
|
||||
function run() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function getNetworkClientStatus(host, port, interface) {
|
||||
let key = 'host (' + host + ') at port (' + port + ') via interface (' + interface + ')'
|
||||
|
||||
try {
|
||||
|
||||
let web3 = web3Map.get(key)
|
||||
|
||||
if (web3 === undefined) {
|
||||
/* This means that we never got connected to this client before */
|
||||
switch (interface) {
|
||||
case 'ws': {
|
||||
web3 = new Web3('ws://' + host + ':' + port + '');
|
||||
break
|
||||
}
|
||||
case 'http': {
|
||||
web3 = new Web3('http://' + host + ':' + port + '');
|
||||
break
|
||||
}
|
||||
default: {
|
||||
return { error: 'Interface parameter must be eithre ws or http. Received ' + interface }
|
||||
}
|
||||
}
|
||||
|
||||
return await testConnection()
|
||||
|
||||
async function testConnection() {
|
||||
let accounts = await web3.eth.getAccounts()
|
||||
if (web3.currentProvider.connected === false) {
|
||||
return { error: 'Connection to ' + key + ' could not be established.' }
|
||||
} else {
|
||||
return await returnStatus(web3)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return await returnStatus(web3)
|
||||
}
|
||||
|
||||
async function returnStatus(web3) {
|
||||
|
||||
let status = {}
|
||||
status.isSyncing = await web3.eth.isSyncing()
|
||||
status.chainId = await web3.eth.getChainId()
|
||||
status.result = 'Ok'
|
||||
return status
|
||||
}
|
||||
} catch(err) {
|
||||
return { error: 'Could not connect to ' + key }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ function newEthereumBlockchainSpace() {
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
|
||||
let clientMap = new Map()
|
||||
let lastTryToReconnectDatetime
|
||||
|
||||
return thisObject
|
||||
@@ -30,38 +29,34 @@ function newEthereumBlockchainSpace() {
|
||||
}
|
||||
|
||||
function physics() {
|
||||
networkClientStatusPhysics()
|
||||
}
|
||||
|
||||
async function networkClientStatusPhysics() {
|
||||
|
||||
/* We will query the node only every 3 seconds */
|
||||
if (lastTryToReconnectDatetime === undefined) {
|
||||
connectingPhysics()
|
||||
checkStatus()
|
||||
lastTryToReconnectDatetime = (new Date()).valueOf()
|
||||
} else {
|
||||
let now = (new Date()).valueOf()
|
||||
if (now - lastTryToReconnectDatetime > 3000) {
|
||||
connectingPhysics()
|
||||
checkStatus()
|
||||
lastTryToReconnectDatetime = now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function connectingPhysics() {
|
||||
try {
|
||||
if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return }
|
||||
async function checkStatus() {
|
||||
try {
|
||||
if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return }
|
||||
|
||||
let blockchain = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByType('Ethereum Blockchain')
|
||||
if (blockchain === undefined) { return }
|
||||
for (let i = 0; i < blockchain.blockchainNetworks.length; i++) {
|
||||
let blockchainNetwork = blockchain.blockchainNetworks[i]
|
||||
for (let j = 0; j < blockchainNetwork.networkClients.length; j++) {
|
||||
let networkClient = blockchainNetwork.networkClients[j]
|
||||
/*
|
||||
We will check now if this network client is already at the networkClientsMap,
|
||||
if not, we will add it and stablish the connection to the ethereum node.
|
||||
*/
|
||||
let client = clientMap.get(networkClient.id)
|
||||
let blockchain = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByType('Ethereum Blockchain')
|
||||
if (blockchain === undefined) { return }
|
||||
for (let i = 0; i < blockchain.blockchainNetworks.length; i++) {
|
||||
let blockchainNetwork = blockchain.blockchainNetworks[i]
|
||||
for (let j = 0; j < blockchainNetwork.networkClients.length; j++) {
|
||||
let networkClient = blockchainNetwork.networkClients[j]
|
||||
|
||||
if (client === undefined) {
|
||||
client = {}
|
||||
let config = JSON.parse(networkClient.config)
|
||||
if (config.host === undefined) {
|
||||
networkClient.payload.uiObject.setErrorMessage('Property host not defined at node config.')
|
||||
@@ -73,103 +68,110 @@ function newEthereumBlockchainSpace() {
|
||||
}
|
||||
|
||||
/* Web Sockets would be the default protocol */
|
||||
let providerURL
|
||||
let provider
|
||||
let clientPort
|
||||
let clientInterface
|
||||
if (config.webSocketsPort !== undefined) {
|
||||
providerURL = 'ws://' + config.host + ':' + config.webSocketsPort + ''
|
||||
provider = new Web3.providers.WebsocketProvider(providerURL, {
|
||||
headers: {
|
||||
Origin: "http://localhost"
|
||||
}
|
||||
});
|
||||
clientInterface = 'ws'
|
||||
clientPort = config.webSocketsPort
|
||||
} else {
|
||||
providerURL = 'http://' + config.host + ':' + config.httpPort + ''
|
||||
provider = new Web3.providers.HttpProvider(providerURL, {
|
||||
headers: {
|
||||
Origin: "http://localhost"
|
||||
}
|
||||
});
|
||||
clientInterface = 'http'
|
||||
clientPort = config.httpPort
|
||||
}
|
||||
|
||||
try {
|
||||
client.web3 = new window.Web3('ws://localhost:8546'); // new window.Web3(provider);
|
||||
let params = {
|
||||
method: 'getNetworkClientStatus',
|
||||
host: config.host,
|
||||
port: clientPort,
|
||||
interface: clientInterface
|
||||
}
|
||||
|
||||
/* This is a way we found to wait for the connection to be stablished */
|
||||
|
||||
await waitForConnectionToBeStablished()
|
||||
callWebServer(JSON.stringify(params), 'WEB3', onResponse)
|
||||
|
||||
async function waitForConnectionToBeStablished() {
|
||||
let accounts = await web3.eth.getAccounts()
|
||||
if (client.web3.currentProvider.connected === false) {
|
||||
networkClient.payload.uiObject.setErrorMessage('Can not connect to this client.')
|
||||
} else {
|
||||
clientMap.set(networkClient.id, client)
|
||||
setStatus()
|
||||
}
|
||||
function onResponse(err, data) {
|
||||
/* Lets check the result of the call through the http interface */
|
||||
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
networkClient.payload.uiObject.setErrorMessage('Call via HTTP Interface failed.')
|
||||
return
|
||||
}
|
||||
/*
|
||||
if (client.web3.currentProvider.connected === false) {
|
||||
networkClient.payload.uiObject.setErrorMessage('Can not connect to this client.')
|
||||
continue
|
||||
}
|
||||
/*
|
||||
let isListening = await client.web3.eth.net.isListening()
|
||||
if (isListening === true) {
|
||||
clientMap.set(networkClient.id, client)
|
||||
setStatus()
|
||||
|
||||
let status = JSON.parse(data)
|
||||
|
||||
/* Lets check the result of the method call */
|
||||
if (status.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
networkClient.payload.uiObject.setErrorMessage('Call to WEB3 Server failed. ' + status.error)
|
||||
return
|
||||
}
|
||||
|
||||
showStatus(status)
|
||||
}
|
||||
|
||||
async function showStatus(status) {
|
||||
const ANNIMATION_CYCLES_TO_LAST = 300
|
||||
|
||||
networkClient.payload.uiObject.resetErrorMessage()
|
||||
|
||||
if (status.isSyncing === false) {
|
||||
networkClient.payload.uiObject.setStatus('Client is looking for peers...', ANNIMATION_CYCLES_TO_LAST)
|
||||
return
|
||||
}
|
||||
/* If it is not syncing, then we have the current block and the highets block too */
|
||||
let percentage = (status.isSyncing.currentBlock * 100 / status.isSyncing.highestBlock).toFixed(4)
|
||||
let extraStatus = ''
|
||||
if (status.isSyncing.highestBlock - status.isSyncing.currentBlock < 300) {
|
||||
extraStatus = 'Block Download Phase Finished. Downloading Trie Data Structure.'
|
||||
} else {
|
||||
networkClient.payload.uiObject.setStatus('Not connected to Ethereum Client.')
|
||||
extraStatus = 'Block Download Phase.'
|
||||
networkClient.payload.uiObject.setPercentage(percentage, ANNIMATION_CYCLES_TO_LAST)
|
||||
}
|
||||
*/
|
||||
} catch (err) {
|
||||
networkClient.payload.uiObject.setErrorMessage('Error connecting to this client: ' + err.message)
|
||||
}
|
||||
|
||||
} else {
|
||||
setStatus()
|
||||
}
|
||||
async function setStatus() {
|
||||
networkClient.payload.uiObject.valueAtAngle = false
|
||||
networkClient.payload.uiObject.setValue(
|
||||
'Block ' + splitLargeNumber(status.isSyncing.currentBlock) +
|
||||
' from ' + splitLargeNumber(status.isSyncing.highestBlock) +
|
||||
'. State ' + splitLargeNumber(status.isSyncing.pulledStates) +
|
||||
' from ' + splitLargeNumber(status.isSyncing.knownStates)
|
||||
, 200)
|
||||
|
||||
networkClient.payload.uiObject.resetErrorMessage()
|
||||
try {
|
||||
client.isSyncing = await client.web3.eth.isSyncing()
|
||||
client.chainId = await client.web3.eth.getChainId()
|
||||
} catch {
|
||||
networkClient.payload.uiObject.resetStatus()
|
||||
networkClient.payload.uiObject.setErrorMessage('Connection to client lost.')
|
||||
clientMap.delete(networkClient.id)
|
||||
return
|
||||
}
|
||||
if (status.isSyncing.currentBlock !== status.isSyncing.highestBlock) {
|
||||
networkClient.payload.uiObject.setStatus('Connected via http. Client is Syncing... ' + extraStatus, ANNIMATION_CYCLES_TO_LAST)
|
||||
} else {
|
||||
networkClient.payload.uiObject.setStatus('Connected to ' + client.networkName + ' via http. ', ANNIMATION_CYCLES_TO_LAST)
|
||||
}
|
||||
|
||||
client.networkName = UI.projects.ethereum.globals.chainIds.chainNameById(client.chainId)
|
||||
|
||||
if (client.isSyncing === false) {
|
||||
networkClient.payload.uiObject.setStatus('Client is looking for peers...')
|
||||
return
|
||||
}
|
||||
/* If it is not syncing, then we have the current block and the highets block too */
|
||||
let percentage = (client.isSyncing.currentBlock * 100 / client.isSyncing.highestBlock).toFixed(4)
|
||||
let extraStatus = ''
|
||||
if (client.isSyncing.highestBlock - client.isSyncing.currentBlock < 300) {
|
||||
extraStatus = 'Block Download Finished. Downloading Trie Data Structure.'
|
||||
} else {
|
||||
extraStatus = 'Block Download Phase.'
|
||||
networkClient.payload.uiObject.setPercentage(percentage)
|
||||
}
|
||||
|
||||
networkClient.payload.uiObject.valueAtAngle = false
|
||||
networkClient.payload.uiObject.setValue('Block ' + client.isSyncing.currentBlock + ' from ' + client.isSyncing.highestBlock + '. State ' + client.isSyncing.pulledStates + ' from ' + client.isSyncing.knownStates)
|
||||
|
||||
if (client.isSyncing.currentBlock !== client.isSyncing.highestBlock) {
|
||||
networkClient.payload.uiObject.setStatus('Connected via http. Client is Syncing... ' + extraStatus)
|
||||
} else {
|
||||
networkClient.payload.uiObject.setStatus('Connected to ' + client.networkName + ' via http. ')
|
||||
function splitLargeNumber(number) {
|
||||
let label = number.toString()
|
||||
let result = label
|
||||
switch (label.length) {
|
||||
case 4: {
|
||||
return label[0] + ',' + label[1] + label[2] + label[3]
|
||||
}
|
||||
case 5: {
|
||||
return label[0] + label[1] + ',' + label[2] + label[3] + label[4]
|
||||
}
|
||||
case 6: {
|
||||
return label[0] + label[1] + label[2] + ',' + label[3] + label[4] + label[5]
|
||||
}
|
||||
case 7: {
|
||||
return label[0] + ',' + label[1] + label[2] + label[3] + ',' + label[4] + label[5] + label[6]
|
||||
}
|
||||
case 8: {
|
||||
return label[0] + label[1] + ',' + label[2] + label[3] + label[4] + ',' + label[5] + label[6] + label[7]
|
||||
}
|
||||
case 9: {
|
||||
return label[0] + label[1] + label[2] + ',' + label[3] + label[4] + label[5] + ',' + label[6] + label[7] + label[8]
|
||||
}
|
||||
case 10: {
|
||||
return label[0] + ',' + label[1] + label[2] + label[3] + ',' + label[4] + label[5] + label[6] + ',' + label[7] + label[8] + label[9]
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] checkStatus -> err = ' + err.stack) }
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] physics -> err = ' + err.stack) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1761,7 +1761,7 @@ function newUiObject() {
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
if (radius > 6) {
|
||||
const MAX_LABEL_LENGTH = 65
|
||||
const MAX_LABEL_LENGTH = 70
|
||||
|
||||
label = currentValue
|
||||
if (!isNaN(currentValue)) {
|
||||
|
||||
Reference in new issue
Block a user