File size: 1,904 Bytes
6f1c297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { argv } from 'yargs';
import { pack, unpack } from 'msgpackr';
import { Reply } from 'zeromq';
import { renderGaugeImage } from '../../libs/gauge-renderer';

interface Params {
	method: string;
	args: any[];
	kwargs: Record<any, any>;
}

const unsafeMethods = ['bind', 'constructor', 'toString', 'toJSON'];

class GaugeServer {
	private socket: Reply;

	async bind(port?: string) {
		this.socket = new Reply();
		await this.socket.bind(port);

		console.log(`gauge server listening at ${port}`);

		try {
			for await (const [data] of this.socket) {
				const { method, args, kwargs } = (unpack(data) as Params) ?? {};

				console.log(`request: ${method}`);

				if (!unsafeMethods.includes(method) && this[method]) {
					try {
						const data = await this[method]?.(args, kwargs);
						console.log(`success: ${method}`);

						await this.socket.send(
							pack({
								code: 0,
								msg: 'success',
								data,
							})
						);
					} catch (err) {
						console.error(`fail: ${method}, error: ${err}`);
						await this.socket.send(
							pack({
								code: -1,
								msg: `Error: ${JSON.stringify(err)}`,
								data: null,
							})
						);
					}
				} else {
					console.error(`fail: ${method}, error: no method`);
					await this.socket.send(
						pack({
							code: -1,
							msg: `no method: ${method}`,
							data: null,
						})
					);
				}
			}
		} catch (err) {
			console.log('restarting gauge server..', err.stack);
			await this.socket.close();
			await this.bind(port);
		}
	}

	async predict(args?: any[], kwargs?: Record<any, any>) {
		let source, gauge, baseY;

		if (args) {
			[source, gauge, baseY] = args;
		}

		if (kwargs) {
			({ source, gauge, baseY } = kwargs);
		}

		return renderGaugeImage(source, gauge, baseY);
	}
}

async function main() {
	const server = new GaugeServer();

	await server.bind(`tcp://*:${argv.port}`);
}

main();