@@ -8,22 +8,24 @@ const nb_native = require('../util/nb_native');
8
8
const { GlacierBackend } = require ( '../sdk/nsfs_glacier_backend/backend' ) ;
9
9
const { getGlacierBackend } = require ( '../sdk/nsfs_glacier_backend/helper' ) ;
10
10
const native_fs_utils = require ( '../util/native_fs_utils' ) ;
11
+ const { is_desired_time, record_current_time } = require ( './manage_nsfs_cli_utils' ) ;
11
12
12
13
const CLUSTER_LOCK = 'cluster.lock' ;
13
14
const SCAN_LOCK = 'scan.lock' ;
14
15
15
16
async function process_migrations ( ) {
16
17
const fs_context = native_fs_utils . get_process_fs_context ( ) ;
17
-
18
- await lock_and_run ( fs_context , CLUSTER_LOCK , async ( ) => {
18
+ const lock_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , CLUSTER_LOCK ) ;
19
+ await native_fs_utils . lock_and_run ( fs_context , lock_path , async ( ) => {
19
20
const backend = getGlacierBackend ( ) ;
20
21
21
22
if (
22
23
await backend . low_free_space ( ) ||
23
24
await time_exceeded ( fs_context , config . NSFS_GLACIER_MIGRATE_INTERVAL , GlacierBackend . MIGRATE_TIMESTAMP_FILE )
24
25
) {
25
26
await run_glacier_migrations ( fs_context , backend ) ;
26
- await record_current_time ( fs_context , GlacierBackend . MIGRATE_TIMESTAMP_FILE ) ;
27
+ const timestamp_file_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , GlacierBackend . MIGRATE_TIMESTAMP_FILE ) ;
28
+ await record_current_time ( fs_context , timestamp_file_path ) ;
27
29
}
28
30
} ) ;
29
31
}
@@ -40,8 +42,8 @@ async function run_glacier_migrations(fs_context, backend) {
40
42
41
43
async function process_restores ( ) {
42
44
const fs_context = native_fs_utils . get_process_fs_context ( ) ;
43
-
44
- await lock_and_run ( fs_context , CLUSTER_LOCK , async ( ) => {
45
+ const lock_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , CLUSTER_LOCK ) ;
46
+ await native_fs_utils . lock_and_run ( fs_context , lock_path , async ( ) => {
45
47
const backend = getGlacierBackend ( ) ;
46
48
47
49
if (
@@ -51,7 +53,8 @@ async function process_restores() {
51
53
52
54
53
55
await run_glacier_restore ( fs_context , backend ) ;
54
- await record_current_time ( fs_context , GlacierBackend . RESTORE_TIMESTAMP_FILE ) ;
56
+ const timestamp_file_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , GlacierBackend . RESTORE_TIMESTAMP_FILE ) ;
57
+ await record_current_time ( fs_context , timestamp_file_path ) ;
55
58
} ) ;
56
59
}
57
60
@@ -67,68 +70,27 @@ async function run_glacier_restore(fs_context, backend) {
67
70
68
71
async function process_expiry ( ) {
69
72
const fs_context = native_fs_utils . get_process_fs_context ( ) ;
70
-
71
- await lock_and_run ( fs_context , SCAN_LOCK , async ( ) => {
73
+ const lock_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , SCAN_LOCK ) ;
74
+ await native_fs_utils . lock_and_run ( fs_context , lock_path , async ( ) => {
72
75
const backend = getGlacierBackend ( ) ;
76
+ const timestamp_file_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , GlacierBackend . EXPIRY_TIMESTAMP_FILE ) ;
73
77
if (
74
78
await backend . low_free_space ( ) ||
75
79
await is_desired_time (
76
- fs_context ,
77
- new Date ( ) ,
78
- config . NSFS_GLACIER_EXPIRY_RUN_TIME ,
79
- config . NSFS_GLACIER_EXPIRY_RUN_DELAY_LIMIT_MINS ,
80
- GlacierBackend . EXPIRY_TIMESTAMP_FILE ,
80
+ fs_context ,
81
+ new Date ( ) ,
82
+ config . NSFS_GLACIER_EXPIRY_RUN_TIME ,
83
+ config . NSFS_GLACIER_EXPIRY_RUN_DELAY_LIMIT_MINS ,
84
+ timestamp_file_path ,
85
+ config . NSFS_GLACIER_EXPIRY_TZ
81
86
)
82
87
) {
83
88
await backend . expiry ( fs_context ) ;
84
- await record_current_time ( fs_context , GlacierBackend . EXPIRY_TIMESTAMP_FILE ) ;
89
+ await record_current_time ( fs_context , timestamp_file_path ) ;
85
90
}
86
91
} ) ;
87
92
}
88
93
89
- /**
90
- * is_desired_time returns true if the given time matches with
91
- * the desired time or if
92
- * @param {nb.NativeFSContext } fs_context
93
- * @param {Date } current
94
- * @param {string } desire time in format 'hh:mm'
95
- * @param {number } delay_limit_mins
96
- * @param {string } timestamp_file
97
- * @returns {Promise<boolean> }
98
- */
99
- async function is_desired_time ( fs_context , current , desire , delay_limit_mins , timestamp_file ) {
100
- const [ desired_hour , desired_min ] = desire . split ( ':' ) . map ( Number ) ;
101
- if (
102
- isNaN ( desired_hour ) ||
103
- isNaN ( desired_min ) ||
104
- ( desired_hour < 0 || desired_hour >= 24 ) ||
105
- ( desired_min < 0 || desired_min >= 60 )
106
- ) {
107
- throw new Error ( 'invalid desired_time - must be hh:mm' ) ;
108
- }
109
-
110
- const min_time = get_tz_date ( desired_hour , desired_min , 0 , config . NSFS_GLACIER_EXPIRY_TZ ) ;
111
- const max_time = get_tz_date ( desired_hour , desired_min + delay_limit_mins , 0 , config . NSFS_GLACIER_EXPIRY_TZ ) ;
112
-
113
- if ( current >= min_time && current <= max_time ) {
114
- try {
115
- const { data } = await nb_native ( ) . fs . readFile ( fs_context , path . join ( config . NSFS_GLACIER_LOGS_DIR , timestamp_file ) ) ;
116
- const lastrun = new Date ( data . toString ( ) ) ;
117
-
118
- // Last run should NOT be in this window
119
- if ( lastrun >= min_time && lastrun <= max_time ) return false ;
120
- } catch ( error ) {
121
- if ( error . code === 'ENOENT' ) return true ;
122
- console . error ( 'failed to read last run timestamp:' , error , 'timestamp_file:' , timestamp_file ) ;
123
-
124
- throw error ;
125
- }
126
-
127
- return true ;
128
- }
129
-
130
- return false ;
131
- }
132
94
133
95
/**
134
96
* time_exceeded returns true if the time between last run recorded in the given
@@ -154,20 +116,6 @@ async function time_exceeded(fs_context, interval, timestamp_file) {
154
116
return false ;
155
117
}
156
118
157
- /**
158
- * record_current_time stores the current timestamp in ISO format into
159
- * the given timestamp file
160
- * @param {nb.NativeFSContext } fs_context
161
- * @param {string } timestamp_file
162
- */
163
- async function record_current_time ( fs_context , timestamp_file ) {
164
- await nb_native ( ) . fs . writeFile (
165
- fs_context ,
166
- path . join ( config . NSFS_GLACIER_LOGS_DIR , timestamp_file ) ,
167
- Buffer . from ( new Date ( ) . toISOString ( ) ) ,
168
- ) ;
169
- }
170
-
171
119
/**
172
120
* run_glacier_operations takes a log_namespace and a callback and executes the
173
121
* callback on each log file in that namespace. It will also generate a failure
@@ -187,49 +135,6 @@ async function run_glacier_operation(fs_context, log_namespace, cb) {
187
135
}
188
136
}
189
137
190
- /**
191
- * @param {number } hours
192
- * @param {number } mins
193
- * @param {number } secs
194
- * @param {'UTC' | 'LOCAL' } tz
195
- * @returns {Date }
196
- */
197
- function get_tz_date ( hours , mins , secs , tz ) {
198
- const date = new Date ( ) ;
199
-
200
- if ( tz === 'UTC' ) {
201
- date . setUTCHours ( hours ) ;
202
- date . setUTCMinutes ( hours ) ;
203
- date . setUTCSeconds ( secs ) ;
204
- date . setUTCMilliseconds ( 0 ) ;
205
- } else {
206
- date . setHours ( hours ) ;
207
- date . setMinutes ( mins ) ;
208
- date . setSeconds ( secs ) ;
209
- date . setMilliseconds ( 0 ) ;
210
- }
211
-
212
- return date ;
213
- }
214
-
215
- /**
216
- * lock_and_run acquires a flock and calls the given callback after
217
- * acquiring the lock
218
- * @param {nb.NativeFSContext } fs_context
219
- * @param {string } lockfilename
220
- * @param {Function } cb
221
- */
222
- async function lock_and_run ( fs_context , lockfilename , cb ) {
223
- const lockfd = await nb_native ( ) . fs . open ( fs_context , path . join ( config . NSFS_GLACIER_LOGS_DIR , lockfilename ) , 'w' ) ;
224
-
225
- try {
226
- await lockfd . fcntllock ( fs_context , 'EXCLUSIVE' ) ;
227
- await cb ( ) ;
228
- } finally {
229
- await lockfd . close ( fs_context ) ;
230
- }
231
- }
232
-
233
138
exports . process_migrations = process_migrations ;
234
139
exports . process_restores = process_restores ;
235
140
exports . process_expiry = process_expiry ;
0 commit comments