@@ -415,16 +415,22 @@ class NCLifecycle {
415
415
async get_candidates ( bucket_json , lifecycle_rule , object_sdk ) {
416
416
const candidates = { abort_mpu_candidates : [ ] , delete_candidates : [ ] } ;
417
417
const rule_state = this . lifecycle_run_status . buckets_statuses [ bucket_json . name ] . rules_statuses [ lifecycle_rule . id ] ?. state || { } ;
418
+ const versions_list = undefined ;
418
419
if ( lifecycle_rule . expiration ) {
419
420
candidates . delete_candidates = await this . get_candidates_by_expiration_rule ( lifecycle_rule , bucket_json ,
420
- object_sdk , rule_state ) ;
421
+ object_sdk ) ;
421
422
if ( lifecycle_rule . expiration . days || lifecycle_rule . expiration . expired_object_delete_marker ) {
422
423
const dm_candidates = await this . get_candidates_by_expiration_delete_marker_rule ( lifecycle_rule , bucket_json ) ;
423
424
candidates . delete_candidates = candidates . delete_candidates . concat ( dm_candidates ) ;
424
425
}
425
426
}
426
427
if ( lifecycle_rule . noncurrent_version_expiration ) {
427
- const non_current_candidates = await this . get_candidates_by_noncurrent_version_expiration_rule ( lifecycle_rule , bucket_json ) ;
428
+ const non_current_candidates = await this . get_candidates_by_noncurrent_version_expiration_rule (
429
+ lifecycle_rule ,
430
+ bucket_json ,
431
+ object_sdk ,
432
+ { versions_list}
433
+ ) ;
428
434
candidates . delete_candidates = candidates . delete_candidates . concat ( non_current_candidates ) ;
429
435
}
430
436
if ( lifecycle_rule . abort_incomplete_multipart_upload ) {
@@ -472,12 +478,12 @@ class NCLifecycle {
472
478
* @param {Object } bucket_json
473
479
* @returns {Promise<Object[]> }
474
480
*/
475
- async get_candidates_by_expiration_rule ( lifecycle_rule , bucket_json , object_sdk , rule_state ) {
481
+ async get_candidates_by_expiration_rule ( lifecycle_rule , bucket_json , object_sdk ) {
476
482
const is_gpfs = nb_native ( ) . fs . gpfs ;
477
483
if ( is_gpfs && config . NC_LIFECYCLE_GPFS_ILM_ENABLED ) {
478
484
return this . get_candidates_by_expiration_rule_gpfs ( lifecycle_rule , bucket_json ) ;
479
485
} else {
480
- return this . get_candidates_by_expiration_rule_posix ( lifecycle_rule , bucket_json , object_sdk , rule_state ) ;
486
+ return this . get_candidates_by_expiration_rule_posix ( lifecycle_rule , bucket_json , object_sdk ) ;
481
487
}
482
488
}
483
489
@@ -490,26 +496,41 @@ class NCLifecycle {
490
496
return [ ] ;
491
497
}
492
498
499
+ async load_objects_list ( object_sdk , lifecycle_rule , bucket_json , rule_state ) {
500
+ const objects_list = await object_sdk . list_objects ( {
501
+ bucket : bucket_json . name ,
502
+ prefix : lifecycle_rule . filter ?. prefix ,
503
+ key_marker : rule_state . key_marker ,
504
+ limit : config . NC_LIFECYCLE_LIST_BATCH_SIZE
505
+ } ) ;
506
+ if ( objects_list . is_truncated ) {
507
+ rule_state . key_marker = objects_list . next_marker ;
508
+ rule_state . is_finished = false ;
509
+ } else {
510
+ rule_state . is_finished = true ;
511
+ }
512
+ const bucket_state = this . lifecycle_run_status . buckets_statuses [ bucket_json . name ] . state ;
513
+ bucket_state . num_processed_objects += objects_list . objects . length ;
514
+ return objects_list ;
515
+ }
516
+
493
517
/**
494
518
*
495
519
* @param {* } lifecycle_rule
496
520
* @param {Object } bucket_json
497
521
* @returns {Promise<Object[]> }
498
522
*/
499
- async get_candidates_by_expiration_rule_posix ( lifecycle_rule , bucket_json , object_sdk , rule_state ) {
523
+ async get_candidates_by_expiration_rule_posix ( lifecycle_rule , bucket_json , object_sdk ) {
524
+ const rule_state = this . lifecycle_run_status . buckets_statuses [ bucket_json . name ] . rules_statuses [ lifecycle_rule . id ] . state . expire ;
525
+ if ( rule_state . is_finished ) return [ ] ;
500
526
const expiration = this . _get_expiration_time ( lifecycle_rule . expiration ) ;
501
527
if ( expiration < 0 ) return [ ] ;
502
528
const filter_func = this . _build_lifecycle_filter ( { filter : lifecycle_rule . filter , expiration} ) ;
503
529
504
530
const filtered_objects = [ ] ;
505
531
// TODO list_objects does not accept a filter and works in batch sizes of 1000. should handle batching
506
532
// also should maybe create a helper function or add argument for a filter in list object
507
- const objects_list = await object_sdk . list_objects ( {
508
- bucket : bucket_json . name ,
509
- prefix : lifecycle_rule . filter ?. prefix ,
510
- key_marker : rule_state . key_marker ,
511
- limit : config . NC_LIFECYCLE_LIST_BATCH_SIZE
512
- } ) ;
533
+ const objects_list = await this . load_objects_list ( object_sdk , lifecycle_rule , bucket_json , rule_state ) ;
513
534
objects_list . objects . forEach ( obj => {
514
535
const lifecycle_object = this . _get_lifecycle_object_info_from_list_object_entry ( obj ) ;
515
536
if ( filter_func ( lifecycle_object ) ) {
@@ -518,14 +539,6 @@ class NCLifecycle {
518
539
filtered_objects . push ( candidate ) ;
519
540
}
520
541
} ) ;
521
-
522
- const bucket_state = this . lifecycle_run_status . buckets_statuses [ bucket_json . name ] . state ;
523
- bucket_state . num_processed_objects += objects_list . objects . length ;
524
- if ( objects_list . is_truncated ) {
525
- rule_state . key_marker = objects_list . next_marker ;
526
- } else {
527
- rule_state . is_finished = true ;
528
- }
529
542
return filtered_objects ;
530
543
}
531
544
@@ -544,6 +557,44 @@ class NCLifecycle {
544
557
//////// NON CURRENT VERSION HELPERS ////////
545
558
/////////////////////////////////////////////
546
559
560
+ async load_versions_list ( object_sdk , bucket_json , rule_state ) {
561
+ const list_versions = await object_sdk . list_object_versions ( {
562
+ bucket : bucket_json . name ,
563
+ prefix : rule_state . filter ?. prefix ,
564
+ limit : config . NC_LIFECYCLE_LIST_BATCH_SIZE ,
565
+ key_marker : rule_state . key_marker_versioned ,
566
+ version_id_marker : rule_state . version_id_marker
567
+ } ) ;
568
+ if ( list_versions . is_truncated ) {
569
+ rule_state . is_finished = false ;
570
+ rule_state . key_marker_versioned = list_versions . next_marker ;
571
+ rule_state . version_id_marker = list_versions . next_version_id_marker ;
572
+ } else {
573
+ rule_state . is_finished = true ;
574
+ }
575
+ const bucket_state = this . lifecycle_run_status . buckets_statuses [ bucket_json . name ] . state ;
576
+ bucket_state . num_processed_objects += list_versions . objects . length ;
577
+ return list_versions ;
578
+ }
579
+
580
+ filter_newer_versions ( object_info , newer_noncurrent_state , num_newer_versions ) {
581
+ if ( object_info . is_latest ) {
582
+ newer_noncurrent_state . version_count = 0 ; //latest
583
+ newer_noncurrent_state . current_version = object_info . key ;
584
+ return false ;
585
+ }
586
+ newer_noncurrent_state . version_count += 1 ;
587
+ if ( newer_noncurrent_state . version_count > num_newer_versions ) {
588
+ return true ;
589
+ }
590
+ return false ;
591
+ }
592
+
593
+ filter_noncurrent_days ( object_info , num_non_current_days ) {
594
+ //TODO implement
595
+ return false ;
596
+ }
597
+
547
598
/**
548
599
* get_candidates_by_noncurrent_version_expiration_rule processes the noncurrent version expiration rule
549
600
* TODO:
@@ -553,11 +604,31 @@ class NCLifecycle {
553
604
* @param {Object } bucket_json
554
605
* @returns {Promise<Object[]> }
555
606
*/
556
- async get_candidates_by_noncurrent_version_expiration_rule ( lifecycle_rule , bucket_json ) {
557
- // TODO - implement
558
- return [ ] ;
559
- }
607
+ async get_candidates_by_noncurrent_version_expiration_rule ( lifecycle_rule , bucket_json , object_sdk , { versions_list} ) {
608
+ const rule_state = this . lifecycle_run_status . buckets_statuses [ bucket_json . name ] . rules_statuses [ lifecycle_rule . id ] . state . noncurrent ;
609
+ if ( rule_state . is_finished ) return [ ] ;
560
610
611
+ if ( ! versions_list ) {
612
+ versions_list = await this . load_versions_list ( object_sdk , bucket_json , rule_state ) ;
613
+ }
614
+
615
+ const filter_func = this . _build_lifecycle_filter ( { filter : lifecycle_rule . filter , expiration : 0 } ) ;
616
+ const num_newer_versions = lifecycle_rule . noncurrent_version_expiration . newer_noncurrent_versions ;
617
+ const num_non_current_days = lifecycle_rule . noncurrent_version_expiration . noncurrent_days ;
618
+ const delete_candidates = [ ] ;
619
+
620
+ for ( const entry of versions_list . objects ) {
621
+ const lifecycle_info = this . _get_lifecycle_object_info_from_list_object_entry ( entry ) ;
622
+ if ( ( num_newer_versions !== undefined && this . filter_newer_versions ( entry , rule_state , num_newer_versions ) ) ||
623
+ ( num_non_current_days !== undefined && this . filter_noncurrent_days ( entry , num_non_current_days ) ) ) {
624
+ if ( filter_func ( lifecycle_info ) ) {
625
+ delete_candidates . push ( { key : entry . key , version_id : entry . version_id } ) ;
626
+ }
627
+ }
628
+ }
629
+
630
+ return delete_candidates ;
631
+ }
561
632
////////////////////////////////////
562
633
///////// ABORT MPU HELPERS ////////
563
634
////////////////////////////////////
@@ -733,6 +804,11 @@ class NCLifecycle {
733
804
this . init_bucket_status ( bucket_name ) ;
734
805
}
735
806
}
807
+ if ( op_times . end_time ) {
808
+ if ( op_name === TIMED_OPS . PROCESS_RULE ) {
809
+ this . update_rule_status_is_finished ( bucket_name , rule_id ) ;
810
+ }
811
+ }
736
812
this . _update_times_on_status ( { op_name, op_times, bucket_name, rule_id } ) ;
737
813
this . _update_error_on_status ( { error, bucket_name, rule_id } ) ;
738
814
if ( bucket_name && rule_id ) {
@@ -879,12 +955,23 @@ class NCLifecycle {
879
955
*/
880
956
init_rule_status ( bucket_name , rule_id ) {
881
957
this . lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] ??= { } ;
882
- this . lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . state ??= { } ;
958
+ this . lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . state ??= { expire : { } , noncurrent : { } } ;
883
959
this . lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . rule_process_times = { } ;
884
960
this . lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . rule_stats = { } ;
885
961
return this . lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] ;
886
962
}
887
963
964
+ /**
965
+ * updates the rule state if all actions finished
966
+ * @param {string } bucket_name
967
+ * @param {string } rule_id
968
+ */
969
+ update_rule_status_is_finished ( bucket_name , rule_id ) {
970
+ const rule_state = this . lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . state ;
971
+ rule_state . is_finished = ( rule_state . expire . is_finished === undefined || rule_state . expire . is_finished === true ) &&
972
+ ( rule_state . noncurrent . is_finished === undefined || rule_state . noncurrent . is_finished === true ) ;
973
+ }
974
+
888
975
/**
889
976
*
890
977
* @param {Object[] } buckets
@@ -908,7 +995,7 @@ class NCLifecycle {
908
995
}
909
996
}
910
997
}
911
- }
998
+ }
912
999
}
913
1000
914
1001
//////////////////
0 commit comments