@@ -5,120 +5,146 @@ import { logger } from "~/core/utils/logger";
55import type { config } from "~/typings/database" ;
66
77function convertFromMinToMs ( minutes : number ) : number {
8- return minutes * 60 * 1000 ;
8+ return minutes * 60 * 1000 ;
99}
1010
1111async function initialRun (
12- scheduleName : string ,
13- scheduleFunction : Promise < void > | void ,
14- isAsync : boolean ,
12+ scheduleName : string ,
13+ scheduleFunction : Promise < void > | void ,
14+ isAsync : boolean ,
1515) {
16- try {
17- if ( isAsync ) {
18- await scheduleFunction ;
19- } else {
20- scheduleFunction ;
21- }
22- logger . info ( `Startup run success for: ${ scheduleName } ` ) ;
23- } catch ( error ) {
24- logger . error ( `Startup run failed for ${ scheduleName } , ${ error as string } ` ) ;
25- }
16+ try {
17+ if ( isAsync ) {
18+ await scheduleFunction ;
19+ } else {
20+ scheduleFunction ;
21+ }
22+ logger . info ( `Startup run success for: ${ scheduleName } ` ) ;
23+ } catch ( error ) {
24+ logger . error ( `Startup run failed for ${ scheduleName } , ${ error as string } ` ) ;
25+ }
2626}
2727
28- async function scheduledJob (
29- name : string ,
30- jobFn : ( ) => Promise < void > ,
31- intervalMs : number ,
32- ) {
33- while ( true ) {
34- const start = Date . now ( ) ;
35- logger . info ( `Task Start: ${ name } ` ) ;
36- try {
37- await jobFn ( ) ;
38- logger . info ( `Task End: ${ name } succeeded.` ) ;
39- } catch ( e ) {
40- logger . error ( `Task End: ${ name } failed:` , e ) ;
41- }
42- const elapsed = Date . now ( ) - start ;
43- const delay = Math . max ( 0 , intervalMs - elapsed ) ;
44- await new Promise ( ( r ) => setTimeout ( r , delay ) ) ;
45- }
28+ type CancelFn = ( ) => void ;
29+ let cancelFunctions : CancelFn [ ] = [ ] ;
30+
31+ async function reloadSchedules ( ) {
32+ logger . info ( "Reloading schedules..." ) ;
33+
34+ cancelFunctions . forEach ( ( cancel ) => cancel ( ) ) ;
35+ cancelFunctions = [ ] ;
36+
37+ await setSchedules ( ) ;
38+ }
39+
40+ function scheduledJob (
41+ name : string ,
42+ jobFn : ( ) => Promise < void > ,
43+ intervalMs : number ,
44+ ) : CancelFn {
45+ let stopped = false ;
46+
47+ async function run ( ) {
48+ if ( stopped ) return ;
49+ const start = Date . now ( ) ;
50+ logger . info ( `Task Start: ${ name } ` ) ;
51+ try {
52+ await jobFn ( ) ;
53+ logger . info ( `Task End: ${ name } succeeded.` ) ;
54+ } catch ( e ) {
55+ logger . error ( `Task End: ${ name } failed:` , e ) ;
56+ }
57+ const elapsed = Date . now ( ) - start ;
58+ const delay = Math . max ( 0 , intervalMs - elapsed ) ;
59+ setTimeout ( run , delay ) ;
60+ }
61+
62+ run ( ) ;
63+
64+ return ( ) => {
65+ stopped = true ;
66+ } ;
4667}
4768
4869async function setSchedules ( ) {
49- logger . info ( "Starting DockStatAPI" ) ;
50- try {
51- const rawConfigData : unknown [ ] = dbFunctions . getConfig ( ) ;
52- const configData = rawConfigData [ 0 ] ;
53-
54- if (
55- ! configData ||
56- typeof ( configData as config ) . keep_data_for !== "number" ||
57- typeof ( configData as config ) . fetching_interval !== "number"
58- ) {
59- logger . error ( "Invalid configuration data:" , configData ) ;
60- throw new Error ( "Invalid configuration data" ) ;
61- }
62-
63- const { keep_data_for, fetching_interval } = configData as config ;
64-
65- if ( keep_data_for === undefined ) {
66- const errMsg = "keep_data_for is undefined" ;
67- logger . error ( errMsg ) ;
68- throw new Error ( errMsg ) ;
69- }
70-
71- if ( fetching_interval === undefined ) {
72- const errMsg = "fetching_interval is undefined" ;
73- logger . error ( errMsg ) ;
74- throw new Error ( errMsg ) ;
75- }
76-
77- logger . info (
78- `Scheduling: Fetching container statistics every ${ fetching_interval } minutes` ,
79- ) ;
80-
81- logger . info (
82- `Scheduling: Updating host statistics every ${ fetching_interval } minutes` ,
83- ) ;
84-
85- logger . info (
86- `Scheduling: Cleaning up Database every hour and deleting data older then ${ keep_data_for } days` ,
87- ) ;
88-
89- // Schedule container data fetching
90- await initialRun ( "storeContainerData" , storeContainerData ( ) , true ) ;
91- scheduledJob (
92- "storeContainerData" ,
93- storeContainerData ,
94- convertFromMinToMs ( fetching_interval ) ,
95- ) ;
96-
97- // Schedule Host statistics updates
98- await initialRun ( "storeHostData" , storeHostData ( ) , true ) ;
99- scheduledJob (
100- "storeHostData" ,
101- storeHostData ,
102- convertFromMinToMs ( fetching_interval ) ,
103- ) ;
104-
105- // Schedule database cleanup
106- await initialRun (
107- "dbFunctions.deleteOldData" ,
108- dbFunctions . deleteOldData ( keep_data_for ) ,
109- false ,
110- ) ;
111- scheduledJob (
112- "cleanupOldData" ,
113- ( ) => Promise . resolve ( dbFunctions . deleteOldData ( keep_data_for ) ) ,
114- convertFromMinToMs ( 60 ) ,
115- ) ;
116-
117- logger . info ( "Schedules have been set successfully." ) ;
118- } catch ( error ) {
119- logger . error ( "Error setting schedules:" , error ) ;
120- throw new Error ( error as string ) ;
121- }
70+ logger . info ( "Starting DockStatAPI" ) ;
71+ try {
72+ const rawConfigData : unknown [ ] = dbFunctions . getConfig ( ) ;
73+ const configData = rawConfigData [ 0 ] ;
74+
75+ if (
76+ ! configData ||
77+ typeof ( configData as config ) . keep_data_for !== "number" ||
78+ typeof ( configData as config ) . fetching_interval !== "number"
79+ ) {
80+ logger . error ( "Invalid configuration data:" , configData ) ;
81+ throw new Error ( "Invalid configuration data" ) ;
82+ }
83+
84+ const { keep_data_for, fetching_interval } = configData as config ;
85+
86+ if ( keep_data_for === undefined ) {
87+ const errMsg = "keep_data_for is undefined" ;
88+ logger . error ( errMsg ) ;
89+ throw new Error ( errMsg ) ;
90+ }
91+
92+ if ( fetching_interval === undefined ) {
93+ const errMsg = "fetching_interval is undefined" ;
94+ logger . error ( errMsg ) ;
95+ throw new Error ( errMsg ) ;
96+ }
97+
98+ logger . info (
99+ `Scheduling: Fetching container statistics every ${ fetching_interval } minutes` ,
100+ ) ;
101+
102+ logger . info (
103+ `Scheduling: Updating host statistics every ${ fetching_interval } minutes` ,
104+ ) ;
105+
106+ logger . info (
107+ `Scheduling: Cleaning up Database every hour and deleting data older then ${ keep_data_for } days` ,
108+ ) ;
109+ // Schedule container data fetching
110+ await initialRun ( "storeContainerData" , storeContainerData ( ) , true ) ;
111+ cancelFunctions . push (
112+ scheduledJob (
113+ "storeContainerData" ,
114+ storeContainerData ,
115+ convertFromMinToMs ( fetching_interval ) ,
116+ ) ,
117+ ) ;
118+
119+ // Schedule Host statistics updates
120+ await initialRun ( "storeHostData" , storeHostData ( ) , true ) ;
121+ cancelFunctions . push (
122+ scheduledJob (
123+ "storeHostData" ,
124+ storeHostData ,
125+ convertFromMinToMs ( fetching_interval ) ,
126+ ) ,
127+ ) ;
128+
129+ // Schedule database cleanup
130+ await initialRun (
131+ "dbFunctions.deleteOldData" ,
132+ dbFunctions . deleteOldData ( keep_data_for ) ,
133+ false ,
134+ ) ;
135+ cancelFunctions . push (
136+ scheduledJob (
137+ "cleanupOldData" ,
138+ ( ) => Promise . resolve ( dbFunctions . deleteOldData ( keep_data_for ) ) ,
139+ convertFromMinToMs ( 60 ) ,
140+ ) ,
141+ ) ;
142+
143+ logger . info ( "Schedules have been set successfully." ) ;
144+ } catch ( error ) {
145+ logger . error ( "Error setting schedules:" , error ) ;
146+ throw new Error ( error as string ) ;
147+ }
122148}
123149
124- export { setSchedules } ;
150+ export { setSchedules , reloadSchedules } ;
0 commit comments