Menci
6 years ago
9 changed files with 105 additions and 65 deletions
@ -1,8 +1,10 @@ |
|||||||
import { disconnect as disconnectRMQ } from './rmq'; |
import { disconnect as disconnectRMQ } from './rmq'; |
||||||
|
import { disconnect as disconnectSIO } from './remote'; |
||||||
import winston = require('winston'); |
import winston = require('winston'); |
||||||
|
|
||||||
export function cleanUp(retCode: number) { |
export function cleanUp(retCode: number) { |
||||||
winston.info('Cleaning up...'); |
winston.info('Cleaning up...'); |
||||||
disconnectRMQ(); |
disconnectRMQ(); |
||||||
process.exit(1); |
disconnectSIO(); |
||||||
|
process.exit(retCode); |
||||||
} |
} |
@ -0,0 +1,75 @@ |
|||||||
|
import * as url from 'url'; |
||||||
|
import * as util from 'util'; |
||||||
|
import { globalConfig as Cfg } from './config'; |
||||||
|
import msgpack = require('msgpack-lite'); |
||||||
|
import winston = require('winston'); |
||||||
|
import { ProgressReportData } from '../interfaces'; |
||||||
|
import { JudgeTask } from './interfaces'; |
||||||
|
import * as SocketIOClient from 'socket.io-client'; |
||||||
|
|
||||||
|
let socketIOConnection: SocketIOClient.Socket; |
||||||
|
let cancelCurrentPull: Function; |
||||||
|
|
||||||
|
export async function connect() { |
||||||
|
const socketIOUrl = url.resolve(Cfg.serverUrl, 'judge'); |
||||||
|
winston.verbose(`Connect to Socket.IO "${socketIOUrl}"...`); |
||||||
|
socketIOConnection = SocketIOClient(socketIOUrl); |
||||||
|
|
||||||
|
socketIOConnection.on('disconnect', () => { |
||||||
|
winston.verbose(`Disconnected from Socket.IO "${socketIOUrl}"...`); |
||||||
|
if (cancelCurrentPull) cancelCurrentPull(); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
export async function disconnect() { |
||||||
|
socketIOConnection.close(); |
||||||
|
} |
||||||
|
|
||||||
|
export async function waitForTask(handle: (task: JudgeTask) => Promise<void>) { |
||||||
|
while (true) { |
||||||
|
winston.verbose('Waiting for new task...'); |
||||||
|
await new Promise((resolve, reject) => { |
||||||
|
// This should be cancelled if socket disconnects.
|
||||||
|
let cancelled = false; |
||||||
|
cancelCurrentPull = () => { |
||||||
|
cancelled = true; |
||||||
|
winston.verbose('Cancelled task polling since disconnected.'); |
||||||
|
resolve(); |
||||||
|
} |
||||||
|
|
||||||
|
socketIOConnection.once('onTask', async (payload: Buffer, ack: Function) => { |
||||||
|
// After cancelled, a new pull is emitted while socket's still disconnected.
|
||||||
|
if (cancelled) return; |
||||||
|
|
||||||
|
try { |
||||||
|
winston.verbose('onTask.'); |
||||||
|
await handle(msgpack.decode(payload)); |
||||||
|
ack(); |
||||||
|
resolve(); |
||||||
|
} catch (e) { |
||||||
|
reject(e); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
socketIOConnection.emit('waitForTask', Cfg.serverToken, () => { |
||||||
|
winston.verbose('waitForTask acked.'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Difference between result and progress:
|
||||||
|
// The `progress' is to be handled by *all* frontend proxies and pushed to all clients.
|
||||||
|
// The `result' is to be handled only *once*, and is to be written to the database.
|
||||||
|
|
||||||
|
export async function reportProgress(data: ProgressReportData) { |
||||||
|
winston.verbose('Reporting progress', data); |
||||||
|
const payload = msgpack.encode(data); |
||||||
|
socketIOConnection.emit('reportProgress', Cfg.serverToken, payload); |
||||||
|
} |
||||||
|
|
||||||
|
export async function reportResult(data: ProgressReportData) { |
||||||
|
winston.verbose('Reporting result', data); |
||||||
|
const payload = msgpack.encode(data); |
||||||
|
socketIOConnection.emit('reportResult', Cfg.serverToken, payload); |
||||||
|
} |
Loading…
Reference in new issue