idea-aws 3.7.1 → 3.7.2

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.
@@ -63,18 +63,21 @@ export declare class DynamoDB {
63
63
  * @param ignoreErr if set, ignore the errors and continue the bulk op.
64
64
  */
65
65
  batchGet(table: string, keys: DDB.DocumentClient.Key[], ignoreErr?: boolean): Promise<DDB.DocumentClient.AttributeMap[]>;
66
- protected batchGetHelper(table: string, keys: DDB.DocumentClient.Key[], resultElements: DDB.DocumentClient.AttributeMap[], ignoreErr: boolean, currentChunk: number, chunkSize: number): Promise<DDB.DocumentClient.AttributeMap[]>;
66
+ protected batchGetHelper(table: string, keys: DDB.DocumentClient.Key[], resultElements: DDB.DocumentClient.AttributeMap[], ignoreErr: boolean, currentChunk?: number, chunkSize?: number): Promise<DDB.DocumentClient.AttributeMap[]>;
67
67
  /**
68
68
  * Put an array of items in a DynamoDb table, avoiding the limits of DynamoDB's BatchWriteItem.
69
- * @param ignoreErr if true, ignore the errors and continue the bulk op
69
+ * In case of errors, it will retry with a random back-off mechanism until the timeout.
70
+ * Therefore, in case of timeout, there may be some elements written and some not.
70
71
  */
71
- batchPut(table: string, items: DDB.DocumentClient.AttributeMap[], ignoreErr?: boolean): Promise<void>;
72
+ batchPut(table: string, items: DDB.DocumentClient.AttributeMap[]): Promise<void>;
72
73
  /**
73
74
  * Delete an array of items from a DynamoDb table, avoiding the limits of DynamoDB's BatchWriteItem.
74
- * @param ignoreErr if true, ignore the errors and continue the bulk op.
75
+ * In case of errors, it will retry with a random back-off mechanism until the timeout.
76
+ * Therefore, in case of timeout, there may be some elements deleted and some not.
75
77
  */
76
- batchDelete(table: string, keys: DDB.DocumentClient.Key[], ignoreErr?: boolean): Promise<void>;
77
- protected batchWriteHelper(table: string, items: DDB.DocumentClient.AttributeMap[], isPut: boolean, ignoreErr: boolean, currentChunk: number, chunkSize: number): Promise<void>;
78
+ batchDelete(table: string, keys: DDB.DocumentClient.Key[]): Promise<void>;
79
+ protected batchWriteHelper(table: string, itemsOrKeys: DDB.DocumentClient.AttributeMap[] | DDB.DocumentClient.Key[], isPut: boolean, currentChunk?: number, chunkSize?: number): Promise<void>;
80
+ protected batchWriteChunkWithRetries(table: string, params: DDB.DocumentClient.BatchWriteItemInput): Promise<void>;
78
81
  /**
79
82
  * Query a DynamoDb table, avoiding the limits of DynamoDB's Query.
80
83
  * @param params the params to apply to DynamoDB's function
@@ -157,9 +157,9 @@ class DynamoDB {
157
157
  (0, idea_toolbox_1.logger)(`BATCH GET ${table}`, null, 'No elements to get');
158
158
  return [];
159
159
  }
160
- await this.batchGetHelper(table, keys, [], Boolean(ignoreErr), 0, 100);
160
+ await this.batchGetHelper(table, keys, [], Boolean(ignoreErr));
161
161
  }
162
- async batchGetHelper(table, keys, resultElements, ignoreErr, currentChunk, chunkSize) {
162
+ async batchGetHelper(table, keys, resultElements, ignoreErr, currentChunk = 0, chunkSize = 100) {
163
163
  const batch = { RequestItems: {} };
164
164
  batch.RequestItems[table] = { Keys: [] };
165
165
  batch.RequestItems[table].Keys = keys.slice(currentChunk, currentChunk + chunkSize);
@@ -182,48 +182,57 @@ class DynamoDB {
182
182
  }
183
183
  /**
184
184
  * Put an array of items in a DynamoDb table, avoiding the limits of DynamoDB's BatchWriteItem.
185
- * @param ignoreErr if true, ignore the errors and continue the bulk op
185
+ * In case of errors, it will retry with a random back-off mechanism until the timeout.
186
+ * Therefore, in case of timeout, there may be some elements written and some not.
186
187
  */
187
- async batchPut(table, items, ignoreErr) {
188
+ async batchPut(table, items) {
188
189
  if (!items.length)
189
190
  return (0, idea_toolbox_1.logger)(`BATCH WRITE (PUT) ${table}`, null, 'No elements to write');
190
- await this.batchWriteHelper(table, items, true, Boolean(ignoreErr), 0, 25);
191
+ await this.batchWriteHelper(table, items, true);
191
192
  }
192
193
  /**
193
194
  * Delete an array of items from a DynamoDb table, avoiding the limits of DynamoDB's BatchWriteItem.
194
- * @param ignoreErr if true, ignore the errors and continue the bulk op.
195
+ * In case of errors, it will retry with a random back-off mechanism until the timeout.
196
+ * Therefore, in case of timeout, there may be some elements deleted and some not.
195
197
  */
196
- async batchDelete(table, keys, ignoreErr) {
198
+ async batchDelete(table, keys) {
197
199
  if (!keys.length)
198
200
  return (0, idea_toolbox_1.logger)(`BATCH WRITE (DELETE) ${table}`, null, 'No elements to write');
199
- await this.batchWriteHelper(table, keys, false, Boolean(ignoreErr), 0, 25);
201
+ await this.batchWriteHelper(table, keys, false);
200
202
  }
201
- async batchWriteHelper(table, items, isPut, ignoreErr, currentChunk, chunkSize) {
202
- const batch = { RequestItems: {} };
203
- if (isPut) {
204
- batch.RequestItems[table] = items
205
- .slice(currentChunk, currentChunk + chunkSize)
206
- .map(i => ({ PutRequest: { Item: i } }));
207
- }
208
- else {
209
- // isDelete
210
- batch.RequestItems[table] = items
211
- .slice(currentChunk, currentChunk + chunkSize)
212
- .map(k => ({ DeleteRequest: { Key: k } }));
213
- }
214
- (0, idea_toolbox_1.logger)(`BATCH WRITE (${isPut ? 'PUT' : 'DELETE'}) ${table}`, null, `${currentChunk} of ${items.length}`);
215
- try {
216
- await this.dynamo.batchWrite(batch).promise();
217
- }
218
- catch (err) {
219
- if (!ignoreErr)
220
- throw err;
221
- }
203
+ async batchWriteHelper(table, itemsOrKeys, isPut, currentChunk = 0, chunkSize = 25) {
204
+ (0, idea_toolbox_1.logger)(`BATCH WRITE (${isPut ? 'PUT' : 'DELETE'}) ${table}`, null, `${currentChunk} of ${itemsOrKeys.length}`);
205
+ let requests;
206
+ if (isPut)
207
+ requests = itemsOrKeys.slice(currentChunk, currentChunk + chunkSize).map(i => ({ PutRequest: { Item: i } }));
208
+ // isDelete
209
+ else
210
+ requests = itemsOrKeys.slice(currentChunk, currentChunk + chunkSize).map(k => ({ DeleteRequest: { Key: k } }));
211
+ const batch = { RequestItems: { [table]: requests } };
212
+ await this.batchWriteChunkWithRetries(table, batch);
222
213
  // if there are still chunks to manage, go on recursively
223
- if (currentChunk + chunkSize < items.length)
224
- await this.batchWriteHelper(table, items, isPut, ignoreErr, currentChunk + chunkSize, chunkSize);
225
- // no more chunks to manage: we're done
226
- return;
214
+ if (currentChunk + chunkSize < itemsOrKeys.length)
215
+ await this.batchWriteHelper(table, itemsOrKeys, isPut, currentChunk + chunkSize, chunkSize);
216
+ }
217
+ async batchWriteChunkWithRetries(table, params) {
218
+ const getRandomInt = (max) => Math.floor(Math.random() * max);
219
+ const wait = (seconds) => new Promise(x => setTimeout(() => x(), seconds * 1000));
220
+ let attempts = 0;
221
+ do {
222
+ const response = await this.dynamo.batchWrite(params).promise();
223
+ if (response.UnprocessedItems &&
224
+ response.UnprocessedItems[table] &&
225
+ response.UnprocessedItems[table].length > 0) {
226
+ params.RequestItems = response.UnprocessedItems;
227
+ attempts++;
228
+ const waitSeconds = getRandomInt(attempts * 5);
229
+ (0, idea_toolbox_1.logger)('BATCH WRITE THROTTLED', null, `Waiting ${waitSeconds} seconds to retry`);
230
+ await wait(waitSeconds);
231
+ }
232
+ else {
233
+ params.RequestItems = null;
234
+ }
235
+ } while (params.RequestItems);
227
236
  }
228
237
  /**
229
238
  * Query a DynamoDb table, avoiding the limits of DynamoDB's Query.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "idea-aws",
3
- "version": "3.7.1",
3
+ "version": "3.7.2",
4
4
  "description": "AWS wrappers to use in IDEA's back-ends",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",