GSI - Employe Self Service Mobile
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
3.2 KiB

2 months ago
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const pathLib = require("path");
  4. const removeRemote_1 = require("./removeRemote");
  5. const listRemote_1 = require("./listRemote");
  6. const stack_1 = require("../throttler/stack");
  7. function chunkList(ls, chunkSize) {
  8. const chunks = [];
  9. for (let i = 0; i < ls.length; i += chunkSize) {
  10. chunks.push(ls.slice(i, i + chunkSize));
  11. }
  12. return chunks;
  13. }
  14. const INITIAL_DELETE_BATCH_SIZE = 25;
  15. const INITIAL_LIST_NUM_SUB_PATH = 100;
  16. const MAX_LIST_NUM_SUB_PATH = 204800;
  17. class DatabaseRemove {
  18. constructor(instance, path, host, disableTriggers) {
  19. this.path = path;
  20. this.remote = new removeRemote_1.RTDBRemoveRemote(instance, host, disableTriggers);
  21. this.deleteJobStack = new stack_1.Stack({
  22. name: "delete stack",
  23. concurrency: 1,
  24. retries: 3,
  25. });
  26. this.listRemote = new listRemote_1.RTDBListRemote(instance, host);
  27. this.listStack = new stack_1.Stack({
  28. name: "list stack",
  29. concurrency: 1,
  30. retries: 3,
  31. });
  32. }
  33. async execute() {
  34. await this.deletePath(this.path);
  35. }
  36. async deletePath(path) {
  37. if (await this.deleteJobStack.run(() => this.remote.deletePath(path))) {
  38. return true;
  39. }
  40. let listNumSubPath = INITIAL_LIST_NUM_SUB_PATH;
  41. let batchSizeLow = 1;
  42. let batchSizeHigh = MAX_LIST_NUM_SUB_PATH + 1;
  43. let batchSize = INITIAL_DELETE_BATCH_SIZE;
  44. while (true) {
  45. const subPathList = await this.listStack.run(() => this.listRemote.listPath(path, listNumSubPath));
  46. if (subPathList.length === 0) {
  47. return false;
  48. }
  49. const chunks = chunkList(subPathList, batchSize);
  50. let nSmallChunks = 0;
  51. for (const chunk of chunks) {
  52. if (await this.deleteSubPath(path, chunk)) {
  53. nSmallChunks += 1;
  54. }
  55. }
  56. if (nSmallChunks > chunks.length / 2) {
  57. batchSizeLow = batchSize;
  58. batchSize = Math.floor(Math.min(batchSize * 2, (batchSizeHigh + batchSize) / 2));
  59. }
  60. else {
  61. batchSizeHigh = batchSize;
  62. batchSize = Math.floor((batchSizeLow + batchSize) / 2);
  63. }
  64. if (listNumSubPath * 2 <= MAX_LIST_NUM_SUB_PATH) {
  65. listNumSubPath = listNumSubPath * 2;
  66. }
  67. else {
  68. listNumSubPath = Math.floor(MAX_LIST_NUM_SUB_PATH / batchSize) * batchSize;
  69. }
  70. }
  71. }
  72. async deleteSubPath(path, subPaths) {
  73. if (subPaths.length === 0) {
  74. throw new Error("deleteSubPath is called with empty subPaths list");
  75. }
  76. if (subPaths.length === 1) {
  77. return this.deletePath(pathLib.join(path, subPaths[0]));
  78. }
  79. if (await this.deleteJobStack.run(() => this.remote.deleteSubPath(path, subPaths))) {
  80. return true;
  81. }
  82. const mid = Math.floor(subPaths.length / 2);
  83. await this.deleteSubPath(path, subPaths.slice(0, mid));
  84. await this.deleteSubPath(path, subPaths.slice(mid));
  85. return false;
  86. }
  87. }
  88. exports.default = DatabaseRemove;