You've already forked pigallery2
mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-07-15 01:24:25 +02:00
improving event loop handling
This commit is contained in:
19
src/backend/model/EventLoopHandler.ts
Normal file
19
src/backend/model/EventLoopHandler.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
export class EventLoopHandler {
|
||||||
|
|
||||||
|
private eventCounter = 0;
|
||||||
|
|
||||||
|
constructor(private readonly MAX_LOOP = 10) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setImmediate is slow, but does the right thing
|
||||||
|
* next tick is super fast, but does not help much with the event loop as it does not allow a full event loop cycle
|
||||||
|
* https://medium.com/dkatalis/eventloop-in-nodejs-settimeout-setimmediate-vs-process-nexttick-37c852c67acb
|
||||||
|
* */
|
||||||
|
step(fn: () => Promise<void> | void) {
|
||||||
|
|
||||||
|
this.eventCounter = this.eventCounter % 10;
|
||||||
|
const eventFN = this.eventCounter++ === 1 ? setImmediate : process.nextTick;
|
||||||
|
eventFN(fn);
|
||||||
|
}
|
||||||
|
}
|
@ -134,6 +134,7 @@ export abstract class Job<T extends Record<string, unknown> = Record<string, unk
|
|||||||
}
|
}
|
||||||
|
|
||||||
private run(): void {
|
private run(): void {
|
||||||
|
// we call setImmediate later.
|
||||||
process.nextTick(async (): Promise<void> => {
|
process.nextTick(async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {TaskQue} from './TaskQue';
|
import {TaskQue} from './TaskQue';
|
||||||
|
import {EventLoopHandler} from '../EventLoopHandler';
|
||||||
|
|
||||||
export interface ITaskExecuter<I, O> {
|
export interface ITaskExecuter<I, O> {
|
||||||
execute(input: I): Promise<O>;
|
execute(input: I): Promise<O>;
|
||||||
@ -7,6 +8,7 @@ export interface ITaskExecuter<I, O> {
|
|||||||
export class TaskExecuter<I, O> implements ITaskExecuter<I, O> {
|
export class TaskExecuter<I, O> implements ITaskExecuter<I, O> {
|
||||||
private taskQue = new TaskQue<I, O>();
|
private taskQue = new TaskQue<I, O>();
|
||||||
private taskInProgress = 0;
|
private taskInProgress = 0;
|
||||||
|
private readonly el = new EventLoopHandler();
|
||||||
private run = async () => {
|
private run = async () => {
|
||||||
if (this.taskQue.isEmpty() || this.taskInProgress >= this.size) {
|
if (this.taskQue.isEmpty() || this.taskInProgress >= this.size) {
|
||||||
return;
|
return;
|
||||||
@ -20,7 +22,7 @@ export class TaskExecuter<I, O> implements ITaskExecuter<I, O> {
|
|||||||
}
|
}
|
||||||
this.taskQue.ready(task);
|
this.taskQue.ready(task);
|
||||||
this.taskInProgress--;
|
this.taskInProgress--;
|
||||||
process.nextTick(this.run);
|
this.el.step(this.run);
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(private size: number, private worker: (input: I) => Promise<O>) {
|
constructor(private size: number, private worker: (input: I) => Promise<O>) {
|
||||||
|
Reference in New Issue
Block a user