@bitblit/ratchet-aws 4.0.80-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/dist/cjs/batch/aws-batch-background-processor.js +44 -0
  2. package/dist/cjs/batch/aws-batch-ratchet.js +55 -0
  3. package/dist/cjs/build/ratchet-aws-info.js +18 -0
  4. package/dist/cjs/cache/dynamo-db-storage-provider.js +111 -0
  5. package/dist/cjs/cache/s3-storage-provider.js +44 -0
  6. package/dist/cjs/cache/simple-cache-object-wrapper.js +2 -0
  7. package/dist/cjs/cache/simple-cache-read-options.js +2 -0
  8. package/dist/cjs/cache/simple-cache-storage-provider.js +2 -0
  9. package/dist/cjs/cache/simple-cache.js +66 -0
  10. package/dist/cjs/cloudwatch/cloud-watch-log-group-ratchet.js +73 -0
  11. package/dist/cjs/cloudwatch/cloud-watch-logs-ratchet.js +173 -0
  12. package/dist/cjs/cloudwatch/cloud-watch-metrics-ratchet.js +57 -0
  13. package/dist/cjs/daemon/daemon-like.js +2 -0
  14. package/dist/cjs/daemon/daemon-process-create-options.js +2 -0
  15. package/dist/cjs/daemon/daemon-process-state-public-token.js +2 -0
  16. package/dist/cjs/daemon/daemon-process-state.js +2 -0
  17. package/dist/cjs/daemon/daemon-util.js +152 -0
  18. package/dist/cjs/daemon/daemon.js +126 -0
  19. package/dist/cjs/dao/prototype-dao-config.js +2 -0
  20. package/dist/cjs/dao/prototype-dao-db.js +2 -0
  21. package/dist/cjs/dao/prototype-dao-provider.js +2 -0
  22. package/dist/cjs/dao/prototype-dao.js +88 -0
  23. package/dist/cjs/dao/s3-prototype-dao-provider.js +28 -0
  24. package/dist/cjs/dao/s3-simple-dao.js +78 -0
  25. package/dist/cjs/dao/simple-dao-item.js +2 -0
  26. package/dist/cjs/dynamodb/dynamo-ratchet-like.js +2 -0
  27. package/dist/cjs/dynamodb/dynamo-ratchet.js +667 -0
  28. package/dist/cjs/dynamodb/dynamo-table-ratchet.js +91 -0
  29. package/dist/cjs/dynamodb/hash-spreader.js +62 -0
  30. package/dist/cjs/ec2/ec2-ratchet.js +107 -0
  31. package/dist/cjs/environment/cascade-environment-service-provider.js +27 -0
  32. package/dist/cjs/environment/env-var-environment-service-provider.js +33 -0
  33. package/dist/cjs/environment/environment-service-config.js +2 -0
  34. package/dist/cjs/environment/environment-service-provider.js +2 -0
  35. package/dist/cjs/environment/environment-service.js +52 -0
  36. package/dist/cjs/environment/fixed-environment-service-provider.js +24 -0
  37. package/dist/cjs/environment/s3-environment-service-provider.js +29 -0
  38. package/dist/cjs/environment/ssm-environment-service-provider.js +61 -0
  39. package/dist/cjs/expiring-code/dynamo-expiring-code-provider.js +26 -0
  40. package/dist/cjs/expiring-code/expiring-code-params.js +2 -0
  41. package/dist/cjs/expiring-code/expiring-code-provider.js +2 -0
  42. package/dist/cjs/expiring-code/expiring-code-ratchet.js +37 -0
  43. package/dist/cjs/expiring-code/expiring-code.js +2 -0
  44. package/dist/cjs/expiring-code/s3-expiring-code-provider.js +49 -0
  45. package/dist/cjs/iam/aws-credentials-ratchet.js +21 -0
  46. package/dist/cjs/index.js +81 -0
  47. package/dist/cjs/lambda/lambda-event-detector.js +42 -0
  48. package/dist/cjs/lambda/lambda-event-type-guards.js +28 -0
  49. package/dist/cjs/model/cloud-watch-metrics-minute-level-dynamo-count-request.js +2 -0
  50. package/dist/cjs/model/cloud-watch-metrics-unit.js +33 -0
  51. package/dist/cjs/model/dynamo/doc-put-item-command-input.js +2 -0
  52. package/dist/cjs/model/dynamo/doc-query-command-input.js +2 -0
  53. package/dist/cjs/model/dynamo/doc-scan-command-input.js +2 -0
  54. package/dist/cjs/model/dynamo/doc-update-item-command-input.js +2 -0
  55. package/dist/cjs/model/dynamo-count-result.js +2 -0
  56. package/dist/cjs/route53/route-53-ratchet.js +57 -0
  57. package/dist/cjs/runtime-parameter/cached-stored-runtime-parameter.js +2 -0
  58. package/dist/cjs/runtime-parameter/dynamo-runtime-parameter-provider.js +38 -0
  59. package/dist/cjs/runtime-parameter/global-variable-override-runtime-parameter-provider.js +54 -0
  60. package/dist/cjs/runtime-parameter/memory-runtime-parameter-provider.js +30 -0
  61. package/dist/cjs/runtime-parameter/runtime-parameter-provider.js +2 -0
  62. package/dist/cjs/runtime-parameter/runtime-parameter-ratchet.js +74 -0
  63. package/dist/cjs/runtime-parameter/stored-runtime-parameter.js +2 -0
  64. package/dist/cjs/s3/s3-cache-ratchet.js +332 -0
  65. package/dist/cjs/s3/s3-cache-to-local-disk-ratchet.js +105 -0
  66. package/dist/cjs/s3/s3-location-sync-ratchet.js +142 -0
  67. package/dist/cjs/s3/s3-ratchet.js +26 -0
  68. package/dist/cjs/ses/email-attachment.js +2 -0
  69. package/dist/cjs/ses/mailer-config.js +2 -0
  70. package/dist/cjs/ses/mailer-like.js +2 -0
  71. package/dist/cjs/ses/mailer.js +208 -0
  72. package/dist/cjs/ses/ratchet-template-renderer.js +2 -0
  73. package/dist/cjs/ses/ready-to-send-email.js +2 -0
  74. package/dist/cjs/ses/remote-handlebars-template-renderer.js +79 -0
  75. package/dist/cjs/ses/resolved-ready-to-send-email.js +2 -0
  76. package/dist/cjs/sns/sns-ratchet.js +47 -0
  77. package/dist/cjs/sync-lock/dynamo-db-sync-lock.js +69 -0
  78. package/dist/cjs/sync-lock/memory-sync-lock.js +40 -0
  79. package/dist/cjs/sync-lock/sync-lock-provider.js +2 -0
  80. package/dist/es/batch/aws-batch-background-processor.js +40 -0
  81. package/dist/es/batch/aws-batch-ratchet.js +51 -0
  82. package/dist/es/build/ratchet-aws-info.js +14 -0
  83. package/dist/es/cache/dynamo-db-storage-provider.js +107 -0
  84. package/dist/es/cache/s3-storage-provider.js +40 -0
  85. package/dist/es/cache/simple-cache-object-wrapper.js +1 -0
  86. package/dist/es/cache/simple-cache-read-options.js +1 -0
  87. package/dist/es/cache/simple-cache-storage-provider.js +1 -0
  88. package/dist/es/cache/simple-cache.js +62 -0
  89. package/dist/es/cloudwatch/cloud-watch-log-group-ratchet.js +69 -0
  90. package/dist/es/cloudwatch/cloud-watch-logs-ratchet.js +169 -0
  91. package/dist/es/cloudwatch/cloud-watch-metrics-ratchet.js +53 -0
  92. package/dist/es/daemon/daemon-like.js +1 -0
  93. package/dist/es/daemon/daemon-process-create-options.js +1 -0
  94. package/dist/es/daemon/daemon-process-state-public-token.js +1 -0
  95. package/dist/es/daemon/daemon-process-state.js +1 -0
  96. package/dist/es/daemon/daemon-util.js +148 -0
  97. package/dist/es/daemon/daemon.js +122 -0
  98. package/dist/es/dao/prototype-dao-config.js +1 -0
  99. package/dist/es/dao/prototype-dao-db.js +1 -0
  100. package/dist/es/dao/prototype-dao-provider.js +1 -0
  101. package/dist/es/dao/prototype-dao.js +84 -0
  102. package/dist/es/dao/s3-prototype-dao-provider.js +24 -0
  103. package/dist/es/dao/s3-simple-dao.js +74 -0
  104. package/dist/es/dao/simple-dao-item.js +1 -0
  105. package/dist/es/dynamodb/dynamo-ratchet-like.js +1 -0
  106. package/dist/es/dynamodb/dynamo-ratchet.js +663 -0
  107. package/dist/es/dynamodb/dynamo-table-ratchet.js +87 -0
  108. package/dist/es/dynamodb/hash-spreader.js +58 -0
  109. package/dist/es/ec2/ec2-ratchet.js +103 -0
  110. package/dist/es/environment/cascade-environment-service-provider.js +23 -0
  111. package/dist/es/environment/env-var-environment-service-provider.js +29 -0
  112. package/dist/es/environment/environment-service-config.js +1 -0
  113. package/dist/es/environment/environment-service-provider.js +1 -0
  114. package/dist/es/environment/environment-service.js +48 -0
  115. package/dist/es/environment/fixed-environment-service-provider.js +20 -0
  116. package/dist/es/environment/s3-environment-service-provider.js +25 -0
  117. package/dist/es/environment/ssm-environment-service-provider.js +56 -0
  118. package/dist/es/expiring-code/dynamo-expiring-code-provider.js +22 -0
  119. package/dist/es/expiring-code/expiring-code-params.js +1 -0
  120. package/dist/es/expiring-code/expiring-code-provider.js +1 -0
  121. package/dist/es/expiring-code/expiring-code-ratchet.js +33 -0
  122. package/dist/es/expiring-code/expiring-code.js +1 -0
  123. package/dist/es/expiring-code/s3-expiring-code-provider.js +45 -0
  124. package/dist/es/iam/aws-credentials-ratchet.js +17 -0
  125. package/dist/es/index.js +78 -0
  126. package/dist/es/lambda/lambda-event-detector.js +38 -0
  127. package/dist/es/lambda/lambda-event-type-guards.js +24 -0
  128. package/dist/es/model/cloud-watch-metrics-minute-level-dynamo-count-request.js +1 -0
  129. package/dist/es/model/cloud-watch-metrics-unit.js +30 -0
  130. package/dist/es/model/dynamo/doc-put-item-command-input.js +1 -0
  131. package/dist/es/model/dynamo/doc-query-command-input.js +1 -0
  132. package/dist/es/model/dynamo/doc-scan-command-input.js +1 -0
  133. package/dist/es/model/dynamo/doc-update-item-command-input.js +1 -0
  134. package/dist/es/model/dynamo-count-result.js +1 -0
  135. package/dist/es/route53/route-53-ratchet.js +53 -0
  136. package/dist/es/runtime-parameter/cached-stored-runtime-parameter.js +1 -0
  137. package/dist/es/runtime-parameter/dynamo-runtime-parameter-provider.js +34 -0
  138. package/dist/es/runtime-parameter/global-variable-override-runtime-parameter-provider.js +49 -0
  139. package/dist/es/runtime-parameter/memory-runtime-parameter-provider.js +26 -0
  140. package/dist/es/runtime-parameter/runtime-parameter-provider.js +1 -0
  141. package/dist/es/runtime-parameter/runtime-parameter-ratchet.js +70 -0
  142. package/dist/es/runtime-parameter/stored-runtime-parameter.js +1 -0
  143. package/dist/es/s3/s3-cache-ratchet.js +328 -0
  144. package/dist/es/s3/s3-cache-to-local-disk-ratchet.js +100 -0
  145. package/dist/es/s3/s3-location-sync-ratchet.js +137 -0
  146. package/dist/es/s3/s3-ratchet.js +22 -0
  147. package/dist/es/ses/email-attachment.js +1 -0
  148. package/dist/es/ses/mailer-config.js +1 -0
  149. package/dist/es/ses/mailer-like.js +1 -0
  150. package/dist/es/ses/mailer.js +204 -0
  151. package/dist/es/ses/ratchet-template-renderer.js +1 -0
  152. package/dist/es/ses/ready-to-send-email.js +1 -0
  153. package/dist/es/ses/remote-handlebars-template-renderer.js +74 -0
  154. package/dist/es/ses/resolved-ready-to-send-email.js +1 -0
  155. package/dist/es/sns/sns-ratchet.js +43 -0
  156. package/dist/es/sync-lock/dynamo-db-sync-lock.js +65 -0
  157. package/dist/es/sync-lock/memory-sync-lock.js +36 -0
  158. package/dist/es/sync-lock/sync-lock-provider.js +1 -0
  159. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  160. package/dist/tsconfig.es.tsbuildinfo +1 -0
  161. package/dist/tsconfig.types.tsbuildinfo +1 -0
  162. package/dist/types/batch/aws-batch-background-processor.d.ts +12 -0
  163. package/dist/types/batch/aws-batch-ratchet.d.ts +16 -0
  164. package/dist/types/build/ratchet-aws-info.d.ts +5 -0
  165. package/dist/types/cache/dynamo-db-storage-provider.d.ts +25 -0
  166. package/dist/types/cache/s3-storage-provider.d.ts +14 -0
  167. package/dist/types/cache/simple-cache-object-wrapper.d.ts +7 -0
  168. package/dist/types/cache/simple-cache-read-options.d.ts +5 -0
  169. package/dist/types/cache/simple-cache-storage-provider.d.ts +8 -0
  170. package/dist/types/cache/simple-cache.d.ts +14 -0
  171. package/dist/types/cloudwatch/cloud-watch-log-group-ratchet.d.ts +9 -0
  172. package/dist/types/cloudwatch/cloud-watch-logs-ratchet.d.ts +14 -0
  173. package/dist/types/cloudwatch/cloud-watch-metrics-ratchet.d.ts +10 -0
  174. package/dist/types/daemon/daemon-like.d.ts +17 -0
  175. package/dist/types/daemon/daemon-process-create-options.d.ts +7 -0
  176. package/dist/types/daemon/daemon-process-state-public-token.d.ts +4 -0
  177. package/dist/types/daemon/daemon-process-state.d.ts +13 -0
  178. package/dist/types/daemon/daemon-util.d.ts +24 -0
  179. package/dist/types/daemon/daemon.d.ts +33 -0
  180. package/dist/types/dao/prototype-dao-config.d.ts +8 -0
  181. package/dist/types/dao/prototype-dao-db.d.ts +4 -0
  182. package/dist/types/dao/prototype-dao-provider.d.ts +5 -0
  183. package/dist/types/dao/prototype-dao.d.ts +15 -0
  184. package/dist/types/dao/s3-prototype-dao-provider.d.ts +10 -0
  185. package/dist/types/dao/s3-simple-dao.d.ts +15 -0
  186. package/dist/types/dao/simple-dao-item.d.ts +5 -0
  187. package/dist/types/dynamodb/dynamo-ratchet-like.d.ts +27 -0
  188. package/dist/types/dynamodb/dynamo-ratchet.d.ts +36 -0
  189. package/dist/types/dynamodb/dynamo-table-ratchet.d.ts +11 -0
  190. package/dist/types/dynamodb/hash-spreader.d.ts +15 -0
  191. package/dist/types/ec2/ec2-ratchet.d.ts +25 -0
  192. package/dist/types/environment/cascade-environment-service-provider.d.ts +9 -0
  193. package/dist/types/environment/env-var-environment-service-provider.d.ts +10 -0
  194. package/dist/types/environment/environment-service-config.d.ts +7 -0
  195. package/dist/types/environment/environment-service-provider.d.ts +7 -0
  196. package/dist/types/environment/environment-service.d.ts +14 -0
  197. package/dist/types/environment/fixed-environment-service-provider.d.ts +10 -0
  198. package/dist/types/environment/s3-environment-service-provider.d.ts +18 -0
  199. package/dist/types/environment/ssm-environment-service-provider.d.ts +12 -0
  200. package/dist/types/expiring-code/dynamo-expiring-code-provider.d.ts +12 -0
  201. package/dist/types/expiring-code/expiring-code-params.d.ts +7 -0
  202. package/dist/types/expiring-code/expiring-code-provider.d.ts +5 -0
  203. package/dist/types/expiring-code/expiring-code-ratchet.d.ts +13 -0
  204. package/dist/types/expiring-code/expiring-code.d.ts +6 -0
  205. package/dist/types/expiring-code/s3-expiring-code-provider.d.ts +17 -0
  206. package/dist/types/iam/aws-credentials-ratchet.d.ts +9 -0
  207. package/dist/types/index.d.ts +81 -0
  208. package/dist/types/lambda/lambda-event-detector.d.ts +14 -0
  209. package/dist/types/lambda/lambda-event-type-guards.d.ts +10 -0
  210. package/dist/types/model/cloud-watch-metrics-minute-level-dynamo-count-request.d.ts +12 -0
  211. package/dist/types/model/cloud-watch-metrics-unit.d.ts +29 -0
  212. package/dist/types/model/dynamo/doc-put-item-command-input.d.ts +4 -0
  213. package/dist/types/model/dynamo/doc-query-command-input.d.ts +5 -0
  214. package/dist/types/model/dynamo/doc-scan-command-input.d.ts +5 -0
  215. package/dist/types/model/dynamo/doc-update-item-command-input.d.ts +5 -0
  216. package/dist/types/model/dynamo-count-result.d.ts +5 -0
  217. package/dist/types/route53/route-53-ratchet.d.ts +7 -0
  218. package/dist/types/runtime-parameter/cached-stored-runtime-parameter.d.ts +4 -0
  219. package/dist/types/runtime-parameter/dynamo-runtime-parameter-provider.d.ts +11 -0
  220. package/dist/types/runtime-parameter/global-variable-override-runtime-parameter-provider.d.ts +24 -0
  221. package/dist/types/runtime-parameter/memory-runtime-parameter-provider.d.ts +13 -0
  222. package/dist/types/runtime-parameter/runtime-parameter-provider.d.ts +11 -0
  223. package/dist/types/runtime-parameter/runtime-parameter-ratchet.d.ts +15 -0
  224. package/dist/types/runtime-parameter/stored-runtime-parameter.d.ts +6 -0
  225. package/dist/types/s3/s3-cache-ratchet.d.ts +38 -0
  226. package/dist/types/s3/s3-cache-to-local-disk-ratchet.d.ts +21 -0
  227. package/dist/types/s3/s3-location-sync-ratchet.d.ts +21 -0
  228. package/dist/types/s3/s3-ratchet.d.ts +5 -0
  229. package/dist/types/ses/email-attachment.d.ts +23 -0
  230. package/dist/types/ses/mailer-config.d.ts +15 -0
  231. package/dist/types/ses/mailer-like.d.ts +18 -0
  232. package/dist/types/ses/mailer.d.ts +26 -0
  233. package/dist/types/ses/ratchet-template-renderer.d.ts +8 -0
  234. package/dist/types/ses/ready-to-send-email.d.ts +66 -0
  235. package/dist/types/ses/remote-handlebars-template-renderer.d.ts +15 -0
  236. package/dist/types/ses/resolved-ready-to-send-email.d.ts +16 -0
  237. package/dist/types/sns/sns-ratchet.d.ts +8 -0
  238. package/dist/types/sync-lock/dynamo-db-sync-lock.d.ts +10 -0
  239. package/dist/types/sync-lock/memory-sync-lock.d.ts +11 -0
  240. package/dist/types/sync-lock/sync-lock-provider.d.ts +5 -0
  241. package/package.json +112 -0
