{"version":3,"sources":["../../src/service/RequestQueue.ts"],"sourcesContent":["import { await_interval, Queue, log } from '../utils/index.js';\nimport type { Request } from './types/index.js';\n\nclass RequestQueue {\n    /* This class will keep track of all the requests that are made to the service,\n     * how long each request takes to be processed,\n     * how many requests are in the queue,\n     * when the requests are being processed, and\n     * request individually.\n     */\n\n    private queue: Queue<Request> = new Queue();\n    private process_request: Function;\n    private get_slave: Function;\n    private isRunning: boolean = false;\n    private interval: NodeJS.Timeout;\n    private heartbeat = 100; // Check every 100ms if the request is completed\n    private turnover_times: number[] = []; // Stores time taken for the last 500 requests\n    private MAX_TURNOVER_ENTRIES = 500; // Limit storage to last 500 requests\n\n    constructor({ process_request, get_slave }: { process_request: Function, get_slave: Function }) {\n        /*\n         * Set an interval to check if there are items in the queue.\n         * If there are, pop the first element and process it.\n         * If there are no elements, wait for the next element to be added.\n         */\n        // set functions\n        this.process_request = process_request;\n        this.get_slave = get_slave;\n        if (!this.process_request) throw new Error('Process request cannot be null');\n        if (!this.get_slave) throw new Error('Get slave cannot be null');\n        // run interval\n        this.interval = setInterval(async () => {\n            // do not run another function if the previous one is still running\n            if (this.isRunning) return;\n            // if there are no items in the queue\n            if (this.queue.size() === 0) { \n                this.isRunning = false;\n                return;\n            }\n            // start the request function\n            this.isRunning = true;\n            // get the first request from queue\n            let request = this.queue.pop();\n            if(request === false) throw new Error('Request is null... is the request queue empty?');\n            // get a slave to process the request\n            const slave = await this.get_slave(request.selector);\n            // process the request\n            let startTime = Date.now();\n            let endTime : number;\n            // set running as false\n            this.isRunning = false;\n            // process the request\n            this.process_request(slave, request).then(\n                (result: any) => { // record the time\n                    if(!request) throw new Error('Request is false... is the request queue empty?');\n                    endTime = Date.now();\n                    // add values to the request\n                    request.completed = true;\n                    request.result = result;\n                    // Track the time taken for this request\n                    const timeTaken = endTime - startTime;\n                    //log(`[RequestQueue] Request completed in ${timeTaken}ms`);\n                    this.turnover_times.push(timeTaken);\n                    // Keep only the last 500 entries\n                    if (this.turnover_times.length > this.MAX_TURNOVER_ENTRIES) \n                        this.turnover_times.shift(); // Remove the oldest entry\n                }\n            ).catch((err : any) => {\n                console.error('[RequestQueue] Request failed to complete');\n                console.error(err);\n                return err;\n            });\n        }, 100);\n    }\n\n    public addRequest(request: Request): Promise<any> {\n        // Add request to the queue and return a promise\n        // that will be resolved when the request is completed\n        return new Promise(async (resolve, reject) => {\n            this.queue.push(request);\n            // Wait until the request is completed, or 60 minutes\n            await await_interval(() => {\n                log(request);\n                return request.completed === true;\n            }, 60 * 60 * 1000, this.heartbeat)\n            .catch(err => {\n                console.error('[RequestQueue] Request failed to complete');\n                console.error(err);\n                reject(err)\n            });\n            // Resolve the promise with the result of the request\n            resolve(request.result);\n        });\n    }\n\n    public queueSize() : number {\n        return this.queue.size();\n    }\n\n    public getTurnoverRatio(): number {\n        if (this.turnover_times.length === 0) return 0;\n        const sum = this.turnover_times.reduce((acc, time) => acc + time, 0);\n        return sum / this.turnover_times.length;\n    }\n\n    public exit() {\n        this.queue.clear();\n        clearInterval(this.interval);\n\n    }\n}\n\nexport default RequestQueue;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA2C;AAG3C,MAAM,aAAa;AAAA;AAAA,EAiBf,YAAY,EAAE,iBAAiB,UAAU,GAAuD;AAThG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAQ,SAAwB,IAAI,mBAAM;AAC1C,wBAAQ;AACR,wBAAQ;AACR,wBAAQ,aAAqB;AAC7B,wBAAQ;AACR,wBAAQ,aAAY;AACpB;AAAA,wBAAQ,kBAA2B,CAAC;AACpC;AAAA,wBAAQ,wBAAuB;AAS3B,SAAK,kBAAkB;AACvB,SAAK,YAAY;AACjB,QAAI,CAAC,KAAK,gBAAiB,OAAM,IAAI,MAAM,gCAAgC;AAC3E,QAAI,CAAC,KAAK,UAAW,OAAM,IAAI,MAAM,0BAA0B;AAE/D,SAAK,WAAW,YAAY,YAAY;AAEpC,UAAI,KAAK,UAAW;AAEpB,UAAI,KAAK,MAAM,KAAK,MAAM,GAAG;AACzB,aAAK,YAAY;AACjB;AAAA,MACJ;AAEA,WAAK,YAAY;AAEjB,UAAI,UAAU,KAAK,MAAM,IAAI;AAC7B,UAAG,YAAY,MAAO,OAAM,IAAI,MAAM,gDAAgD;AAEtF,YAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,QAAQ;AAEnD,UAAI,YAAY,KAAK,IAAI;AACzB,UAAI;AAEJ,WAAK,YAAY;AAEjB,WAAK,gBAAgB,OAAO,OAAO,EAAE;AAAA,QACjC,CAAC,WAAgB;AACb,cAAG,CAAC,QAAS,OAAM,IAAI,MAAM,iDAAiD;AAC9E,oBAAU,KAAK,IAAI;AAEnB,kBAAQ,YAAY;AACpB,kBAAQ,SAAS;AAEjB,gBAAM,YAAY,UAAU;AAE5B,eAAK,eAAe,KAAK,SAAS;AAElC,cAAI,KAAK,eAAe,SAAS,KAAK;AAClC,iBAAK,eAAe,MAAM;AAAA,QAClC;AAAA,MACJ,EAAE,MAAM,CAAC,QAAc;AACnB,gBAAQ,MAAM,2CAA2C;AACzD,gBAAQ,MAAM,GAAG;AACjB,eAAO;AAAA,MACX,CAAC;AAAA,IACL,GAAG,GAAG;AAAA,EACV;AAAA,EAEO,WAAW,SAAgC;AAG9C,WAAO,IAAI,QAAQ,OAAO,SAAS,WAAW;AAC1C,WAAK,MAAM,KAAK,OAAO;AAEvB,gBAAM,6BAAe,MAAM;AACvB,8BAAI,OAAO;AACX,eAAO,QAAQ,cAAc;AAAA,MACjC,GAAG,KAAK,KAAK,KAAM,KAAK,SAAS,EAChC,MAAM,SAAO;AACV,gBAAQ,MAAM,2CAA2C;AACzD,gBAAQ,MAAM,GAAG;AACjB,eAAO,GAAG;AAAA,MACd,CAAC;AAED,cAAQ,QAAQ,MAAM;AAAA,IAC1B,CAAC;AAAA,EACL;AAAA,EAEO,YAAqB;AACxB,WAAO,KAAK,MAAM,KAAK;AAAA,EAC3B;AAAA,EAEO,mBAA2B;AAC9B,QAAI,KAAK,eAAe,WAAW,EAAG,QAAO;AAC7C,UAAM,MAAM,KAAK,eAAe,OAAO,CAAC,KAAK,SAAS,MAAM,MAAM,CAAC;AACnE,WAAO,MAAM,KAAK,eAAe;AAAA,EACrC;AAAA,EAEO,OAAO;AACV,SAAK,MAAM,MAAM;AACjB,kBAAc,KAAK,QAAQ;AAAA,EAE/B;AACJ;AAEA,IAAO,uBAAQ;","names":[]}