make admin watch tools go over socket events (breaks it for shards)
This commit is contained in:
parent
f7352a49c7
commit
b84c6e9b60
|
@ -11,6 +11,7 @@ import Sequelize from 'sequelize';
|
||||||
import isIPAllowed from './isAllowed';
|
import isIPAllowed from './isAllowed';
|
||||||
import { validateCoorRange } from '../utils/validation';
|
import { validateCoorRange } from '../utils/validation';
|
||||||
import CanvasCleaner from './CanvasCleaner';
|
import CanvasCleaner from './CanvasCleaner';
|
||||||
|
import socketEvents from '../socket/socketEvents';
|
||||||
import { RegUser } from '../data/sql';
|
import { RegUser } from '../data/sql';
|
||||||
import {
|
import {
|
||||||
cleanCacheForIP,
|
cleanCacheForIP,
|
||||||
|
@ -36,12 +37,6 @@ import {
|
||||||
imageABGR2Canvas,
|
imageABGR2Canvas,
|
||||||
protectCanvasArea,
|
protectCanvasArea,
|
||||||
} from './Image';
|
} from './Image';
|
||||||
import {
|
|
||||||
getIIDSummary,
|
|
||||||
getIIDPixels,
|
|
||||||
getSummaryFromArea,
|
|
||||||
getPixelsFromArea,
|
|
||||||
} from './parsePixelLog';
|
|
||||||
import rollbackCanvasArea from './rollback';
|
import rollbackCanvasArea from './rollback';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -299,13 +294,17 @@ export async function executeWatchAction(
|
||||||
let ret;
|
let ret;
|
||||||
if (!ulcoor && !brcoor && iid) {
|
if (!ulcoor && !brcoor && iid) {
|
||||||
if (action === 'summary') {
|
if (action === 'summary') {
|
||||||
ret = await getIIDSummary(
|
ret = await socketEvents.req(
|
||||||
|
'watch',
|
||||||
|
'getIIDSummary',
|
||||||
iid,
|
iid,
|
||||||
time,
|
time,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (action === 'all') {
|
if (action === 'all') {
|
||||||
ret = await getIIDPixels(
|
ret = await socketEvents.req(
|
||||||
|
'watch',
|
||||||
|
'getIIDPixels',
|
||||||
iid,
|
iid,
|
||||||
time,
|
time,
|
||||||
);
|
);
|
||||||
|
@ -332,7 +331,9 @@ export async function executeWatchAction(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action === 'summary') {
|
if (action === 'summary') {
|
||||||
ret = await getSummaryFromArea(
|
ret = await socketEvents.req(
|
||||||
|
'watch',
|
||||||
|
'getSummaryFromArea',
|
||||||
canvasid,
|
canvasid,
|
||||||
x, y, u, v,
|
x, y, u, v,
|
||||||
time,
|
time,
|
||||||
|
@ -340,7 +341,9 @@ export async function executeWatchAction(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (action === 'all') {
|
if (action === 'all') {
|
||||||
ret = await getPixelsFromArea(
|
ret = await socketEvents.req(
|
||||||
|
'watch',
|
||||||
|
'getPixelsFromArea',
|
||||||
canvasid,
|
canvasid,
|
||||||
x, y, u, v,
|
x, y, u, v,
|
||||||
time,
|
time,
|
||||||
|
|
|
@ -2,6 +2,7 @@ import fs from 'fs';
|
||||||
import readline from 'readline';
|
import readline from 'readline';
|
||||||
|
|
||||||
import { PIXELLOGGER_PREFIX } from './logger';
|
import { PIXELLOGGER_PREFIX } from './logger';
|
||||||
|
import socketEvents from '../socket/socketEvents';
|
||||||
import { getNamesToIds } from '../data/sql/RegUser';
|
import { getNamesToIds } from '../data/sql/RegUser';
|
||||||
import {
|
import {
|
||||||
getIdsToIps,
|
getIdsToIps,
|
||||||
|
@ -392,3 +393,16 @@ export async function getPixelsFromArea(
|
||||||
rows,
|
rows,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
socketEvents.onReq('watch', (action, ...args) => {
|
||||||
|
if (action === 'getIIDSummary') {
|
||||||
|
return getIIDSummary(...args);
|
||||||
|
} if (action === 'getIIDPixels') {
|
||||||
|
return getIIDPixels(...args);
|
||||||
|
} if (action === 'getSummaryFromArea') {
|
||||||
|
return getSummaryFromArea(...args);
|
||||||
|
} if (action === 'getPixelsFromArea') {
|
||||||
|
return getPixelsFromArea(...args);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
|
@ -496,3 +496,28 @@ export function parseInterval(interval) {
|
||||||
}
|
}
|
||||||
return (num * factor);
|
return (num * factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* conbine two similar objects
|
||||||
|
*/
|
||||||
|
export function combineObjects(a, b) {
|
||||||
|
if (!b) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
if (!a) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
if (Array.isArray(a)) {
|
||||||
|
return a.concat(b);
|
||||||
|
}
|
||||||
|
if (typeof a === 'object') {
|
||||||
|
let keys = Object.keys(a);
|
||||||
|
keys.forEach((key) => {
|
||||||
|
const u = a[key];
|
||||||
|
const v = b[key];
|
||||||
|
a[key] = combineObjects(u, v);
|
||||||
|
});
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* sends messages to other ppfun instances
|
* sends messages to other ppfun instances
|
||||||
* to work as cluster
|
* to work as cluster
|
||||||
|
* If methods have no descriptions, they can be checked in ./SockEvents.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
@ -56,6 +57,9 @@ class MessageBroker extends SocketEvents {
|
||||||
console.log('CLUSTER: Initialized message broker');
|
console.log('CLUSTER: Initialized message broker');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* messages on shared broadcast channels that every shard is listening to
|
||||||
|
*/
|
||||||
async onShardBCMessage(message) {
|
async onShardBCMessage(message) {
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
|
@ -117,6 +121,48 @@ class MessageBroker extends SocketEvents {
|
||||||
|| this.shardOnlineCounters[0][0] === this.thisShard;
|
|| this.shardOnlineCounters[0][0] === this.thisShard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* requests that go over all shards and wait for responses from all
|
||||||
|
*/
|
||||||
|
reqOnShards(type, ...args) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const chan = Math.floor(Math.random() * 100000).toString()
|
||||||
|
+ Math.floor(Math.random() * 100000).toString();
|
||||||
|
const chankey = `res:${chan}`;
|
||||||
|
|
||||||
|
let amountOtherShards = this.shardOnlineCounters.length - 1;
|
||||||
|
let id;
|
||||||
|
let ret = null;
|
||||||
|
await this.subscriber.subscribe(chankey, (message) => {
|
||||||
|
amountOtherShards -= 1;
|
||||||
|
const retn = JSON.parse(message);
|
||||||
|
combineObjects(ret, retn);
|
||||||
|
if (!amountOtherShards) {
|
||||||
|
this.subscriber.unsubscribe(chankey);
|
||||||
|
clearTimeout(id);
|
||||||
|
resolve(ret);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
id = setTimeout(() => {
|
||||||
|
this.subscriber.unsubscribe(chankey);
|
||||||
|
reject(new Error(`Timeout on req ${type}`));
|
||||||
|
}, 45000);
|
||||||
|
this.emit(`req:${type}`, chan, ...args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async reqOnShards(...args) {
|
||||||
|
const ret = Promise.all([
|
||||||
|
this.reqShard(...args),
|
||||||
|
super.req(...args),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
onReq(type, cb) {
|
||||||
|
this.on(`req:${type}`, async (chan, ...args) => {
|
||||||
|
const ret = await cb(...args);
|
||||||
|
this.emit(`res:${chan}`, ret);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
updateShardOnlineCounter(shard, cnt) {
|
updateShardOnlineCounter(shard, cnt) {
|
||||||
const shardCounter = this.shardOnlineCounters.find(
|
const shardCounter = this.shardOnlineCounters.find(
|
||||||
(c) => c[0] === shard,
|
(c) => c[0] === shard,
|
||||||
|
@ -130,6 +176,9 @@ class MessageBroker extends SocketEvents {
|
||||||
this.sumOnlineCounters();
|
this.sumOnlineCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* messages on binary shard channels, where specific shards send from
|
||||||
|
*/
|
||||||
onShardBinaryMessage(buffer, shard) {
|
onShardBinaryMessage(buffer, shard) {
|
||||||
try {
|
try {
|
||||||
const opcode = buffer[0];
|
const opcode = buffer[0];
|
||||||
|
@ -186,9 +235,6 @@ class MessageBroker extends SocketEvents {
|
||||||
*/
|
*/
|
||||||
emit(key, ...args) {
|
emit(key, ...args) {
|
||||||
super.emit(key, ...args);
|
super.emit(key, ...args);
|
||||||
if (key === 'recvChatMessage') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const msg = `${this.thisShard}:${key},${JSON.stringify(args)}`;
|
const msg = `${this.thisShard}:${key},${JSON.stringify(args)}`;
|
||||||
this.publisher.publish('bc', msg);
|
this.publisher.publish('bc', msg);
|
||||||
}
|
}
|
||||||
|
@ -223,6 +269,14 @@ class MessageBroker extends SocketEvents {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recvChatMessage(
|
||||||
|
user,
|
||||||
|
message,
|
||||||
|
channelId,
|
||||||
|
) {
|
||||||
|
super.emit('recvChatMessage', user, message, channelId);
|
||||||
|
}
|
||||||
|
|
||||||
broadcastChunkUpdate(
|
broadcastChunkUpdate(
|
||||||
canvasId,
|
canvasId,
|
||||||
chunk,
|
chunk,
|
||||||
|
|
|
@ -48,6 +48,37 @@ class SocketEvents extends EventEmitter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* requests that expect a response
|
||||||
|
* req(type, args) can be awaited
|
||||||
|
* it will return a response from whatever listenes on onReq(type, cb(args))
|
||||||
|
*/
|
||||||
|
req(type, ...args) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const chan = Math.floor(Math.random() * 100000).toString()
|
||||||
|
+ Math.floor(Math.random() * 100000).toString();
|
||||||
|
const chankey = `res:${chan}`;
|
||||||
|
let id;
|
||||||
|
const callback = (ret) => {
|
||||||
|
clearTimeout(id);
|
||||||
|
resolve(ret);
|
||||||
|
};
|
||||||
|
id = setTimeout(() => {
|
||||||
|
this.off(chankey, callback);
|
||||||
|
reject(new Error(`Timeout on req ${type}`));
|
||||||
|
}, 45000);
|
||||||
|
this.once(chankey, callback);
|
||||||
|
this.emit(`req:${type}`, chan, ...args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onReq(type, cb) {
|
||||||
|
this.on(`req:${type}`, async (chan, ...args) => {
|
||||||
|
const ret = await cb(...args);
|
||||||
|
this.emit(`res:${chan}`, ret);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* broadcast pixel message via websocket
|
* broadcast pixel message via websocket
|
||||||
* @param canvasId number ident of canvas
|
* @param canvasId number ident of canvas
|
||||||
|
|
Loading…
Reference in New Issue
Block a user