UNPKG

slavery-js

Version:

A simple clustering app that allows you to scale an application on multiple thread, containers or machines

1 lines 26 kB
{"version":3,"sources":["../../src/nodes/Node.ts"],"sourcesContent":["import Network, { Listener, Connection } from '../network/index.js';\nimport { ServiceClient } from '../service/index.js';\nimport type { ServiceAddress } from './types/index.js';\nimport { await_interval, execAsyncCode, log } from '../utils/index.js';\nimport { serializeError, deserializeError } from 'serialize-error';\n\n/*\n * this class will basicaly connect to all of the services given to it by the primary service.\n * 1.- attempt to make a conenction the primary service passed by the server\n * 2.- it will take a list of services\n\n/* this calss will make a slave type which will be an a child of the Node class\n * this is the class that will be used to run the the client of a node\n * like other classes it will work as both\n * the server connection to the client and the client conenction to the server.\n * this class will have a list of methods that will be converted to listeners\n * and a list of listeners that will be converted to methods\n */\n\ntype NodeStatus = 'idle' | 'working' | 'error';\n\nclass Node {\n public mode: 'client' | 'server' | undefined = undefined;\n public id: string | undefined = undefined;\n public status: NodeStatus = 'idle';\n public listeners: Listener[] = [];\n public lastUpdateAt: number = Date.now();\n public network: Network | undefined = undefined;\n public servicesConnected: boolean = false;\n // fields when the class is client handler on a service\n public statusChangeCallback: ((status: NodeStatus, node: Node) => void) | null = null;\n // stash changes functions\n public stashSetFunction: (({ key, value }: { key: string, value: any }) => any) | null = null;\n public stashGetFunction: ((key: string) => any) | null = null;\n // fields when the class is a service handler on a node\n public services: ServiceAddress[] = [];\n public doneMethods: { [key: string]: boolean } = {};\n public methods: { [key: string]: (parameter?: any, self?: Node) => any } = {};\n\n constructor(){}\n\n /* this function will work on any mode the class is on */\n\n public getId = () => this.id;\n public getStatus = () => this.status;\n public lastHeardOfIn = () => Date.now() - this.lastUpdateAt;\n public isIdle = () => this.status === 'idle';\n public isWorking = () => this.status === 'working';\n public isError = () => this.status === 'error';\n private updateLastHeardOf = () => this.lastUpdateAt = Date.now();\n private updateStatus = (status: NodeStatus) => this.status = status;\n public untilFinish = async () => { // await until the node is idle\n await await_interval(() => this.isIdle(), 1000)\n .catch(() => { throw new Error('The node is not idle') })\n return true;\n }\n\n public run = async (method: string, parameter: any) => {\n if(this.mode === 'client') return await this.run_client({ method, parameter });\n else if(this.mode === 'server') return await this.run_server({ method, parameter });\n else throw new Error('The mode has not been set');\n }\n\n public exec = async (method: string, code: string) => {\n if(this.mode === 'client') return await this.exec_client(code);\n else if(this.mode === 'server') return await this.exec_server(code);\n else throw new Error('The mode has not been set');\n }\n\n public setServices = async (services: ServiceAddress[]) => {\n if(this.mode === 'client') return await this.setServices_client(services);\n else if(this.mode === 'server') return await this.setServices_server(services);\n else throw new Error('The mode has not been set');\n }\n\n public exit = async () => {\n if(this.mode === 'client') return await this.exit_client();\n else if(this.mode === 'server') return await this.exit_server();\n else throw new Error('The mode has not been set');\n }\n\n public ping = async () => {\n if(this.mode === 'client') return await this.ping_client();\n else if(this.mode === 'server') return await this.ping_server();\n else throw new Error('The mode has not been set');\n }\n\n /* this functions will set the Node.ts as a client handler for the server */\n public setNodeConnection(connection: Connection, network: Network){\n if(this.mode !== undefined && this.mode !== null )\n throw new Error('The node mode has already been set');\n // set the mode as a server client hander\n this.mode = 'server';\n // get the node id from the conenction\n this.id = connection.getTargetId();\n // set the network\n this.network = network;\n // define the listners which we will be using to talk witht the client node\n if(this.stashSetFunction === null || this.stashGetFunction === null )\n throw new Error('The stash functions have not been set');\n // set the listeners\n this.listeners = [// this callbacks will run when we recive this event from the client node\n { event: '_set_status', parameters: ['status'], callback: this.handleStatusChange.bind(this) },\n { event: '_ping', parameters: [], callback: () => '_pong' },\n { event: '_set_stash', parameters: ['key', 'value'], callback: this.stashSetFunction },\n { event: '_get_stash', parameters: ['key'], callback: this.stashGetFunction },\n ]\n // register the listeners on the connection\n connection.setListeners(this.listeners);\n }\n\n public setStatusChangeCallback(callback: (status: NodeStatus, node: Node) => void){\n this.statusChangeCallback = callback;\n }\n\n public setStashFunctions({ set, get }: { set: (key: string, value: any) => any, get: (key: string) => any }){\n this.stashSetFunction = ({ key, value }: { key: string, value: any }) => set(key, value);\n this.stashGetFunction = get;\n }\n\n public handleStatusChange(status: NodeStatus){\n // set status as status and call the callback\n this.updateStatus(status);\n this.statusChangeCallback && this.statusChangeCallback(status, this);\n }\n\n public lastHeardOf(){\n // this function will be called when the client node tells us that it is working\n this.updateLastHeardOf();\n return this.lastHeardOfIn();\n }\n\n private async run_server({method, parameter}: {method: string, parameter: any}){\n // this function will send the node a method to be run in the client\n // set the status to working\n this.handleStatusChange('working');\n let res = await this.send('_run', { method, parameter });\n // set the status to idle\n this.handleStatusChange('idle');\n // if there is an error\n if(res.isError === true)\n res.error = deserializeError(res.error);\n // return the result\n return res\n }\n\n private async exec_server(code: string){\n // this function will send the node a code to be run in the client\n // set the status to working\n this.handleStatusChange('working');\n let res = await this.send('_exec', code);\n // set the status to idle\n this.handleStatusChange('idle');\n // if there is an error\n if(res.isError === true)\n res.error = deserializeError(res.error);\n // return the result\n return res\n }\n\n private async setServices_server(services: ServiceAddress[]){\n // this function will send send a list of services to the client node\n let res = await this.send('_set_services', services);\n return res;\n }\n\n public async ping_server(){\n // this function will ping the client node\n let res = await this.send('_ping');\n if(res === 'pong') this.updateLastHeardOf();\n return true;\n }\n\n public async exit_server(){\n // this function tell the node client to exit\n let res = await this.send('_exit', null)\n // we catch the timeout erro scince the client node will exit\n .catch((error) => { if(error === 'timeout') return true; else throw error; });\n return res\n }\n\n public async registerServices(service: ServiceAddress[]){\n // for every service we need to send the service address to the client node\n let services = service.map(service => new Promise(async (resolve) => {\n let result = await this.send('_connect_service', service);\n resolve(result);\n }));\n // await until they are all connected\n return await Promise.all(services);\n }\n\n public async send(method: string, parameter: any = null){\n // fucntion for sending a method to the client node\n if(this.network === undefined) throw new Error('The network has not been set');\n if(this.id === undefined) throw new Error('The id has not been set');\n if(this.mode === undefined) throw new Error('The mode has not been set');\n // get the connection of which we will send the method\n let connection: Connection | undefined = undefined;\n if(this.mode === 'server')\n connection = this.network.getNode(this.id);\n else if(this.mode === 'client')\n connection = this.network.getService('master');\n if(connection === undefined)\n throw new Error('Could not get the conenction from the network');\n // send the method to the node\n return await connection.send(method, parameter);\n }\n\n\n /* this function will be called when the client node tells us that it is working */\n public async connectToMaster(host: string, port: number){\n // conenct the master process which will tell us what to do\n // create an id for the node\n this.id = this.id || Math.random().toString(36).substring(4);\n this.network = new Network({name: 'node', id: this.id});\n // form the conenction with the master\n this.network.connect({ host, port, as: 'master' });\n // set the mode as a client\n this.mode = 'client';\n // set the listeners which we will us on the and the master can call on\n this.listeners = [\n { event: '_run', parameters: ['method', 'parameter'], callback: this.run_client.bind(this) },\n { event: '_exec', parameters: ['code_string'], callback: this.exec_client.bind(this) },\n { event: '_set_services', parameters: ['services'], callback: this.setServices_client.bind(this) },\n { event: '_is_idle', parameters: [], callback: this.isIdle.bind(this) },\n { event: '_is_busy', parameters: [], callback: this.isBusy.bind(this) },\n { event: '_has_done', parameters: ['method'], callback: this.hasDone.bind(this) },\n { event: '_ping', parameters: [], callback: () => 'pong' },\n { event: '_exit', parameters: [], callback: this.exit_client.bind(this) }\n ];\n // register the listeners on the network\n this.network.registerListeners(this.listeners);\n }\n\n private async run_client({method, parameter}: {method: string, parameter: any}){\n // this function will be called by the a service or another node to run a function\n // wait until services are connected, with timeout of 10 seconds\n await await_interval(() => this.servicesConnected, 10000).catch(() => {\n throw new Error(`[Node][${this.id}] Could not connect to the services`);\n })\n try {\n // set the status to working\n this.updateStatus('working');\n // get the services that we have connected to\n let services = this.services.map(\n (s: ServiceAddress) => new ServiceClient(s.name, this.network as Network)\n ).reduce((acc: any, s: ServiceClient) => {\n acc[s.name] = s;\n return acc;\n }, {})\n // run method\n const result = await this.methods[method](parameter, { ...services, slave: this, self: this });\n // set has done method\n this.doneMethods[method] = true;\n // return the result\n return { result, isError: false };\n } catch(error){ // serilize the error\n this.updateStatus('error');\n // return the error\n return { error: serializeError(error), isError: true };\n } finally {\n // set the status to idle\n this.updateStatus('idle');\n }\n }\n\n\n private async exec_client(code_string: string){\n /* this function will execute some passed albitrary code */\n // check if the code_string is a string\n if(typeof code_string !== 'string')\n return { isError: true, error: serializeError(new Error('Code string is not a string')) }\n // await until service is connected\n await await_interval(() => this.servicesConnected, 10000).catch(() => {\n throw new Error(`[Service] Could not connect to the services`);\n })\n let services = this.services.map(\n (s: ServiceAddress) => new ServiceClient(s.name, this.network as Network)\n ).reduce((acc: any, s: ServiceClient) => {\n acc[s.name] = s;\n return acc;\n }, {})\n let parameter = { ...services, master: this, self: this };\n try {\n // run the albitrary code\n let result = await execAsyncCode(code_string, parameter);\n return { result: result, isError: false };\n } catch(e) {\n return { isError: true, error: serializeError(e) }\n }\n }\n\n public async _startup(){\n // this function should not be here, and Node class should be self contained\n // thus this class need an outside class to call it, after it has set up its\n // addMethods and setServices and connectToMaster functions have run.\n if(this.methods['_startup'] !== undefined)\n await this.run_client({ method: '_startup', parameter: null });\n }\n\n // this function will communicate with the master node and set the stash in that moment\n public setStash = async (key: any, value: any = null) => await this.send('_set_stash', { key, value });\n public getStash = async (key: string = '') => await this.send('_get_stash', key);\n\n public addMethods(methods: { [key: string]: (parameter: any) => any }){\n // we add the methods to this class\n this.methods = methods;\n // populate methods done\n for(let method in methods)\n this.doneMethods[method] = false;\n }\n\n\n private async setServices_client(services: ServiceAddress[]){\n // we get the list of services that we need to connect to\n this.services = services;\n // connect to the services\n for(let service of services){\n let res = await this.connectService(service);\n if(!res)\n console.error('Could not connect to the service, ', service.name);\n else\n log(`[Node][${this.id}] Connected to the service, ${service.name}`);\n }\n this.servicesConnected = true;\n return true\n }\n\n public async connectService({ name, host, port }: ServiceAddress){\n /* this is the client inplementation.\n * it will connect to the service and create methods\n * for every listener that the service has */\n if(!host || !port)\n throw new Error('The service information is not complete');\n // check if there is a service already running on the port and host\n if(this.network === undefined)\n throw new Error('The network has not been set');\n return await this.network.connect({name, host, port});\n }\n\n private async ping_client(){\n // this function will ping the master node\n let res = await this.send('_ping');\n if(res === '_pong') this.updateLastHeardOf();\n return true;\n }\n\n private async exit_client(){\n // before we bail we must be nice enough to close our connections\n setTimeout(async () => {\n // if there is a _cleanup method defined\n if(this.methods['_cleanup'] !== undefined)\n await this.run_client({ method: '_cleanup', parameter: null });\n // we close the connections we have,\n if(this.network !== undefined) this.network.close();\n // then we exit the process\n process.exit(0);\n }, 1000);\n return true\n }\n\n public getListeners(){\n if(this.network === undefined) throw new Error('The network has not been set');\n if(this.id === undefined) throw new Error('The id has not been set');\n let listeners = [];\n let connection: Connection | undefined = undefined;\n if(this.mode === 'server'){\n connection = this.network.getNode(this.id);\n listeners = connection.getListeners();\n }else if(this.mode === 'client'){\n connection = this.network.getNode('master');\n listeners = connection.getListeners();\n if(connection === undefined)\n throw new Error('Could not get the conenction from the network');\n }\n return listeners;\n }\n\n public hasDone(method: string){\n return this.doneMethods[method] || false;\n }\n\n /* method synonims */\n public isBusy = this.isWorking;\n public hasFinished = this.hasDone;\n public hasError = this.isError;\n public toFinish = this.untilFinish;\n public set = this.setStash;\n public get = this.getStash;\n public stash = this.setStash;\n public unstash = this.getStash;\n}\n\n\nexport default Node;\n"],"mappings":"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","names":["service","Network"]}