@@ -0,0 +1,107 @@
1
+ import { RequireRatchet } from '@bitblit/ratchet-common';
2
+ export class DynamoDbStorageProvider {
3
+ constructor(dynamo, opts) {
4
+ this.dynamo = dynamo;
5
+ this.opts = opts;
6
+ RequireRatchet.notNullOrUndefined(this.dynamo, 'dynamo');
7
+ RequireRatchet.notNullOrUndefined(this.opts, 'opts');
8
+ RequireRatchet.notNullOrUndefined(this.opts.tableName, 'opts.tableName');
9
+ RequireRatchet.notNullOrUndefined(this.opts.hashKeyName, 'opts.hashKeyName');
10
+ RequireRatchet.true(!this.opts.useRangeKeys || (!!this.opts.rangeKeyName && !!this.opts.hashKeyValue), 'invalid range configuration');
11
+ }
12
+ static createDefaultOptions() {
13
+ const rval = {
14
+ tableName: 'simple-cache',
15
+ useRangeKeys: false,
16
+ hashKeyName: 'cache-key',
17
+ rangeKeyName: null,
18
+ hashKeyValue: null,
19
+ };
20
+ return rval;
21
+ }
22
+ createKeyObject(cacheKey) {
23
+ const keys = {};
24
+ if (this.opts.useRangeKeys) {
25
+ keys[this.opts.hashKeyName] = this.opts.hashKeyValue;
26
+ keys[this.opts.rangeKeyName] = cacheKey;
27
+ }
28
+ else {
29
+ keys[this.opts.hashKeyName] = cacheKey;
30
+ }
31
+ return keys;
32
+ }
33
+ cleanDynamoFieldsFromObjectInPlace(rval) {
34
+ if (rval) {
35
+ delete rval[this.opts.hashKeyName];
36
+ if (this.opts.rangeKeyName) {
37
+ delete rval[this.opts.rangeKeyName];
38
+ }
39
+ if (this.opts.dynamoExpiresColumnName) {
40
+ delete rval[this.opts.dynamoExpiresColumnName];
41
+ }
42
+ }
43
+ }
44
+ extractKeysFromObject(rval) {
45
+ let keys = null;
46
+ if (rval) {
47
+ keys = {};
48
+ if (this.opts.useRangeKeys) {
49
+ keys[this.opts.hashKeyName] = this.opts.hashKeyValue;
50
+ keys[this.opts.rangeKeyName] = rval.cacheKey;
51
+ }
52
+ else {
53
+ keys[this.opts.hashKeyName] = rval.cacheKey;
54
+ }
55
+ }
56
+ return keys;
57
+ }
58
+ async readFromCache(cacheKey) {
59
+ const dKey = this.createKeyObject(cacheKey);
60
+ const rval = await this.dynamo.simpleGet(this.opts.tableName, dKey);
61
+ this.cleanDynamoFieldsFromObjectInPlace(rval);
62
+ return rval;
63
+ }
64
+ async storeInCache(value) {
65
+ RequireRatchet.notNullOrUndefined(value, 'value');
66
+ RequireRatchet.notNullOrUndefined(value.cacheKey, 'value.cacheKey');
67
+ const toSave = Object.assign({}, value, this.createKeyObject(value.cacheKey));
68
+ if (this.opts.dynamoExpiresColumnName && value.expiresEpochMS) {
69
+ toSave[this.opts.dynamoExpiresColumnName] = Math.floor(value.expiresEpochMS / 1000);
70
+ }
71
+ const wrote = await this.dynamo.simplePut(this.opts.tableName, toSave);
72
+ return !!wrote;
73
+ }
74
+ async removeFromCache(cacheKey) {
75
+ await this.dynamo.simpleDelete(this.opts.tableName, this.createKeyObject(cacheKey));
76
+ }
77
+ async clearCache() {
78
+ const allValues = await this.readAll();
79
+ const allKeys = allValues.map((a) => this.extractKeysFromObject(a));
80
+ const rval = await this.dynamo.deleteAllInBatches(this.opts.tableName, allKeys, 25);
81
+ return rval;
82
+ }
83
+ async readAll() {
84
+ let rval = null;
85
+ if (this.opts.useRangeKeys) {
86
+ const qry = {
87
+ TableName: this.opts.tableName,
88
+ KeyConditionExpression: '#cacheKey = :cacheKey',
89
+ ExpressionAttributeNames: {
90
+ '#cacheKey': this.opts.hashKeyName,
91
+ },
92
+ ExpressionAttributeValues: {
93
+ ':cacheKey': this.opts.hashKeyValue,
94
+ },
95
+ };
96
+ rval = await this.dynamo.fullyExecuteQuery(qry);
97
+ }
98
+ else {
99
+ const scan = {
100
+ TableName: this.opts.tableName,
101
+ };
102
+ rval = await this.dynamo.fullyExecuteScan(scan);
103
+ }
104
+ rval.forEach((r) => this.cleanDynamoFieldsFromObjectInPlace(r));
105
+ return rval;
106
+ }
107
+ }
@@ -0,0 +1,40 @@
1
+ import { RequireRatchet, StringRatchet } from '@bitblit/ratchet-common';
2
+ export class S3StorageProvider {
3
+ constructor(s3CacheRatchet, prefix) {
4
+ this.s3CacheRatchet = s3CacheRatchet;
5
+ this.prefix = prefix;
6
+ RequireRatchet.notNullOrUndefined(this.s3CacheRatchet, 's3CacheRatchet');
7
+ RequireRatchet.notNullOrUndefined(this.s3CacheRatchet.getDefaultBucket(), 's3CacheRatchet.defaultBucket');
8
+ }
9
+ keyToPath(cacheKey) {
10
+ let rval = StringRatchet.trimToEmpty(this.prefix);
11
+ if (rval.length > 0 && !rval.endsWith('/')) {
12
+ rval += '/';
13
+ }
14
+ rval += cacheKey;
15
+ return rval;
16
+ }
17
+ async readFromCache(cacheKey) {
18
+ const rval = await this.s3CacheRatchet.fetchCacheFileAsObject(this.keyToPath(cacheKey));
19
+ return rval;
20
+ }
21
+ async storeInCache(value) {
22
+ RequireRatchet.notNullOrUndefined(value, 'value');
23
+ RequireRatchet.notNullOrUndefined(value.cacheKey, 'value.cacheKey');
24
+ const tmp = await this.s3CacheRatchet.writeObjectToCacheFile(this.keyToPath(value.cacheKey), value);
25
+ return !!tmp;
26
+ }
27
+ async removeFromCache(cacheKey) {
28
+ await this.s3CacheRatchet.removeCacheFile(this.keyToPath(cacheKey));
29
+ }
30
+ async clearCache() {
31
+ const keys = await this.s3CacheRatchet.directChildrenOfPrefix(this.keyToPath(''));
32
+ const removed = await Promise.all(keys.map((k) => this.removeFromCache(k)));
33
+ return keys.length;
34
+ }
35
+ async readAll() {
36
+ const keys = await this.s3CacheRatchet.directChildrenOfPrefix(this.keyToPath(''));
37
+ const rval = await Promise.all(keys.map((k) => this.readFromCache(k)));
38
+ return rval;
39
+ }
40
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,62 @@
1
+ import { Logger } from '@bitblit/ratchet-common';
2
+ export class SimpleCache {
3
+ constructor(provider, defaultTimeToLiveMS = 1000 * 60) {
4
+ this.provider = provider;
5
+ this.defaultTimeToLiveMS = defaultTimeToLiveMS;
6
+ }
7
+ createDefaultReadOptions() {
8
+ return {
9
+ maxStalenessMS: null,
10
+ timeToLiveMS: this.defaultTimeToLiveMS,
11
+ cacheNullValues: false,
12
+ };
13
+ }
14
+ async fetchWrapper(cacheKey, producer, opts = this.createDefaultReadOptions()) {
15
+ Logger.silly('Fetching %s', cacheKey);
16
+ const now = new Date().getTime();
17
+ let rval = await this.provider.readFromCache(cacheKey);
18
+ if (rval && rval.expiresEpochMS < now) {
19
+ Logger.debug('Object found, but expired - removing');
20
+ rval = null;
21
+ }
22
+ if (rval && opts && opts.maxStalenessMS && now - rval.createdEpochMS > opts.maxStalenessMS) {
23
+ Logger.debug('Object found by too stale - removing');
24
+ rval = null;
25
+ }
26
+ if (!rval) {
27
+ Logger.debug('%s not found in cache, generating', cacheKey);
28
+ const tmp = await producer();
29
+ if (tmp || opts?.cacheNullValues) {
30
+ Logger.debug('Writing %j to cache');
31
+ rval = {
32
+ cacheKey: cacheKey,
33
+ createdEpochMS: now,
34
+ expiresEpochMS: opts && opts.timeToLiveMS ? now + opts.timeToLiveMS : null,
35
+ value: tmp,
36
+ generated: false,
37
+ };
38
+ await this.provider.storeInCache(rval);
39
+ rval.generated = true;
40
+ }
41
+ }
42
+ return rval;
43
+ }
44
+ async fetch(cacheKey, producer, opts = null) {
45
+ const wrapper = await this.fetchWrapper(cacheKey, producer, opts);
46
+ return wrapper ? wrapper.value : null;
47
+ }
48
+ async removeFromCache(cacheKey, returnOldValue) {
49
+ let rval = null;
50
+ if (returnOldValue) {
51
+ rval = await this.fetchWrapper(cacheKey, () => null);
52
+ }
53
+ await this.provider.removeFromCache(cacheKey);
54
+ return rval;
55
+ }
56
+ async clearCache() {
57
+ return this.provider.clearCache();
58
+ }
59
+ async readAll() {
60
+ return this.provider.readAll();
61
+ }
62
+ }
@@ -0,0 +1,69 @@
1
+ import { CloudWatchLogsClient, DescribeLogStreamsCommand, FilterLogEventsCommand, } from '@aws-sdk/client-cloudwatch-logs';
2
+ import { Logger } from '@bitblit/ratchet-common';
3
+ import { StopWatch } from '@bitblit/ratchet-common';
4
+ export class CloudWatchLogGroupRatchet {
5
+ constructor(logGroup, awsCWLogs = new CloudWatchLogsClient({ region: 'us-east-1' })) {
6
+ this.logGroup = logGroup;
7
+ this.awsCWLogs = awsCWLogs;
8
+ }
9
+ async readLogStreams(startTimestamp = null, endTimestamp = null) {
10
+ const params = {
11
+ logGroupName: this.logGroup,
12
+ orderBy: 'LastEventTime',
13
+ };
14
+ const rval = [];
15
+ do {
16
+ Logger.debug('Pulling more log streams (%d found so far)', rval.length);
17
+ const temp = await this.awsCWLogs.send(new DescribeLogStreamsCommand(params));
18
+ temp.logStreams.forEach((s) => {
19
+ if (s.lastEventTimestamp !== null) {
20
+ if (!startTimestamp || s.lastEventTimestamp >= startTimestamp) {
21
+ if (!endTimestamp || s.firstEventTimestamp <= endTimestamp) {
22
+ rval.push(s);
23
+ }
24
+ }
25
+ }
26
+ });
27
+ params.nextToken = temp.nextToken;
28
+ } while (!!params.nextToken);
29
+ Logger.debug('Found %d total, returning', rval.length);
30
+ return rval;
31
+ }
32
+ async readLogStreamNames(startTimestamp = null, endTimestamp = null) {
33
+ const streams = await this.readLogStreams(startTimestamp, endTimestamp);
34
+ const rval = streams.map((s) => s.logStreamName);
35
+ return rval;
36
+ }
37
+ async readEvents(filter, startTimestamp = null, endTimestamp = null, sortEvents = true, maxEvents = null) {
38
+ const sw = new StopWatch();
39
+ const params = {
40
+ logGroupName: this.logGroup,
41
+ endTime: endTimestamp,
42
+ startTime: startTimestamp,
43
+ };
44
+ if (filter) {
45
+ params.filterPattern = filter;
46
+ }
47
+ Logger.debug('Reading log events matching : %j', params);
48
+ let rval = [];
49
+ do {
50
+ Logger.debug('Pulling more log events (%d found so far) : %s', rval.length, sw.dump());
51
+ const temp = await this.awsCWLogs.send(new FilterLogEventsCommand(params));
52
+ rval = rval.concat(temp.events);
53
+ params.nextToken = temp.nextToken;
54
+ } while (!!params.nextToken && (!maxEvents || rval.length < maxEvents));
55
+ Logger.debug('Found %d total in %s', rval.length, sw.dump());
56
+ if (sortEvents) {
57
+ Logger.debug('Sorting events by timestamp');
58
+ rval = rval.sort((a, b) => {
59
+ let rval = a.timestamp - b.timestamp;
60
+ if (rval === 0) {
61
+ rval = a.message.localeCompare(b.message);
62
+ }
63
+ return rval;
64
+ });
65
+ }
66
+ sw.log();
67
+ return rval;
68
+ }
69
+ }
@@ -0,0 +1,169 @@
1
+ import { CloudWatchLogsClient, DeleteLogGroupCommand, DeleteLogStreamCommand, DescribeLogGroupsCommand, DescribeLogStreamsCommand, GetQueryResultsCommand, StartQueryCommand, StopQueryCommand, } from '@aws-sdk/client-cloudwatch-logs';
2
+ import { Logger } from '@bitblit/ratchet-common';
3
+ import { PromiseRatchet } from '@bitblit/ratchet-common';
4
+ import { RequireRatchet } from '@bitblit/ratchet-common';
5
+ import { StringRatchet } from '@bitblit/ratchet-common';
6
+ export class CloudWatchLogsRatchet {
7
+ constructor(cloudwatchLogs = null) {
8
+ this.cwLogs = cloudwatchLogs ? cloudwatchLogs : new CloudWatchLogsClient({ region: 'us-east-1' });
9
+ }
10
+ async removeEmptyOrOldLogStreams(logGroupName, maxToRemove = 1000, oldestEventEpochMS = null) {
11
+ Logger.info('Removing empty streams from %s, oldest event epoch MS : %d', logGroupName, oldestEventEpochMS);
12
+ const streamSearchParams = {
13
+ logGroupName: logGroupName,
14
+ orderBy: 'LastEventTime',
15
+ };
16
+ const oldestEventTester = oldestEventEpochMS || 1;
17
+ let totalStreams = 0;
18
+ const removedStreams = [];
19
+ const failedRemovedStreams = [];
20
+ let waitPerDescribe = 10;
21
+ do {
22
+ Logger.debug('Executing search for streams');
23
+ try {
24
+ const streams = await this.cwLogs.send(new DescribeLogStreamsCommand(streamSearchParams));
25
+ totalStreams += streams.logStreams.length;
26
+ Logger.debug('Found %d streams (%d so far, %d to delete)', streams.logStreams.length, totalStreams, removedStreams.length);
27
+ for (let i = 0; i < streams.logStreams.length && removedStreams.length < maxToRemove; i++) {
28
+ const st = streams.logStreams[i];
29
+ if (!st.firstEventTimestamp) {
30
+ removedStreams.push(st);
31
+ }
32
+ else if (st.lastEventTimestamp < oldestEventTester) {
33
+ removedStreams.push(st);
34
+ }
35
+ }
36
+ streamSearchParams['nextToken'] = streams.nextToken;
37
+ }
38
+ catch (err) {
39
+ const oldWait = waitPerDescribe;
40
+ waitPerDescribe = Math.min(1000, waitPerDescribe * 1.5);
41
+ Logger.info('Caught while describing %s, increasing wait between deletes (was %d, now %d)', err, oldWait, waitPerDescribe);
42
+ }
43
+ } while (!!streamSearchParams['nextToken'] && removedStreams.length < maxToRemove);
44
+ Logger.info('Found %d streams to delete', removedStreams.length);
45
+ let waitPer = 10;
46
+ for (let i = 0; i < removedStreams.length; i++) {
47
+ const delParams = {
48
+ logGroupName: logGroupName,
49
+ logStreamName: removedStreams[i].logStreamName,
50
+ };
51
+ const type = removedStreams[i].storedBytes === 0 ? 'empty' : 'old';
52
+ Logger.info('Removing %s stream %s', type, removedStreams[i].logStreamName);
53
+ let removed = false;
54
+ let retry = 0;
55
+ while (!removed && retry < CloudWatchLogsRatchet.MAX_DELETE_RETRIES) {
56
+ try {
57
+ await this.cwLogs.send(new DeleteLogStreamCommand(delParams));
58
+ removed = true;
59
+ await PromiseRatchet.wait(waitPer);
60
+ }
61
+ catch (err) {
62
+ retry++;
63
+ const oldWait = waitPer;
64
+ waitPer = Math.min(1000, waitPer * 1.5);
65
+ Logger.info('Caught %s, increasing wait between deletes and retrying (wait was %d, now %d) (Retry %d of %d)', err, oldWait, waitPer, retry, CloudWatchLogsRatchet.MAX_DELETE_RETRIES);
66
+ }
67
+ }
68
+ if (!removed) {
69
+ failedRemovedStreams.push(removedStreams[i]);
70
+ }
71
+ }
72
+ Logger.warn('Failed to remove streams : %j', failedRemovedStreams);
73
+ return removedStreams;
74
+ }
75
+ async findOldestEventTimestampInGroup(logGroupName) {
76
+ const stream = await this.findStreamWithOldestEventInGroup(logGroupName);
77
+ return stream ? stream.firstEventTimestamp : null;
78
+ }
79
+ async findStreamWithOldestEventInGroup(logGroupName) {
80
+ Logger.info('Finding oldest event in : %s', logGroupName);
81
+ let rval = null;
82
+ try {
83
+ const streamSearchParams = {
84
+ logGroupName: logGroupName,
85
+ orderBy: 'LastEventTime',
86
+ };
87
+ let totalStreams = 0;
88
+ do {
89
+ Logger.debug('Executing search for streams');
90
+ const streams = await this.cwLogs.send(new DescribeLogStreamsCommand(streamSearchParams));
91
+ totalStreams += streams.logStreams.length;
92
+ Logger.debug('Found %d streams (%d so far)', streams.logStreams.length, totalStreams);
93
+ streams.logStreams.forEach((s) => {
94
+ if (s.firstEventTimestamp && (rval === null || s.firstEventTimestamp < rval.firstEventTimestamp)) {
95
+ rval = s;
96
+ }
97
+ });
98
+ streamSearchParams['nextToken'] = streams.nextToken;
99
+ } while (!!streamSearchParams['nextToken']);
100
+ }
101
+ catch (err) {
102
+ Logger.error('Error attempting to find oldest event in group : %s : %s', logGroupName, err, err);
103
+ }
104
+ return rval;
105
+ }
106
+ async findLogGroups(prefix) {
107
+ RequireRatchet.notNullOrUndefined(prefix);
108
+ const params = {
109
+ logGroupNamePrefix: prefix,
110
+ };
111
+ let rval = [];
112
+ do {
113
+ Logger.info('%d found, pulling log groups : %j', rval.length, params);
114
+ const res = await this.cwLogs.send(new DescribeLogGroupsCommand(params));
115
+ rval = rval.concat(res.logGroups);
116
+ params.nextToken = res.nextToken;
117
+ } while (!!params.nextToken);
118
+ return rval;
119
+ }
120
+ async removeLogGroups(groups) {
121
+ RequireRatchet.notNullOrUndefined(groups);
122
+ const rval = [];
123
+ for (let i = 0; i < groups.length; i++) {
124
+ try {
125
+ Logger.info('Deleting %j', groups[i]);
126
+ const req = {
127
+ logGroupName: groups[i].logGroupName,
128
+ };
129
+ await this.cwLogs.send(new DeleteLogGroupCommand(req));
130
+ rval.push(true);
131
+ }
132
+ catch (err) {
133
+ Logger.error('Failure to delete %j : %s', groups[i], err);
134
+ rval.push(false);
135
+ }
136
+ }
137
+ return rval;
138
+ }
139
+ async removeLogGroupsWithPrefix(prefix) {
140
+ RequireRatchet.notNullOrUndefined(prefix);
141
+ RequireRatchet.true(StringRatchet.trimToEmpty(prefix).length > 0);
142
+ Logger.info('Removing log groups with prefix %s', prefix);
143
+ const groups = await this.findLogGroups(prefix);
144
+ return await this.removeLogGroups(groups);
145
+ }
146
+ async fullyExecuteInsightsQuery(sqr) {
147
+ RequireRatchet.notNullOrUndefined(sqr);
148
+ Logger.debug('Starting insights query : %j', sqr);
149
+ const resp = await this.cwLogs.send(new StartQueryCommand(sqr));
150
+ Logger.debug('Got query id %j', resp);
151
+ let rval = null;
152
+ let delayMS = 100;
153
+ while (!rval || ['Running', 'Scheduled'].includes(rval.status)) {
154
+ rval = await this.cwLogs.send(new GetQueryResultsCommand({ queryId: resp.queryId }));
155
+ await PromiseRatchet.wait(delayMS);
156
+ delayMS *= 2;
157
+ Logger.info('Got : %j', rval);
158
+ }
159
+ return rval;
160
+ }
161
+ async abortInsightsQuery(queryId) {
162
+ let rval = null;
163
+ if (!!queryId) {
164
+ rval = await this.cwLogs.send(new StopQueryCommand({ queryId: queryId }));
165
+ }
166
+ return rval;
167
+ }
168
+ }
169
+ CloudWatchLogsRatchet.MAX_DELETE_RETRIES = 5;
@@ -0,0 +1,53 @@
1
+ import { CloudWatchClient, PutMetricDataCommand } from '@aws-sdk/client-cloudwatch';
2
+ import { Logger } from '@bitblit/ratchet-common';
3
+ import { CloudWatchMetricsUnit } from '../model/cloud-watch-metrics-unit';
4
+ import { DateTime } from 'luxon';
5
+ export class CloudWatchMetricsRatchet {
6
+ constructor(cloudWatch = null) {
7
+ this.cw = cloudWatch ? cloudWatch : new CloudWatchClient({ region: 'us-east-1', apiVersion: '2010-08-01' });
8
+ }
9
+ async writeSingleMetric(namespace, metric, dims, unit = CloudWatchMetricsUnit.None, value, timestampDate = new Date(), highResolution = false) {
10
+ const cwDims = [];
11
+ if (!!dims && dims.length > 0) {
12
+ dims.forEach((d) => {
13
+ cwDims.push({ Name: d.key, Value: d.value });
14
+ });
15
+ }
16
+ const storageResolution = highResolution ? 1 : 60;
17
+ const metricData = {
18
+ Namespace: namespace,
19
+ MetricData: [
20
+ {
21
+ MetricName: metric,
22
+ Dimensions: cwDims,
23
+ Unit: String(unit),
24
+ Value: value,
25
+ Timestamp: timestampDate,
26
+ StorageResolution: storageResolution,
27
+ },
28
+ ],
29
+ };
30
+ Logger.silly('Writing metric to cw : %j', metricData);
31
+ const result = await this.cw.send(new PutMetricDataCommand(metricData));
32
+ Logger.silly('Result: %j', result);
33
+ return result;
34
+ }
35
+ async writeDynamoCountAsMinuteLevelMetric(req) {
36
+ Logger.info('Publishing %s / %s metric for %s UTC', req.namespace, req.metric, req.minuteUTC);
37
+ if (!!req.scan && !!req.query) {
38
+ throw new Error('Must send query or scan, but not both');
39
+ }
40
+ if (!req.scan && !req.query) {
41
+ throw new Error('You must specify either a scan or a query');
42
+ }
43
+ const cnt = !!req.query
44
+ ? await req.dynamoRatchet.fullyExecuteQueryCount(req.query)
45
+ : await req.dynamoRatchet.fullyExecuteScanCount(req.scan);
46
+ Logger.debug('%s / %s for %s are %j', req.namespace, req.metric, req.minuteUTC, cnt);
47
+ const parseDateString = req.minuteUTC.split(' ').join('T') + ':00Z';
48
+ const parseDate = DateTime.fromISO(parseDateString).toJSDate();
49
+ const metricRes = await this.writeSingleMetric(req.namespace, req.metric, req.dims, CloudWatchMetricsUnit.Count, cnt.count, parseDate, false);
50
+ Logger.debug('Metrics response: %j', metricRes);
51
+ return cnt.count;
52
+ }
53
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,148 @@
1
+ import { Logger } from '@bitblit/ratchet-common';
2
+ import { PutObjectCommand, } from '@aws-sdk/client-s3';
3
+ import { Upload } from '@aws-sdk/lib-storage';
4
+ export class DaemonUtil {
5
+ static async start(cache, id, s3Key, options) {
6
+ try {
7
+ options.meta = options.meta || {};
8
+ Logger.info('Starting daemon, key: %s, options: %j', s3Key, options);
9
+ const now = new Date().getTime();
10
+ const newState = {
11
+ id: id,
12
+ title: options.title,
13
+ lastUpdatedEpochMS: now,
14
+ lastUpdatedMessage: 'Created',
15
+ targetFileName: options.targetFileName,
16
+ startedEpochMS: now,
17
+ completedEpochMS: null,
18
+ meta: options.meta,
19
+ error: null,
20
+ link: null,
21
+ contentType: options.contentType,
22
+ };
23
+ const rval = await DaemonUtil.writeState(cache, s3Key, newState, DaemonUtil.DEFAULT_CONTENT);
24
+ return rval;
25
+ }
26
+ catch (err) {
27
+ Logger.error('Error while trying to start a daemon: %j %s', options, err);
28
+ throw err;
29
+ }
30
+ }
31
+ static async writeState(cache, s3Key, newState, contents) {
32
+ try {
33
+ const s3meta = {};
34
+ newState.lastUpdatedEpochMS = new Date().getTime();
35
+ s3meta[DaemonUtil.DAEMON_METADATA_KEY] = JSON.stringify(newState);
36
+ const params = {
37
+ Bucket: cache.getDefaultBucket(),
38
+ Key: s3Key,
39
+ ContentType: newState.contentType,
40
+ Metadata: s3meta,
41
+ Body: new Blob([contents]),
42
+ };
43
+ if (newState.targetFileName) {
44
+ params.ContentDisposition = 'attachment;filename="' + newState.targetFileName + '"';
45
+ }
46
+ const written = await cache.getS3Client().send(new PutObjectCommand(params));
47
+ Logger.silly('Daemon wrote : %s', written);
48
+ return DaemonUtil.stat(cache, s3Key);
49
+ }
50
+ catch (err) {
51
+ Logger.error('Error while trying to write a daemon stat: %j %s', newState, err);
52
+ throw err;
53
+ }
54
+ }
55
+ static async streamDataAndFinish(cache, s3Key, data) {
56
+ Logger.debug('Streaming data to %s', s3Key);
57
+ const inStat = await DaemonUtil.updateMessage(cache, s3Key, 'Streaming data');
58
+ inStat.completedEpochMS = new Date().getTime();
59
+ inStat.lastUpdatedMessage = 'Complete';
60
+ const s3meta = {};
61
+ s3meta[DaemonUtil.DAEMON_METADATA_KEY] = JSON.stringify(inStat);
62
+ const params = {
63
+ Bucket: cache.getDefaultBucket(),
64
+ Key: s3Key,
65
+ ContentType: inStat.contentType,
66
+ Metadata: s3meta,
67
+ Body: data,
68
+ };
69
+ const upload = new Upload({
70
+ client: cache.getS3Client(),
71
+ params: params,
72
+ tags: [],
73
+ queueSize: 4,
74
+ partSize: 1024 * 1024 * 5,
75
+ leavePartsOnError: false,
76
+ });
77
+ upload.on('httpUploadProgress', (progress) => {
78
+ Logger.info('Uploading : %s', progress);
79
+ });
80
+ const written = await upload.done();
81
+ Logger.silly('Daemon wrote : %s', written);
82
+ return DaemonUtil.stat(cache, s3Key);
83
+ }
84
+ static async updateMessage(cache, s3Key, newMessage) {
85
+ try {
86
+ const inStat = await DaemonUtil.stat(cache, s3Key);
87
+ inStat.lastUpdatedMessage = newMessage;
88
+ return DaemonUtil.writeState(cache, s3Key, inStat, DaemonUtil.DEFAULT_CONTENT);
89
+ }
90
+ catch (err) {
91
+ Logger.error('Error while trying to update a daemon message: %j %s', s3Key, err);
92
+ throw err;
93
+ }
94
+ }
95
+ static async stat(s3Cache, path) {
96
+ try {
97
+ Logger.debug('Daemon stat for path %s / %s', s3Cache.getDefaultBucket(), path);
98
+ let stat = null;
99
+ const meta = await s3Cache.fetchMetaForCacheFile(path);
100
+ Logger.debug('Daemon: Meta is %j', meta);
101
+ const metaString = meta && meta.Metadata ? meta.Metadata[DaemonUtil.DAEMON_METADATA_KEY] : null;
102
+ if (metaString) {
103
+ stat = JSON.parse(metaString);
104
+ if (stat.completedEpochMS && !stat.error) {
105
+ stat.link = await s3Cache.preSignedDownloadUrlForCacheFile(path);
106
+ }
107
+ }
108
+ else {
109
+ Logger.warn('No metadata found! (Head was %j)', meta);
110
+ }
111
+ return stat;
112
+ }
113
+ catch (err) {
114
+ Logger.error('Error while trying to fetch a daemon state: %j %s', path, err);
115
+ throw err;
116
+ }
117
+ }
118
+ static async abort(s3Cache, path) {
119
+ return DaemonUtil.error(s3Cache, path, 'Aborted');
120
+ }
121
+ static async error(s3Cache, path, error) {
122
+ try {
123
+ const inStat = await DaemonUtil.stat(s3Cache, path);
124
+ inStat.error = error;
125
+ inStat.completedEpochMS = new Date().getTime();
126
+ return DaemonUtil.writeState(s3Cache, path, inStat, DaemonUtil.DEFAULT_CONTENT);
127
+ }
128
+ catch (err) {
129
+ Logger.error('Error while trying to write a daemon error: %j %s', path, err);
130
+ throw err;
131
+ }
132
+ }
133
+ static async finalize(s3Cache, path, contents) {
134
+ try {
135
+ Logger.info('Finalizing daemon %s with %d bytes', path, contents.length);
136
+ const inStat = await DaemonUtil.stat(s3Cache, path);
137
+ inStat.completedEpochMS = new Date().getTime();
138
+ inStat.lastUpdatedMessage = 'Complete';
139
+ return DaemonUtil.writeState(s3Cache, path, inStat, contents);
140
+ }
141
+ catch (err) {
142
+ Logger.error('Error while trying to finalize a daemon: %j %s', path, err);
143
+ throw err;
144
+ }
145
+ }
146
+ }
147
+ DaemonUtil.DEFAULT_CONTENT = Buffer.from('DAEMON_PLACEHOLDER');
148
+ DaemonUtil.DAEMON_METADATA_KEY = 'daemon_meta';