Skip to content

Commit 7a18cdb

Browse files
authored
Merge pull request #8999 from romayalon/romy-adjust-gpfs-flow-to-key-state-changes
NC | Lifecycle | Adjust expire/noncurrent state properties to GPFS flow + fix of 2 small bugs
2 parents 947eb7f + b66acc0 commit 7a18cdb

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed

src/manage_nsfs/nc_lifecycle.js

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ const TIMED_OPS = Object.freeze({
4747
DELETE_MULTIPLE_OBJECTS: 'delete_multiple_objects'
4848
});
4949

50+
/**
51+
* @typedef {{
52+
* is_finished?: Boolean | Undefined,
53+
* expire?: { is_finished?: Boolean | Undefined, key_marker?: String | Undefined, candidates_file_offset?: number | undefined}
54+
* noncurrent?: { is_finished?: Boolean | Undefined, key_marker_versioned?: String | Undefined, version_id_marker?: String | Undefined }
55+
* }} RuleState
56+
*/
5057

5158
class NCLifecycle {
5259
constructor(config_fs, options = {}) {
@@ -265,7 +272,7 @@ class NCLifecycle {
265272
if (candidates.delete_candidates?.length > 0) {
266273
const expiration = lifecycle_rule.expiration ? this._get_expiration_time(lifecycle_rule.expiration) : 0;
267274
const filter_func = this._build_lifecycle_filter({filter: lifecycle_rule.filter, expiration});
268-
275+
dbg.log0('process_rule: calling delete_multiple_objects, num of objects to be deleted', candidates.delete_candidates.length);
269276
const delete_res = await this._call_op_and_update_status({
270277
bucket_name,
271278
rule_id,
@@ -282,6 +289,7 @@ class NCLifecycle {
282289
}
283290

284291
if (candidates.abort_mpu_candidates?.length > 0) {
292+
dbg.log0('process_rule: calling delete_multiple_objects, num of mpu to be aborted', candidates.delete_candidates.length);
285293
await this._call_op_and_update_status({
286294
bucket_name,
287295
rule_id,
@@ -465,7 +473,7 @@ class NCLifecycle {
465473
* @returns {Promise<Object[]>}
466474
*/
467475
async get_candidates_by_expiration_rule_posix(lifecycle_rule, bucket_json, object_sdk) {
468-
const rule_state = this.lifecycle_run_status.buckets_statuses[bucket_json.name].rules_statuses[lifecycle_rule.id].state.expire;
476+
const rule_state = this._get_rule_state(bucket_json, lifecycle_rule).expire;
469477
if (rule_state.is_finished) return [];
470478
const expiration = this._get_expiration_time(lifecycle_rule.expiration);
471479
if (expiration < 0) return [];
@@ -520,7 +528,7 @@ class NCLifecycle {
520528
* @returns {Promise<Object[]>}
521529
*/
522530
async get_candidates_by_expiration_delete_marker_rule(lifecycle_rule, bucket_json, object_sdk, {versions_list}) {
523-
const rule_state = this.lifecycle_run_status.buckets_statuses[bucket_json.name].rules_statuses[lifecycle_rule.id].state.noncurrent;
531+
const rule_state = this._get_rule_state(bucket_json, lifecycle_rule).noncurrent;
524532
if (rule_state.is_finished) return [];
525533
if (!versions_list) {
526534
versions_list = await this.load_versions_list(object_sdk, lifecycle_rule, bucket_json, rule_state);
@@ -619,7 +627,7 @@ class NCLifecycle {
619627
* @returns {Promise<Object[]>}
620628
*/
621629
async get_candidates_by_noncurrent_version_expiration_rule(lifecycle_rule, bucket_json, object_sdk, {versions_list}) {
622-
const rule_state = this.lifecycle_run_status.buckets_statuses[bucket_json.name].rules_statuses[lifecycle_rule.id].state.noncurrent;
630+
const rule_state = this._get_rule_state(bucket_json, lifecycle_rule).noncurrent;
623631
if (rule_state.is_finished) return [];
624632

625633
if (!versions_list) {
@@ -965,19 +973,22 @@ class NCLifecycle {
965973
*/
966974
init_rule_status(bucket_name, rule_id) {
967975
this.lifecycle_run_status.buckets_statuses[bucket_name].rules_statuses[rule_id] ??= {};
968-
this.lifecycle_run_status.buckets_statuses[bucket_name].rules_statuses[rule_id].state ??= {expire: {}, noncurrent: {}};
976+
this.lifecycle_run_status.buckets_statuses[bucket_name].rules_statuses[rule_id].state ??= { expire: {}, noncurrent: {} };
969977
this.lifecycle_run_status.buckets_statuses[bucket_name].rules_statuses[rule_id].rule_process_times = {};
970978
this.lifecycle_run_status.buckets_statuses[bucket_name].rules_statuses[rule_id].rule_stats ??= {};
971979
return this.lifecycle_run_status.buckets_statuses[bucket_name].rules_statuses[rule_id];
972980
}
973981

974982
/**
975-
* updates the rule state if all actions finished
983+
* update_rule_status_is_finished updates the rule state if all actions finished
984+
* notice that expire and noncurrent properties are initiated in init_rule_status()
985+
* therefore they should not be undefined
976986
* @param {string} bucket_name
977987
* @param {string} rule_id
988+
* @returns {Void}
978989
*/
979990
update_rule_status_is_finished(bucket_name, rule_id) {
980-
const rule_state = this.lifecycle_run_status.buckets_statuses[bucket_name].rules_statuses[rule_id].state;
991+
const rule_state = this._get_rule_state({ name: bucket_name }, { id: rule_id });
981992
rule_state.is_finished = (rule_state.expire.is_finished === undefined || rule_state.expire.is_finished === true) &&
982993
(rule_state.noncurrent.is_finished === undefined || rule_state.noncurrent.is_finished === true);
983994
}
@@ -1011,18 +1022,20 @@ class NCLifecycle {
10111022
* _set_rule_state sets the current rule state on the lifecycle run status
10121023
* @param {Object} bucket_json
10131024
* @param {*} lifecycle_rule
1014-
* @param {{is_finished?: Boolean | Undefined, candidates_file_offset?: number | undefined}} rule_state
1025+
* @param {RuleState} rule_state
10151026
* @returns {Void}
10161027
*/
10171028
_set_rule_state(bucket_json, lifecycle_rule, rule_state) {
1018-
this.lifecycle_run_status.buckets_statuses[bucket_json.name].rules_statuses[lifecycle_rule.id].state = rule_state;
1029+
const existing_state = this._get_rule_state(bucket_json, lifecycle_rule);
1030+
const new_state = { ...existing_state, ...rule_state };
1031+
this.lifecycle_run_status.buckets_statuses[bucket_json.name].rules_statuses[lifecycle_rule.id].state = new_state;
10191032
}
10201033

10211034
/**
10221035
* _get_rule_state gets the current rule state on the lifecycle run status
10231036
* @param {Object} bucket_json
10241037
* @param {*} lifecycle_rule
1025-
* @returns {{is_finished?: Boolean | Undefined, candidates_file_offset?: number | undefined}} rule_state
1038+
* @returns {RuleState}
10261039
*/
10271040
_get_rule_state(bucket_json, lifecycle_rule) {
10281041
return this.lifecycle_run_status.buckets_statuses[bucket_json.name].rules_statuses[lifecycle_rule.id].state;
@@ -1164,6 +1177,7 @@ class NCLifecycle {
11641177
for (const bucket_name of bucket_names) {
11651178
const bucket_json = await this.config_fs.get_bucket_by_name(bucket_name, config_fs_options);
11661179
const bucket_mount_point = this.find_mount_point_by_bucket_path(mount_point_to_policy_map, bucket_json.path);
1180+
if (!bucket_json.lifecycle_configuration_rules?.length) continue;
11671181
for (const lifecycle_rule of bucket_json.lifecycle_configuration_rules) {
11681182
// currently we support expiration (current version) only
11691183
if (lifecycle_rule.expiration) {
@@ -1377,22 +1391,28 @@ class NCLifecycle {
13771391
* 1.2.2. parse the key from the candidate line
13781392
* 1.2.3. push the key to the candidates array
13791393
* 2. if candidates file does not exist, we return without error because it's valid that no candidates found
1394+
* GAP - when supporting noncurrent rule, we should update the state type to noncurrent based on the candidates file path
13801395
* @param {Object} bucket_json
13811396
* @param {*} lifecycle_rule
13821397
* @param {String} rule_candidates_path
13831398
* @returns {Promise<Object[]>} parsed_candidates_array
13841399
*/
13851400
async parse_candidates_from_gpfs_ilm_policy(bucket_json, lifecycle_rule, rule_candidates_path) {
13861401
let reader;
1402+
const state_type = 'expire';
1403+
const rule_state = this._get_rule_state(bucket_json, lifecycle_rule)?.[state_type];
1404+
dbg.log2(`parse_candidates_from_gpfs_ilm_policy rule_state=${rule_state} state_type=${state_type}, currently on gpfs ilm flow - we support only expiration rule`);
1405+
if (rule_state?.is_finished) return [];
1406+
const finished_state = { [state_type]: { is_finished: true, candidates_file_offset: undefined } };
1407+
13871408
try {
1388-
const rule_state = this._get_rule_state(bucket_json, lifecycle_rule);
13891409
dbg.log2(`parse_candidates_from_gpfs_ilm_policy bucket_name=${bucket_json.name}, rule_id ${lifecycle_rule.id}, existing rule_state=${util.inspect(rule_state)}`);
1390-
13911410
const parsed_candidates_array = [];
13921411
reader = new NewlineReader(this.non_gpfs_fs_context, rule_candidates_path, { lock: 'SHARED', read_file_offset: rule_state?.candidates_file_offset || 0 });
1412+
13931413
const [count, is_finished] = await reader.forEachFilePathEntry(async entry => {
13941414
if (parsed_candidates_array.length >= config.NC_LIFECYCLE_LIST_BATCH_SIZE) return false;
1395-
const cur_rule_state = { is_finished: false, candidates_file_offset: reader.next_line_file_offset };
1415+
const cur_rule_state = { [state_type]: { is_finished: false, candidates_file_offset: reader.next_line_file_offset } };
13961416
this._set_rule_state(bucket_json, lifecycle_rule, cur_rule_state);
13971417
const key = this._parse_key_from_line(entry, bucket_json);
13981418
// TODO - need to add etag, size, version_id
@@ -1402,14 +1422,14 @@ class NCLifecycle {
14021422
});
14031423

14041424
if (is_finished) {
1405-
this._set_rule_state(bucket_json, lifecycle_rule, { is_finished: true, candidates_file_offset: undefined });
1425+
this._set_rule_state(bucket_json, lifecycle_rule, finished_state);
14061426
}
14071427
dbg.log2(`parse_candidates_from_gpfs_ilm_policy: parsed_candidates_array ${util.inspect(parsed_candidates_array)}, rule_state=${util.inspect(rule_state)}, count=${count} is_finished=${is_finished}`);
14081428
return parsed_candidates_array;
14091429
} catch (err) {
14101430
if (err.code === 'ENOENT') {
14111431
dbg.log2(`parse_candidates_from_gpfs_ilm_policy ilm_candidates_file_exists does not exist, no candidates to delete`);
1412-
this._set_rule_state(bucket_json, lifecycle_rule, { is_finished: true, candidates_file_offset: undefined });
1432+
this._set_rule_state(bucket_json, lifecycle_rule, finished_state);
14131433
return;
14141434
}
14151435
dbg.error('parse_candidates_from_gpfs_ilm_policy: error', err);

0 commit comments

Comments
 (0)