-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbracery-index.js
More file actions
117 lines (108 loc) · 4.28 KB
/
Copy pathbracery-index.js
File metadata and controls
117 lines (108 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* This is a small AWS lambda function for scraping newsapi.org to Bracery.
*/
// Bracery web
const config = require('./bracery-config');
const util = require('./bracery-util');
// DynamoDB
const dynamoPromise = util.dynamoPromise();
const dynamoBatchSize = 25;
// Bracery
global.nlp = require('./compromise.es6.min'); // hack/workaround so Bracery can see nlp. Not very satisfactory.
const ParseTree = require('./bracery').ParseTree;
// The Lambda function
exports.handler = async (event, context, callback) => {
//console.log('Received event:', JSON.stringify(event, null, 2));
try {
let currentSymbolList = Object.create(null); // avoid giving this a 'constructor' property
let oldSymbolStr = Object.create(null);
let lastWord = null;
do {
let wordScanParams = { TableName: config.wordTableName };
if (lastWord)
wordScanParams.ExclusiveStartKey = lastWord;
let wordScanResult = await dynamoPromise('scan') (wordScanParams);
lastWord = wordScanResult.LastEvaluatedKey;
wordScanResult.Items.forEach ((wordItem) => {
if (wordItem.word) {
oldSymbolStr[wordItem.word] = wordItem.symbols;
currentSymbolList[wordItem.word] = [];
}
});
} while (lastWord);
let lastName = null;
do {
let defScanParams =
({ TableName: config.tableName,
FilterExpression: '#v = :v',
ExpressionAttributeNames: { '#v': 'visibility' },
ExpressionAttributeValues: { ':v': 'public' },
});
if (lastName)
defScanParams.ExclusiveStartKey = lastName;
let defScanResult = await dynamoPromise('scan') (defScanParams);
lastName = defScanResult.LastEvaluatedKey;
defScanResult.Items.forEach ((defItem) => {
const words = util.getWords (defItem.bracery, ParseTree);
const name = defItem.name;
words.forEach ((word) => {
if (word)
currentSymbolList[word] = (currentSymbolList[word] || []).concat ([name]);
});
});
} while (lastName);
let currentSymbolStr = Object.create(null);
let unchanged = 0;
Object.keys(currentSymbolList).forEach ((word) => {
const syms = currentSymbolList[word].sort().join(' ');
if (syms !== oldSymbolStr[word])
currentSymbolStr[word] = syms;
else
++unchanged;
});
Object.keys(oldSymbolStr).forEach ((word) => {
if (!currentSymbolList[word])
currentSymbolStr[word] = null;
});
console.warn (unchanged + ' entries in the word table are unchanged; ' + Object.keys(currentSymbolStr).length + ' are in need of update');
let wordsLeft = null, backoffDelay = 100, backoffMultiplier = 1.5;
let nBatch = 0;
while ((wordsLeft = Object.keys(currentSymbolStr)).length) {
++nBatch;
const wordBatch = wordsLeft.slice (0, dynamoBatchSize);
console.warn('Processing batch #' + nBatch + ' (' + wordsLeft.length + ' remaining): ' + wordBatch.join(', '));
let deleteParams = { RequestItems: {} };
deleteParams.RequestItems[config.wordTableName] = wordBatch
.filter ((word) => oldSymbolStr[word])
.map ((word) => ({
DeleteRequest: { Key: { word: word } }
}));
let failed = Object.create (null);
if (deleteParams.RequestItems[config.wordTableName].length) {
let deleteResult = await dynamoPromise('batchWriteItem') (deleteParams);
if (deleteResult.UnprocessedItems && deleteResult.UnprocessedItems[config.wordTableName])
deleteResult.UnprocessedItems[config.wordTableName].forEach ((item) => { failed[item.name] = true; });
}
let putParams = { RequestItems: {} };
putParams.RequestItems[config.wordTableName] = wordBatch
.filter ((word) => currentSymbolStr[word])
.filter ((word) => !failed[word])
.map ((word) => ({
PutRequest: { Item: { word: word,
symbols: currentSymbolStr[word] } }
}));
if (putParams.RequestItems[config.wordTableName].length) {
let putResult = await dynamoPromise('batchWriteItem') (putParams);
if (putResult.UnprocessedItems && putResult.UnprocessedItems[config.wordTableName])
putResult.UnprocessedItems[config.wordTableName].forEach ((item) => { failed[item.name] = true; });
}
wordBatch
.filter ((word) => !failed[word])
.forEach ((word) => delete currentSymbolStr[word]);
if (Object.keys(failed).length)
await util.promiseDelay (backoffDelay *= backoffMultiplier);
}
} catch (e) {
console.error (e);
throw e;
}
};