@@ -7,14 +7,16 @@ const config = require('../../config');
7
7
const nb_native = require ( '../util/nb_native' ) ;
8
8
const { Glacier } = require ( '../sdk/glacier' ) ;
9
9
const native_fs_utils = require ( '../util/native_fs_utils' ) ;
10
+ const { is_desired_time, record_current_time } = require ( './manage_nsfs_cli_utils' ) ;
10
11
11
12
const CLUSTER_LOCK = 'cluster.lock' ;
12
13
const SCAN_LOCK = 'scan.lock' ;
13
14
14
15
async function process_migrations ( ) {
15
16
const fs_context = native_fs_utils . get_process_fs_context ( ) ;
16
17
17
- 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 ( ) => {
18
20
const backend = Glacier . getBackend ( ) ;
19
21
20
22
if (
@@ -23,7 +25,8 @@ async function process_migrations() {
23
25
await migrate_log_exceeds_threshold ( )
24
26
) {
25
27
await run_glacier_migrations ( fs_context , backend ) ;
26
- await record_current_time ( fs_context , Glacier . MIGRATE_TIMESTAMP_FILE ) ;
28
+ const timestamp_file_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , Glacier . MIGRATE_TIMESTAMP_FILE ) ;
29
+ await record_current_time ( fs_context , timestamp_file_path ) ;
27
30
}
28
31
} ) ;
29
32
}
@@ -41,7 +44,8 @@ async function run_glacier_migrations(fs_context, backend) {
41
44
async function process_restores ( ) {
42
45
const fs_context = native_fs_utils . get_process_fs_context ( ) ;
43
46
44
- await lock_and_run ( fs_context , CLUSTER_LOCK , async ( ) => {
47
+ const lock_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , CLUSTER_LOCK ) ;
48
+ await native_fs_utils . lock_and_run ( fs_context , lock_path , async ( ) => {
45
49
const backend = Glacier . getBackend ( ) ;
46
50
47
51
if (
@@ -51,7 +55,8 @@ async function process_restores() {
51
55
52
56
53
57
await run_glacier_restore ( fs_context , backend ) ;
54
- await record_current_time ( fs_context , Glacier . RESTORE_TIMESTAMP_FILE ) ;
58
+ const timestamp_file_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , Glacier . RESTORE_TIMESTAMP_FILE ) ;
59
+ await record_current_time ( fs_context , timestamp_file_path ) ;
55
60
} ) ;
56
61
}
57
62
@@ -67,68 +72,27 @@ async function run_glacier_restore(fs_context, backend) {
67
72
68
73
async function process_expiry ( ) {
69
74
const fs_context = native_fs_utils . get_process_fs_context ( ) ;
70
-
71
- await lock_and_run ( fs_context , SCAN_LOCK , async ( ) => {
75
+ const lock_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , SCAN_LOCK ) ;
76
+ await native_fs_utils . lock_and_run ( fs_context , lock_path , async ( ) => {
72
77
const backend = Glacier . getBackend ( ) ;
78
+ const timestamp_file_path = path . join ( config . NSFS_GLACIER_LOGS_DIR , Glacier . EXPIRY_TIMESTAMP_FILE ) ;
73
79
if (
74
80
await backend . low_free_space ( ) ||
75
81
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
- Glacier . EXPIRY_TIMESTAMP_FILE ,
82
+ fs_context ,
83
+ new Date ( ) ,
84
+ config . NSFS_GLACIER_EXPIRY_RUN_TIME ,
85
+ config . NSFS_GLACIER_EXPIRY_RUN_DELAY_LIMIT_MINS ,
86
+ timestamp_file_path ,
87
+ config . NSFS_GLACIER_EXPIRY_TZ
81
88
)
82
89
) {
83
90
await backend . expiry ( fs_context ) ;
84
- await record_current_time ( fs_context , Glacier . EXPIRY_TIMESTAMP_FILE ) ;
91
+ await record_current_time ( fs_context , timestamp_file_path ) ;
85
92
}
86
93
} ) ;
87
94
}
88
95
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
96
133
97
/**
134
98
* time_exceeded returns true if the time between last run recorded in the given
@@ -154,20 +118,6 @@ async function time_exceeded(fs_context, interval, timestamp_file) {
154
118
return false ;
155
119
}
156
120
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
121
/**
172
122
* migrate_log_exceeds_threshold returns true if the underlying backend
173
123
* decides that the migrate log size has exceeded the given size threshold.
@@ -210,49 +160,6 @@ async function run_glacier_operation(fs_context, log_namespace, cb) {
210
160
}
211
161
}
212
162
213
- /**
214
- * @param {number } hours
215
- * @param {number } mins
216
- * @param {number } secs
217
- * @param {'UTC' | 'LOCAL' } tz
218
- * @returns {Date }
219
- */
220
- function get_tz_date ( hours , mins , secs , tz ) {
221
- const date = new Date ( ) ;
222
-
223
- if ( tz === 'UTC' ) {
224
- date . setUTCHours ( hours ) ;
225
- date . setUTCMinutes ( hours ) ;
226
- date . setUTCSeconds ( secs ) ;
227
- date . setUTCMilliseconds ( 0 ) ;
228
- } else {
229
- date . setHours ( hours ) ;
230
- date . setMinutes ( mins ) ;
231
- date . setSeconds ( secs ) ;
232
- date . setMilliseconds ( 0 ) ;
233
- }
234
-
235
- return date ;
236
- }
237
-
238
- /**
239
- * lock_and_run acquires a flock and calls the given callback after
240
- * acquiring the lock
241
- * @param {nb.NativeFSContext } fs_context
242
- * @param {string } lockfilename
243
- * @param {Function } cb
244
- */
245
- async function lock_and_run ( fs_context , lockfilename , cb ) {
246
- const lockfd = await nb_native ( ) . fs . open ( fs_context , path . join ( config . NSFS_GLACIER_LOGS_DIR , lockfilename ) , 'w' ) ;
247
-
248
- try {
249
- await lockfd . fcntllock ( fs_context , 'EXCLUSIVE' ) ;
250
- await cb ( ) ;
251
- } finally {
252
- await lockfd . close ( fs_context ) ;
253
- }
254
- }
255
-
256
163
/**
257
164
* prepare_galcier_fs_context returns a shallow copy of given
258
165
* fs_context with backend set to 'GPFS'.
0 commit comments