mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: fallback for non-replicaset instances
This commit is contained in:
1 parent
429bacfaf2
commit
406e45975f
2 files changed
+25
-8
No files matched your search
@@ -562,7 +562,7 @@ export interface FileNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface EventDoc {
|
export interface EventDoc {
|
||||||
sender: string;
|
ack: string[];
|
||||||
event: number | string;
|
event: number | string;
|
||||||
payload: string;
|
payload: string;
|
||||||
expire: Date;
|
expire: Date;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { hostname } from 'os';
|
|||||||
import moment from 'moment-timezone';
|
import moment from 'moment-timezone';
|
||||||
import { FilterQuery, ObjectID } from 'mongodb';
|
import { FilterQuery, ObjectID } from 'mongodb';
|
||||||
import { sleep } from '@hydrooj/utils/lib/utils';
|
import { sleep } from '@hydrooj/utils/lib/utils';
|
||||||
import { BaseService, Task } from '../interface';
|
import { BaseService, EventDoc, Task } from '../interface';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import * as bus from '../service/bus';
|
import * as bus from '../service/bus';
|
||||||
import db from '../service/db';
|
import db from '../service/db';
|
||||||
@@ -161,18 +161,35 @@ bus.once('app/started', async () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
await collEvent.createIndex({ expire: 1 }, { expireAfterSeconds: 0 });
|
await collEvent.createIndex({ expire: 1 }, { expireAfterSeconds: 0 });
|
||||||
const stream = collEvent.watch([{ $match: { sender: { $ne: id } } }]);
|
const stream = collEvent.watch();
|
||||||
stream.on('change', async (change) => {
|
const handleEvent = async (doc: EventDoc) => {
|
||||||
if (change.operationType !== 'insert') return;
|
|
||||||
const doc = change.fullDocument;
|
|
||||||
const payload = JSON.parse(doc.payload);
|
const payload = JSON.parse(doc.payload);
|
||||||
if (process.send) process.send({ type: 'hydro:broadcast', data: { event: doc.event, payload } });
|
if (process.send) process.send({ type: 'hydro:broadcast', data: { event: doc.event, payload } });
|
||||||
if (doc) bus.parallel(doc.event, ...payload);
|
await bus.parallel(doc.event, ...payload);
|
||||||
|
};
|
||||||
|
stream.on('change', async (change) => {
|
||||||
|
if (change.operationType !== 'insert') return;
|
||||||
|
if (change.fullDocument.ack.includes(id)) return;
|
||||||
|
await handleEvent(change.fullDocument);
|
||||||
|
});
|
||||||
|
stream.on('error', async () => {
|
||||||
|
// The $changeStream stage is only supported on replica sets
|
||||||
|
logger.info('No replica set found.');
|
||||||
|
// eslint-disable-next-line no-constant-condition
|
||||||
|
while (true) {
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const res = await collEvent.findOneAndUpdate(
|
||||||
|
{ ack: { $nin: [id] } },
|
||||||
|
{ $push: { ack: id } },
|
||||||
|
);
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
await (res.value ? handleEvent(res.value) : sleep(500));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
bus.on('bus/broadcast', (event, payload) => {
|
bus.on('bus/broadcast', (event, payload) => {
|
||||||
collEvent.insertOne({
|
collEvent.insertOne({
|
||||||
sender: id,
|
ack: [id],
|
||||||
event,
|
event,
|
||||||
payload: JSON.stringify(payload),
|
payload: JSON.stringify(payload),
|
||||||
expire: new Date(Date.now() + 10000),
|
expire: new Date(Date.now() + 10000),
|
||||||
|
|||||||
Reference in new issue
Block a user