@naanlang/naan 1.6.0 → 1.7.0
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.
- package/LICENSE.md +1 -1
- package/README.md +1 -1
- package/bin/index.js +2 -2
- package/dist/env_web.js +3 -31
- package/dist/naan.min.js +10 -10
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +44 -122
- package/frameworks/browser/worker.nlg +64 -24
- package/frameworks/browser/workers.nlg +1 -1
- package/frameworks/client/apiclient.nlg +73 -43
- package/frameworks/client/psm_client.nlg +10 -14
- package/frameworks/common/common.nlg +2 -0
- package/frameworks/node/apiserver.nlg +0 -1
- package/frameworks/node/node.nlg +1 -0
- package/frameworks/node/pty.nlg +21 -21
- package/frameworks/node/shell.nlg +26 -3
- package/frameworks/node/worker.nlg +153 -79
- package/frameworks/project/build.nlg +55 -13
- package/frameworks/project/projects.nlg +1 -1
- package/frameworks/running/debugcom.nlg +20 -3
- package/frameworks/running/debugnub.nlg +16 -7
- package/frameworks/running/executors.nlg +14 -12
- package/frameworks/running/instances.nlg +1 -0
- package/frameworks/running/remote_req.nlg +4 -8
- package/frameworks/running/remote_res.nlg +1 -1
- package/frameworks/running/sourcecode.nlg +3 -2
- package/frameworks/running/taskexec.nlg +14 -57
- package/frameworks/service/imp.nlg +15 -0
- package/frameworks/service/nubnode.nlg +35 -4
- package/frameworks/service/nubweb.nlg +22 -4
- package/frameworks/storage/file_manager.nlg +3 -2
- package/lib/browser/env_web.js +10 -38
- package/lib/browser/env_webworker.js +1 -30
- package/lib/core/naanlib.js +10 -10
- package/lib/env_node.js +5 -22
- package/lib/env_nodeworker.js +8 -43
- package/lib/node_server_init.nlg +149 -0
- package/lib/node_worker.js +36 -0
- package/lib/node_worker_init.nlg +43 -0
- package/package.json +1 -1
- package/plugins/openSearch/openSearch.nlg +3 -2
- package/plugins/openSearch/os_dynamo.nlg +3 -2
- package/plugins/serviceAws/aws_cloudwatchlogs.nlg +44 -2
- package/plugins/serviceAws/aws_dynamo.nlg +144 -63
- package/plugins/serviceAws/aws_utils.nlg +6 -11
- package/plugins/serviceAws/serviceAws.nlg +3 -2
- package/test/test_01_core.nlg +2 -2
- package/test/test_02_context.nlg +8 -8
- package/test/test_03_jsinterop.nlg +3 -3
- package/test/test_07_lingo.nlg +1 -1
package/lib/env_node.js
CHANGED
|
@@ -304,27 +304,6 @@ exports.NaanNodeREPL = function NaanNodeREPL(options) {
|
|
|
304
304
|
// messages are originating from the interpreter itself, so that it does not call itself back
|
|
305
305
|
// recursively. That would be Very Bad™.
|
|
306
306
|
//
|
|
307
|
-
|
|
308
|
-
var replyHook;
|
|
309
|
-
this.OnReplyHook = function OnReplyHook(proc) {
|
|
310
|
-
replyHook = proc;
|
|
311
|
-
return (proc);
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
this.ReplyMessage = function ReplyMessage(data) {
|
|
315
|
-
if (replyHook)
|
|
316
|
-
setTimeout(function() {
|
|
317
|
-
replyHook(data);
|
|
318
|
-
}, 1);
|
|
319
|
-
if (termops)
|
|
320
|
-
{
|
|
321
|
-
setTimeout(function () {
|
|
322
|
-
if (termops)
|
|
323
|
-
termops.messageout(data);
|
|
324
|
-
}, 1);
|
|
325
|
-
}
|
|
326
|
-
return (data);
|
|
327
|
-
};
|
|
328
307
|
|
|
329
308
|
var nodeListener;
|
|
330
309
|
this.OnMessage = function OnMessage(proc) {
|
|
@@ -390,8 +369,12 @@ exports.NaanNodeREPL = function NaanNodeREPL(options) {
|
|
|
390
369
|
debugListener(msg.data); // received a debugger message
|
|
391
370
|
}, 1);
|
|
392
371
|
}
|
|
372
|
+
else if (msg.id == "attached")
|
|
373
|
+
servSelf.ioctl_event("term-attach", msg.guid);
|
|
374
|
+
else if (msg.id == "detached")
|
|
375
|
+
servSelf.ioctl_event("term-detach", msg.guid);
|
|
393
376
|
else if (msg.id == "ioctl-event")
|
|
394
|
-
|
|
377
|
+
servSelf.ioctl_event(msg.msg, msg.arg);
|
|
395
378
|
};
|
|
396
379
|
|
|
397
380
|
// textToRemoteTerm
|
package/lib/env_nodeworker.js
CHANGED
|
@@ -157,7 +157,7 @@ exports.NaanWorkerActivate = function NaanWorkerActivate(cbReady) {
|
|
|
157
157
|
//==========================================================================
|
|
158
158
|
// NodeJS Worker Terminal Interface
|
|
159
159
|
//--------------------------------------------------------------------------
|
|
160
|
-
|
|
160
|
+
|
|
161
161
|
naanlib.onText(function(text, level) {
|
|
162
162
|
if (level)
|
|
163
163
|
msgPort.postMessage({
|
|
@@ -171,7 +171,7 @@ exports.NaanWorkerActivate = function NaanWorkerActivate(cbReady) {
|
|
|
171
171
|
text: text
|
|
172
172
|
});
|
|
173
173
|
});
|
|
174
|
-
|
|
174
|
+
|
|
175
175
|
setInterval(function() {
|
|
176
176
|
var samples = naanlib.status(1);
|
|
177
177
|
if (samples.length > 0)
|
|
@@ -182,34 +182,6 @@ exports.NaanWorkerActivate = function NaanWorkerActivate(cbReady) {
|
|
|
182
182
|
}
|
|
183
183
|
});
|
|
184
184
|
}, 1000);
|
|
185
|
-
|
|
186
|
-
workSelf.ReplyMessage = function ReplyMessage(data) {
|
|
187
|
-
msgPort.postMessage({ // worker is sending a message
|
|
188
|
-
id: "targetout",
|
|
189
|
-
data: data
|
|
190
|
-
});
|
|
191
|
-
return (data);
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
var workerListener;
|
|
195
|
-
workSelf.OnMessage = function OnMessage(proc) {
|
|
196
|
-
workerListener = proc;
|
|
197
|
-
return (proc);
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
workSelf.DispatchMessage = function DispatchMessage(data) {
|
|
201
|
-
msgPort.postMessage({ // target is sending a message
|
|
202
|
-
id: "targetsend",
|
|
203
|
-
data: data
|
|
204
|
-
});
|
|
205
|
-
return (data);
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
var targetReceiver;
|
|
209
|
-
workSelf.OnReceive = function OnReceive(proc) {
|
|
210
|
-
targetReceiver = proc;
|
|
211
|
-
return (proc);
|
|
212
|
-
};
|
|
213
185
|
|
|
214
186
|
workSelf.ReplyDebugger = function ReplyDebugger(data) {
|
|
215
187
|
msgPort.postMessage({ // target is sending debug data
|
|
@@ -218,13 +190,13 @@ exports.NaanWorkerActivate = function NaanWorkerActivate(cbReady) {
|
|
|
218
190
|
});
|
|
219
191
|
return (data);
|
|
220
192
|
};
|
|
221
|
-
|
|
193
|
+
|
|
222
194
|
var debugListener;
|
|
223
195
|
workSelf.OnDebugger = function OnDebugger(proc) {
|
|
224
196
|
debugListener = proc;
|
|
225
197
|
return (proc);
|
|
226
198
|
};
|
|
227
|
-
|
|
199
|
+
|
|
228
200
|
msgPort.on("message", function(msg) {
|
|
229
201
|
if (msg.id == "interrupt")
|
|
230
202
|
naanlib.escape(); // interrupt request from terminal
|
|
@@ -235,7 +207,6 @@ exports.NaanWorkerActivate = function NaanWorkerActivate(cbReady) {
|
|
|
235
207
|
else if (msg.id == "start")
|
|
236
208
|
{ // start execution with optional state
|
|
237
209
|
workSelf.workerID = msg.workerID;
|
|
238
|
-
workSelf.workerGUID = msg.workerGUID;
|
|
239
210
|
workerMetadata = msg.metadata || { };
|
|
240
211
|
if (typeof(__dirname) !== "undefined")
|
|
241
212
|
naanlib.js.h = naanlib.js.d; // set host directory path
|
|
@@ -253,21 +224,15 @@ exports.NaanWorkerActivate = function NaanWorkerActivate(cbReady) {
|
|
|
253
224
|
}
|
|
254
225
|
else if (msg.id == "import")
|
|
255
226
|
importScripts(msg.script); // load a JavaScript
|
|
256
|
-
else if (msg.id == "targetin")
|
|
257
|
-
{
|
|
258
|
-
if (workerListener)
|
|
259
|
-
workerListener(msg.data); // worker received a message
|
|
260
|
-
}
|
|
261
227
|
else if (msg.id == "debugin")
|
|
262
228
|
{
|
|
263
229
|
if (debugListener)
|
|
264
230
|
debugListener(msg.data); // target received a message
|
|
265
231
|
}
|
|
266
|
-
else if (msg.id == "
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
232
|
+
else if (msg.id == "attached")
|
|
233
|
+
workSelf.ioctl_event("term-attach", msg.guid);
|
|
234
|
+
else if (msg.id == "detached")
|
|
235
|
+
workSelf.ioctl_event("term-detach", msg.guid);
|
|
271
236
|
else if (msg.id == "ioctl-event")
|
|
272
237
|
workSelf.ioctl_event(msg.msg, msg.arg);
|
|
273
238
|
});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* node_server_init.nlg
|
|
3
|
+
* Naanide
|
|
4
|
+
*
|
|
5
|
+
* Loaded automatically for Node.js before REPL turned over to the user.
|
|
6
|
+
*
|
|
7
|
+
* column positioning: // // !
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2020-2026 by Richard C. Zulch
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
loglevel(3);
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
* Debugging & Tools
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
if !module.owner.list.running.components.debugnub {
|
|
22
|
+
require("naanlib:frameworks/common/repltools.nlg").ImportReplTools()
|
|
23
|
+
require("naanlib:frameworks/running/debugnub.nlg").DebugNub()
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
App.shell = require("naanlib:frameworks/node/shell.nlg").ShellConnect({
|
|
27
|
+
cwd: js.d
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
* versionCheck
|
|
33
|
+
*
|
|
34
|
+
* Ensure that Node is at least as new as the specified version.
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
function versionCheck(minver, local rxver, curver) {
|
|
39
|
+
rxver = RegExp("([0-9]+)[.]([0-9]+)[.]([0-9]+)")
|
|
40
|
+
minver = minver.match(rxver).map(function(x){Number.parseInt(x)})
|
|
41
|
+
curver = js.g.process.version.match(rxver).map(function(x){Number.parseInt(x)})
|
|
42
|
+
minver[1] < curver[1] || minver[1] == curver[1] && (minver[2] < curver[2] || minver[2] == curver[2] && minver[3] <= curver[3])
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
* saveState
|
|
48
|
+
*
|
|
49
|
+
* Save our state soon. This saves in a future to avoid stack problems. Returns a nonce.
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
function saveState() {
|
|
54
|
+
future(function() {
|
|
55
|
+
js.t.Working()
|
|
56
|
+
js.save()
|
|
57
|
+
}, 0)
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* startup
|
|
63
|
+
*
|
|
64
|
+
* This is the normal NaanIDE startup code. The scenarios are as follows:
|
|
65
|
+
* 1. Start new server at available port and launch browser tab // default behavior
|
|
66
|
+
* 2. Start new server with intialization file that launches browser
|
|
67
|
+
* 3. Start new server at fixed port and launch browser tab
|
|
68
|
+
* 4. Start new server at fixed port with initialization file
|
|
69
|
+
* 5. Connect to existing server at fixed port and evaluate remote expression, then quit
|
|
70
|
+
*
|
|
71
|
+
* This uses the Naan symbol NaanStartParams as:
|
|
72
|
+
* {
|
|
73
|
+
* naanpath: <string> // path to the naan library
|
|
74
|
+
* serverPort: <integer> // defined if the command line specified a port
|
|
75
|
+
* guid: <string> // server secret
|
|
76
|
+
* cmd_mod: <string> // name of a command to execute
|
|
77
|
+
* cmd_path: <string> // path to command's module
|
|
78
|
+
* cmd_args: [<string>] // arguments to the command
|
|
79
|
+
* }
|
|
80
|
+
*
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
closure startup(local error, api, exists, oururl) {
|
|
84
|
+
if !versionCheck("16.20.2") {
|
|
85
|
+
debuglog("NaanIDE: NodeJS too old; version 16.20.2 required.")
|
|
86
|
+
js.g.process.exit(2)
|
|
87
|
+
}
|
|
88
|
+
if !dictionary(NaanStartParams) {
|
|
89
|
+
debuglog("NaanIDE: startup parameters missing.")
|
|
90
|
+
js.g.process.exit(3)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
App.imp = require("naanlib:frameworks/service/imp.nlg").Imp({
|
|
94
|
+
name: "NaanIDE Server"
|
|
95
|
+
type: "Server IMP"
|
|
96
|
+
})
|
|
97
|
+
require("naanlib:frameworks/running/remote_res.nlg")
|
|
98
|
+
.RemoteResponder(App.imp.us.instanceID, { // make our server remotable
|
|
99
|
+
name: "NaanIDE Server"
|
|
100
|
+
type: "Node Remote"
|
|
101
|
+
})
|
|
102
|
+
App.exec = require("naanlib:frameworks/node/worker.nlg").CurBot({
|
|
103
|
+
name: "NaanIDE Server"
|
|
104
|
+
type: "NaaN Server"
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
App.api = undefined
|
|
108
|
+
App.naanpath = NaanStartParams.naanpath
|
|
109
|
+
App.nidecon = require("lib/nidecon").NideCon({
|
|
110
|
+
fixedPort: NaanStartParams.serverPort
|
|
111
|
+
guid: NaanStartParams.guid
|
|
112
|
+
statics: [
|
|
113
|
+
list("", NaanStartParams.naanpath)
|
|
114
|
+
]
|
|
115
|
+
})
|
|
116
|
+
if NaanStartParams.cmd_mod {
|
|
117
|
+
`(error) = App.nidecon.runCommand(NaanStartParams.cmd_mod, NaanStartParams.cmd_path, NaanStartParams.cmd_args)
|
|
118
|
+
saveState().wait() // wait so we don't exit too soon
|
|
119
|
+
if error {
|
|
120
|
+
if error.memo != ""
|
|
121
|
+
ErrorDebuglog("NaanIDE: command failed", error)
|
|
122
|
+
if error.exit
|
|
123
|
+
js.g.process.exit(error.exit) // fatal error
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else if js.expr
|
|
127
|
+
saveState().wait()
|
|
128
|
+
else {
|
|
129
|
+
`(error, api, exists) = App.nidecon.startServer()
|
|
130
|
+
if exists {
|
|
131
|
+
`(error, oururl) = App.nidecon.connectServer()
|
|
132
|
+
if error {
|
|
133
|
+
ErrorDebuglog("NaanIDE: server at port ${NaanStartParams.serverPort} not responding", error)
|
|
134
|
+
js.g.process.exit(1)
|
|
135
|
+
}
|
|
136
|
+
debuglog("existing server access:", oururl)
|
|
137
|
+
return
|
|
138
|
+
} else if error {
|
|
139
|
+
ErrorDebuglog("NaanIDE: can't start server:", error)
|
|
140
|
+
js.g.process.exit(1)
|
|
141
|
+
}
|
|
142
|
+
debuglog("server access:", api.oururl)
|
|
143
|
+
Naan.runtimelib.curdriver().setOptions({prompt:true})
|
|
144
|
+
saveState()
|
|
145
|
+
`(error) = App.nidecon.launchBrowser()
|
|
146
|
+
if error
|
|
147
|
+
ErrorDebuglog("NaanIDE: can't launch browser:", error)
|
|
148
|
+
}
|
|
149
|
+
}();
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* node_worker.js
|
|
3
|
+
* naanide
|
|
4
|
+
*
|
|
5
|
+
* Start a Naanide worker.
|
|
6
|
+
*
|
|
7
|
+
* column positioning: // // !
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2017-2026 by Richard C. Zulch
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
"use strict";
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
* Begin
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
var workerData = require('node:worker_threads').workerData || { }; // passed from creator
|
|
22
|
+
var jspath = require("path");
|
|
23
|
+
var naanpath = jspath.resolve(require.resolve('@naanlang/naan'), '../../../');
|
|
24
|
+
var envpath = jspath.resolve(naanpath, 'lib/env_nodeworker.js');
|
|
25
|
+
var naanenv = require(envpath);
|
|
26
|
+
|
|
27
|
+
naanenv.NaanWorkerActivate(function(naanworker) {
|
|
28
|
+
naanworker.setRequire(require); // require relative to this file
|
|
29
|
+
naanworker.setImport(function(m) { return (import(m)); }); // import relative to this file
|
|
30
|
+
|
|
31
|
+
naanworker.textCommand(""
|
|
32
|
+
+ `App.naanpath = '${ naanpath.replace(/\\/g, "\\\\") }';;` // path/to/our naan library
|
|
33
|
+
+ "App.rootpath = js.d;;" // path/to/our package.json
|
|
34
|
+
+ "Naan.module.defineLoc('naanlib', App.naanpath);;" // defines "naanlib:" prefix for require
|
|
35
|
+
+ "Naan.module.nodeparse('lib/node_worker_init.nlg');;\n"); // Naan initialization
|
|
36
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* nide_worker_init.nlg
|
|
3
|
+
* NaanIDE
|
|
4
|
+
*
|
|
5
|
+
* Loaded automatically for Node.js before REPL turned over to the user.
|
|
6
|
+
*
|
|
7
|
+
* column positioning: // // !
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2020-2026 by Richard C. Zulch
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
loglevel(3);
|
|
15
|
+
chns("Start");
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* Debugging & Tools
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
function init(local metadata) {
|
|
24
|
+
sprint() // no interruptions
|
|
25
|
+
if !module.owner.list.running.components.debugnub {
|
|
26
|
+
require("naanlib:frameworks/common/repltools.nlg").ImportReplTools()
|
|
27
|
+
require("naanlib:frameworks/running/debugnub.nlg").DebugNub()
|
|
28
|
+
}
|
|
29
|
+
App.shell = require("naanlib:frameworks/node/shell.nlg").ShellConnect({
|
|
30
|
+
cwd: js.d
|
|
31
|
+
})
|
|
32
|
+
metadata = new(js.t.metadata())
|
|
33
|
+
App.mainInstanceID = metadata.mainInstanceID
|
|
34
|
+
App.imp = require("naanlib:frameworks/service/imp.nlg").Imp({
|
|
35
|
+
name: metadata.name
|
|
36
|
+
type: "node-worker"
|
|
37
|
+
})
|
|
38
|
+
require("naanlib:frameworks/service/nubnode.nlg").NodeWorkerNub(App.imp, {
|
|
39
|
+
name: App.imp.us.name
|
|
40
|
+
})
|
|
41
|
+
if metadata.maintext
|
|
42
|
+
textparse(metadata.maintext)
|
|
43
|
+
}();
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2023 by Richard C. Zulch
|
|
9
|
+
* Copyright (c) 2023-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -53,6 +53,7 @@ closure openSearchIndex(prosc, indexName, ioptions, local osin) {
|
|
|
53
53
|
osin = new(object, this)
|
|
54
54
|
if symbol(indexName)
|
|
55
55
|
indexName = indexName.tostring()
|
|
56
|
+
osin.name = indexName
|
|
56
57
|
osin.analyzers = { // map names, language to analyzer
|
|
57
58
|
english: "english"
|
|
58
59
|
hashtag: "hashtag"
|
|
@@ -335,7 +336,7 @@ closure openSearchIndex(prosc, indexName, ioptions, local osin) {
|
|
|
335
336
|
`(error, data) = prosc.request(indexName.concat("/_bulk"), {
|
|
336
337
|
method: "POST"
|
|
337
338
|
putdata: docs
|
|
338
|
-
contentType: "application/
|
|
339
|
+
contentType: "application/x-ndjson"
|
|
339
340
|
})
|
|
340
341
|
if data
|
|
341
342
|
data = data.items.map(function(item) {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2023-
|
|
9
|
+
* Copyright (c) 2023-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
|
|
42
42
|
closure OSDynIndexer(index, table, options,
|
|
43
43
|
local dbOptions, scanPending, indexPending, updatePending, output, error, records, data, ids) {
|
|
44
|
+
global()
|
|
44
45
|
if !options.converter
|
|
45
46
|
return (Error("OSDynIndexer: options.converter is required"))
|
|
46
47
|
dbOptions = {
|
|
@@ -78,7 +79,7 @@ closure OSDynIndexer(index, table, options,
|
|
|
78
79
|
//
|
|
79
80
|
// Batch index documents into OpenSearch, returning a nonce signaled with ids array.
|
|
80
81
|
//
|
|
81
|
-
closure batchIndex(records, local pending) {
|
|
82
|
+
closure batchIndex(records, local pending, docs) {
|
|
82
83
|
pending = new(nonce)
|
|
83
84
|
docs = asyncArray(records, 10, closure(record) {
|
|
84
85
|
options.converter(record)
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
closure CloudWatchLogs(local cwlogs) {
|
|
21
|
+
closure CloudWatchLogs(local cwlogs, delayf, backoffMS) {
|
|
22
22
|
global(awsSDK)
|
|
23
23
|
cwlogs = new(object, this)
|
|
24
24
|
|
|
@@ -35,7 +35,42 @@ closure CloudWatchLogs(local cwlogs) {
|
|
|
35
35
|
})
|
|
36
36
|
list(false, { ok: true })
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
// retrier
|
|
40
|
+
//
|
|
41
|
+
// Perform exponential backoff when throttled, returning true for retry or false otherwise.
|
|
42
|
+
//
|
|
43
|
+
function retrier(error, local waitms, newbo) {
|
|
44
|
+
if !error
|
|
45
|
+
delayf = false
|
|
46
|
+
else if error.name == "ThrottlingException" { // retriable errors
|
|
47
|
+
if backoffMS > milliseconds() {
|
|
48
|
+
debuglog("DynaTable.retrier: existing backoff", backoffMS - milliseconds(), "msec")
|
|
49
|
+
return (true) // use existing backoff
|
|
50
|
+
}
|
|
51
|
+
if !delayf
|
|
52
|
+
delayf = ExbackFactory(6,60) // 6s max backoff, 60s deadline
|
|
53
|
+
waitms = delayf()
|
|
54
|
+
debuglog("DynaTable.retrier: new backoff:", waitms, "msec")
|
|
55
|
+
if waitms { // returns false for no retry
|
|
56
|
+
newbo = milliseconds() + waitms // tick when proceeding is allowed
|
|
57
|
+
if !(backoffMS > newbo)
|
|
58
|
+
backoffMS = newbo
|
|
59
|
+
true
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
38
63
|
|
|
64
|
+
// delayer
|
|
65
|
+
//
|
|
66
|
+
// Delay until the current backoff is complete.
|
|
67
|
+
//
|
|
68
|
+
function delayer(local waitms) {
|
|
69
|
+
waitms = backoffMS - milliseconds()
|
|
70
|
+
if waitms > 0
|
|
71
|
+
sleep(waitms + waitms * Math.random()/2)
|
|
72
|
+
}
|
|
73
|
+
|
|
39
74
|
//
|
|
40
75
|
// cwlQueryPager
|
|
41
76
|
//
|
|
@@ -46,7 +81,14 @@ closure CloudWatchLogs(local cwlogs) {
|
|
|
46
81
|
if !remaining
|
|
47
82
|
remaining = 10 // default retrieve limit
|
|
48
83
|
params.limit = remaining
|
|
49
|
-
|
|
84
|
+
delayer()
|
|
85
|
+
QueryPager(cwlogs.aws, procname, params, function(error, data, local processed) {
|
|
86
|
+
if error {
|
|
87
|
+
if !retrier(error)
|
|
88
|
+
return (false)
|
|
89
|
+
delayer()
|
|
90
|
+
return (true)
|
|
91
|
+
}
|
|
50
92
|
processed = doneCB(data)
|
|
51
93
|
if processed
|
|
52
94
|
remaining -= processed
|