@naanlang/naan 1.6.0 → 1.7.1
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 -32
- package/dist/naan.min.js +10 -10
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +161 -212
- package/frameworks/browser/worker.nlg +78 -30
- package/frameworks/browser/workers.nlg +1 -1
- package/frameworks/browser/ws_client.nlg +23 -87
- package/frameworks/client/apiclient.nlg +91 -58
- package/frameworks/client/client.nlg +22 -2
- package/frameworks/client/psm_client.nlg +10 -14
- package/frameworks/client/relaycon.nlg +1 -1
- package/frameworks/common/common.nlg +13 -9
- package/frameworks/node/apiserver.nlg +1 -2
- 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 +166 -84
- package/frameworks/node/ws_client.nlg +25 -84
- package/frameworks/project/build.nlg +83 -32
- package/frameworks/project/projects.nlg +2 -2
- package/frameworks/running/debugcom.nlg +20 -3
- package/frameworks/running/debugnub.nlg +16 -7
- package/frameworks/running/executors.nlg +36 -26
- package/frameworks/running/instances.nlg +34 -22
- package/frameworks/running/remote_req.nlg +6 -9
- package/frameworks/running/remote_res.nlg +2 -2
- package/frameworks/running/sourcecode.nlg +3 -2
- package/frameworks/running/taskexec.nlg +14 -57
- package/frameworks/service/imp.nlg +37 -5
- package/frameworks/service/nubnode.nlg +39 -8
- package/frameworks/service/nubweb.nlg +28 -10
- package/frameworks/storage/file_manager.nlg +3 -2
- package/lib/browser/env_web.js +10 -39
- 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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2019-
|
|
9
|
+
* Copyright (c) 2019-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -304,18 +304,26 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
304
304
|
//
|
|
305
305
|
// Apply substitutions from readSubstitutionFile to string, returning a tuple of the resulting
|
|
306
306
|
// text and the number of substitution patterns actually used from the supplied dictionary.
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
subst
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
307
|
+
// Specify iterative to repeat the substitution on the result until no more substitutions occur.
|
|
308
|
+
//
|
|
309
|
+
function applySubstitutions(text, subs, iterative, local count, subbed) {
|
|
310
|
+
count = 0
|
|
311
|
+
loop {
|
|
312
|
+
subbed = { }
|
|
313
|
+
text = text.replace(RegExp("[$][^$\\s]+[$]", "g"), function(match, local subst) {
|
|
314
|
+
subst = subs[match.slice(1,-1)]
|
|
315
|
+
if subst {
|
|
316
|
+
subbed[match] = true
|
|
317
|
+
subst
|
|
318
|
+
}
|
|
319
|
+
else
|
|
320
|
+
match
|
|
321
|
+
})
|
|
322
|
+
count += length(subbed)
|
|
323
|
+
if length(subbed) == 0 || !iterative
|
|
324
|
+
break
|
|
325
|
+
}
|
|
326
|
+
list(text, count)
|
|
319
327
|
}
|
|
320
328
|
|
|
321
329
|
//
|
|
@@ -426,7 +434,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
426
434
|
// autoquoted to itself, a symbol. This can be used to detect build time vs. runtime.
|
|
427
435
|
|
|
428
436
|
function parseAndPack1(text, fpath, options, operation,
|
|
429
|
-
local util, lib, penv, naansym, dlogsym, pmod, pcomp, output, textout, annerror, annotations, package)
|
|
437
|
+
local util, lib, penv, naansym, dlogsym, pmod, pcomp, ournn, output, textout, annerror, annotations, package)
|
|
430
438
|
{
|
|
431
439
|
//
|
|
432
440
|
// textline
|
|
@@ -445,20 +453,39 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
445
453
|
lib = Naan.module.modlist().Lib.exports
|
|
446
454
|
if !util || !lib
|
|
447
455
|
return (list("Build packager cannot access support functions"))
|
|
456
|
+
//
|
|
457
|
+
// The following crazy rigmarole is about customizing the ParsEnvironment so we can glean
|
|
458
|
+
// enough information to build a package without actually executing the code. To do this we
|
|
459
|
+
// replace the entire Naan.module collection of functions with just build, so the others do
|
|
460
|
+
// nothing. From that we collect the module and component names, plus the manifest. This
|
|
461
|
+
// also sets up a benign "exports" dictionary so module build can "go through the mtions"
|
|
462
|
+
// without modification.
|
|
463
|
+
//
|
|
448
464
|
penv = lib.ParsEnvironment(Dialect, "build-".concat(operation))
|
|
449
465
|
penv.evalq(letlocal(App)) // make local copy of App
|
|
450
466
|
penv.evalq(letlocal(js)) // make local copy of js
|
|
451
|
-
|
|
452
|
-
penv.evalq(assign(naansym,new(Naan))) // make it modifiable
|
|
467
|
+
ournn = new(Naan) // get modifiable Naan
|
|
453
468
|
pmod = { } // our module object
|
|
454
469
|
pcomp = { } // our component object
|
|
455
|
-
|
|
470
|
+
ournn.module = {
|
|
456
471
|
build: function(modname, compname, proc) {
|
|
457
|
-
pmod.id = module
|
|
472
|
+
pmod.id = module.id
|
|
473
|
+
pmod.exports = { }
|
|
458
474
|
pcomp.name = compname
|
|
459
475
|
call(proc, pmod, pcomp) // obtain manifest
|
|
460
476
|
}
|
|
461
477
|
}
|
|
478
|
+
naansym = penv.evalq(function(nn) {
|
|
479
|
+
assign(letlocal(Naan).0,nn)
|
|
480
|
+
`Naan
|
|
481
|
+
}(ournn)) // make Naan modifiable
|
|
482
|
+
penv.evalq(assign(letlocal(module).0, { // make local copy of module
|
|
483
|
+
exports: { }
|
|
484
|
+
}))
|
|
485
|
+
//
|
|
486
|
+
// Here we make a custom debuglog function that identifies the text without color and will
|
|
487
|
+
// write the output to the build log.
|
|
488
|
+
//
|
|
462
489
|
dlogsym = penv.evalq(letlocal(debuglog).0) // make local copy of debuglog
|
|
463
490
|
penv.evalq(function \.debuglog args { // redefine debuglog for capture
|
|
464
491
|
let (arg, spaced) {
|
|
@@ -471,8 +498,19 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
471
498
|
apply(textline, reverse(spaced))
|
|
472
499
|
} () })
|
|
473
500
|
penv.evalq(putproc(car(dlogsym), \.debuglog.proc))
|
|
501
|
+
//
|
|
502
|
+
// The NideBuild symbol is "debug" or "release", etc. or is simply autoquoted as the symbol
|
|
503
|
+
// itself when not building. This is used if the source needs different behavior at build
|
|
504
|
+
// time or run time.
|
|
505
|
+
//
|
|
474
506
|
penv.eval(append(quote(assign(compress("NideBuild"))), operation)) // NideBuild symbol is operation name string
|
|
507
|
+
//
|
|
508
|
+
// This is the actual meat of the matter, the parsing of the program text.
|
|
509
|
+
//
|
|
475
510
|
output = penv.parse(text) // parse and evaluate
|
|
511
|
+
//
|
|
512
|
+
// Output processing and error logging
|
|
513
|
+
//
|
|
476
514
|
textout = ""
|
|
477
515
|
try {
|
|
478
516
|
if !pcomp.name
|
|
@@ -507,20 +545,30 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
507
545
|
}
|
|
508
546
|
if output.errors.length > 0
|
|
509
547
|
return (list("errors in ".concat(fpath), false, annotations, textout))
|
|
548
|
+
//
|
|
549
|
+
// Build the package, if not just doing syntax checking
|
|
550
|
+
//
|
|
510
551
|
if options.naanpack || options.jspack { // actually building a package?
|
|
511
552
|
if !pcomp.name {
|
|
512
|
-
|
|
553
|
+
//
|
|
554
|
+
// Some components cannot use a build function because they are too early in the
|
|
555
|
+
// boot process, but we still need a component. We look for NaanBuildComponent
|
|
556
|
+
// to define a dictionary with filename, name and manifest fields. For example,
|
|
557
|
+
// see Util:Module.nlg
|
|
558
|
+
//
|
|
559
|
+
pcomp = penv.evalq(car(compress(NaanBuildComponent)))
|
|
513
560
|
if !pcomp || !fpath.endsWith("/".concat(pcomp.filename))
|
|
514
561
|
return (list("Build cannot package without component in ".concat(fpath), false, annotations, textout))
|
|
515
562
|
}
|
|
516
|
-
package =
|
|
563
|
+
package = util.pkgSave(compress(pcomp.name), pcomp.manifest)
|
|
564
|
+
if string(package)
|
|
565
|
+
return (list("Build cannot generate package for ".concat(fpath), false, annotations, textout))
|
|
517
566
|
}
|
|
518
567
|
} catch {
|
|
519
568
|
if true
|
|
520
569
|
return (list("Packaging exception in ".concat(fpath, ": ", tostring(exception)), false, annotations, textout))
|
|
521
570
|
} finally {
|
|
522
571
|
penv.destroy() // remove the namespace
|
|
523
|
-
debuglog("parseAndPack1 done", fpath)
|
|
524
572
|
}
|
|
525
573
|
if options.naanpack
|
|
526
574
|
package = (js.w||js.s||js.g).JSON.stringify(package) // doesn't have frameworks/common available
|
|
@@ -546,7 +594,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
546
594
|
build.parallel = ExecutorParallel(track, { // create worker pool
|
|
547
595
|
basename: "build"
|
|
548
596
|
initeval: `(false, (parseAndPack1))
|
|
549
|
-
})
|
|
597
|
+
})
|
|
550
598
|
result = build.parallel.rpc(parseAndPack1, list(text, fpath, options, operation))
|
|
551
599
|
if !result.0 {
|
|
552
600
|
result = result.1 // unpeel RPC result
|
|
@@ -1004,9 +1052,9 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1004
1052
|
}
|
|
1005
1053
|
else if ((`(error, content) = fs.readFile(entry.readpath, readOptions)) && !error) {
|
|
1006
1054
|
if entry.license
|
|
1007
|
-
`(content) = applySubstitutions(content, licFileDefs)
|
|
1055
|
+
`(content) = applySubstitutions(content, licFileDefs, true)
|
|
1008
1056
|
if entry.version
|
|
1009
|
-
`(content) = applySubstitutions(content, verFileDefs)
|
|
1057
|
+
`(content) = applySubstitutions(content, verFileDefs, true)
|
|
1010
1058
|
if entry.naanpack
|
|
1011
1059
|
`(error, content) = parseAndPack(content, entry.readpath, { naanpack: true })
|
|
1012
1060
|
else if entry.jspack
|
|
@@ -1211,17 +1259,20 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1211
1259
|
//
|
|
1212
1260
|
// Run the current build product by spawning a new worker.
|
|
1213
1261
|
//
|
|
1214
|
-
build.runSpawn = function runSpawn(
|
|
1262
|
+
build.runSpawn = function runSpawn(stage,
|
|
1263
|
+
local error, maintext, executor, vpath, site, dirpath) {
|
|
1215
1264
|
`(error, maintext) = fs.readFile(JSpath.join(build.destpath, build.runway.main))
|
|
1216
1265
|
if error
|
|
1217
1266
|
error = Error("Builder: cannot read main file", error)
|
|
1218
1267
|
else {
|
|
1268
|
+
dirpath = fs.path.resolve("/", fs.rootpath, build.destpath, build.runway.path || "")
|
|
1219
1269
|
`(error, executor) = track.spawn(build.runway.spawn.0, "${rules.name} ${build.version}", {
|
|
1220
1270
|
workerID: "Run-${build.version}+${build.buildnum}"
|
|
1221
1271
|
startup: {
|
|
1222
|
-
|
|
1223
|
-
dirpath:
|
|
1272
|
+
maintext: maintext
|
|
1273
|
+
dirpath: dirpath
|
|
1224
1274
|
}
|
|
1275
|
+
rootPath: dirpath
|
|
1225
1276
|
})
|
|
1226
1277
|
if error
|
|
1227
1278
|
error = Error("Builder: cannot spawn executor instance", error)
|
|
@@ -1249,13 +1300,12 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1249
1300
|
//
|
|
1250
1301
|
// Run the current build product by opening a new window.
|
|
1251
1302
|
//
|
|
1252
|
-
build.runWindow = function runWindow(
|
|
1303
|
+
build.runWindow = function runWindow(stage,
|
|
1253
1304
|
local title, main, url, features, vpath, error, window, site) {
|
|
1254
1305
|
if !js.w
|
|
1255
1306
|
return (list(Error('Run method "window" requires browser host')))
|
|
1256
1307
|
if !build.runway."v-site"
|
|
1257
1308
|
return (list(Error('Run method "window" requires v-site specification')))
|
|
1258
|
-
title = rules.name.concat("-", build.buildnum)
|
|
1259
1309
|
main = build.runway.main
|
|
1260
1310
|
if !main
|
|
1261
1311
|
main = "index.html"
|
|
@@ -1271,6 +1321,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1271
1321
|
if error
|
|
1272
1322
|
return (list(Error("Builder: cannot create virtual site", error)))
|
|
1273
1323
|
sleep(1) // needed on Windows or it won't open, fiik why
|
|
1324
|
+
title = rules.name.concat("-", stage, "-", operation)
|
|
1274
1325
|
window = js.w.open(url, title, features)
|
|
1275
1326
|
list(false, { ok: true }) // we don't know the executor
|
|
1276
1327
|
}
|
|
@@ -1281,13 +1332,13 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1281
1332
|
// Run the current build product, which would be after the make call. Returns a standard result
|
|
1282
1333
|
// tuple.
|
|
1283
1334
|
//
|
|
1284
|
-
build.run = function run() {
|
|
1335
|
+
build.run = function run(stage) {
|
|
1285
1336
|
if build.runway.open
|
|
1286
1337
|
fs.shellOpen(JSpath.join(build.destpath, build.runway.open), build.runway.args)
|
|
1287
1338
|
else if build.runway.spawn
|
|
1288
|
-
build.runSpawn()
|
|
1339
|
+
build.runSpawn(stage)
|
|
1289
1340
|
else if build.runway.window
|
|
1290
|
-
build.runWindow()
|
|
1341
|
+
build.runWindow(stage)
|
|
1291
1342
|
else
|
|
1292
1343
|
list(false, { ok: true })
|
|
1293
1344
|
}
|
|
@@ -296,7 +296,7 @@ closure projConnector(projman, projtype, local connector, watch) {
|
|
|
296
296
|
*
|
|
297
297
|
* Nide.proj/
|
|
298
298
|
* nide_cliser.cfg - JSON definition of the project (see below)
|
|
299
|
-
* NaanIDE_version.txt - [default] substitution file defining 1.
|
|
299
|
+
* NaanIDE_version.txt - [default] substitution file defining 1.7.1+1 etc.
|
|
300
300
|
* NaanIDE_version_builds.txt - [default] contains current build number as decimal string
|
|
301
301
|
* build/ - [optional] default build output location
|
|
302
302
|
* NaanIDE.lic - [optional] defines Zulch Laboratories, Inc. and other license info
|
|
@@ -646,7 +646,7 @@ closure projConfig(projman, where, projID, local procon, fs, configpath) {
|
|
|
646
646
|
if builder.refresh()
|
|
647
647
|
buildonly = !buildonly // reverse if refresh
|
|
648
648
|
if !buildonly
|
|
649
|
-
`(error) = builder.run()
|
|
649
|
+
`(error) = builder.run(stage)
|
|
650
650
|
}
|
|
651
651
|
builder.destroy()
|
|
652
652
|
procon.builder = false
|
|
@@ -19,9 +19,6 @@
|
|
|
19
19
|
|
|
20
20
|
closure DebugCommand(executor, notify, local decom, excon) {
|
|
21
21
|
decom = new(object, this)
|
|
22
|
-
executor.DebugCmd({
|
|
23
|
-
op: "attach"
|
|
24
|
-
})
|
|
25
22
|
decom.executor = executor
|
|
26
23
|
|
|
27
24
|
// debugData
|
|
@@ -96,6 +93,24 @@ closure DebugCommand(executor, notify, local decom, excon) {
|
|
|
96
93
|
status
|
|
97
94
|
}
|
|
98
95
|
|
|
96
|
+
// query
|
|
97
|
+
// Send a status update back.
|
|
98
|
+
//
|
|
99
|
+
decom.query = function query() {
|
|
100
|
+
decom.executor.DebugCmd({
|
|
101
|
+
op: "query"
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// attach
|
|
106
|
+
// Attach our GUI to the low-level debugger
|
|
107
|
+
//
|
|
108
|
+
decom.attach = function attach() {
|
|
109
|
+
executor.DebugCmd({
|
|
110
|
+
op: "attach"
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
99
114
|
//
|
|
100
115
|
// Run control.
|
|
101
116
|
//
|
|
@@ -138,6 +153,8 @@ closure DebugCommand(executor, notify, local decom, excon) {
|
|
|
138
153
|
notify.runState(debugStatus())
|
|
139
154
|
}
|
|
140
155
|
|
|
156
|
+
attach()
|
|
157
|
+
|
|
141
158
|
// finis
|
|
142
159
|
|
|
143
160
|
decom
|
|
@@ -35,6 +35,7 @@ closure DebugNub(local nub, debug, paused) {
|
|
|
35
35
|
nub.watches = []
|
|
36
36
|
nub.stacks = { }
|
|
37
37
|
nub.usage = { }
|
|
38
|
+
paused = { }
|
|
38
39
|
|
|
39
40
|
// debugDepth
|
|
40
41
|
// Return the recursive debugging depth as an integer.
|
|
@@ -45,6 +46,18 @@ closure DebugNub(local nub, debug, paused) {
|
|
|
45
46
|
curdepth = 0
|
|
46
47
|
curdepth
|
|
47
48
|
}
|
|
49
|
+
|
|
50
|
+
// sendStatus
|
|
51
|
+
// Send current status to the far end.
|
|
52
|
+
//
|
|
53
|
+
function sendStatus() {
|
|
54
|
+
js.t.ReplyDebugger({
|
|
55
|
+
op: "status"
|
|
56
|
+
depth: debugDepth()
|
|
57
|
+
bpenable: debug.bpenable
|
|
58
|
+
exenable: nub.exenable
|
|
59
|
+
})
|
|
60
|
+
}
|
|
48
61
|
|
|
49
62
|
// onDebugger proc
|
|
50
63
|
// Process an incoming debugger command.
|
|
@@ -52,17 +65,13 @@ closure DebugNub(local nub, debug, paused) {
|
|
|
52
65
|
function onDebugger(msg) {
|
|
53
66
|
if msg.op == "attach" {
|
|
54
67
|
debug.setCommander(nub)
|
|
55
|
-
|
|
56
|
-
op: "status"
|
|
57
|
-
depth: debugDepth()
|
|
58
|
-
bpenable: debug.bpenable
|
|
59
|
-
exenable: nub.exenable
|
|
60
|
-
})
|
|
68
|
+
sendStatus()
|
|
61
69
|
}
|
|
62
70
|
else if msg.op == "detach" {
|
|
63
71
|
debug.setCommander(false)
|
|
64
72
|
paused.wait = false // false: go back to ndb
|
|
65
|
-
}
|
|
73
|
+
} else if msg.op == "query"
|
|
74
|
+
sendStatus()
|
|
66
75
|
else if msg.op == "pause"
|
|
67
76
|
debugger()
|
|
68
77
|
else if msg.op == "resume" || msg.op == "stop"
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* column positioning: // // !
|
|
7
7
|
*
|
|
8
|
-
* Copyright (c) 2020-
|
|
8
|
+
* Copyright (c) 2020-2026 by Richard C. Zulch
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
11
11
|
|
|
@@ -23,13 +23,21 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
23
23
|
exec.type = type
|
|
24
24
|
exec.name = name
|
|
25
25
|
exec.contexts = { }
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
// execReset
|
|
28
28
|
//
|
|
29
29
|
// Initialize remote communications for a new or restarted instance.
|
|
30
30
|
//
|
|
31
|
-
exec.execReset = function execReset() {
|
|
31
|
+
exec.execReset = function execReset(error, local xid, pending) {
|
|
32
|
+
if !error
|
|
33
|
+
error = Error("execReset")
|
|
34
|
+
for `(xid, pending) in exec.pending {
|
|
35
|
+
pending.signal(list(error))
|
|
36
|
+
exec.pending[xid] = undefined
|
|
37
|
+
}
|
|
32
38
|
exec.pending = { }
|
|
39
|
+
exec.inst_ready = false
|
|
40
|
+
exec.inst_error = undefined
|
|
33
41
|
exec.nextSendID = toint(RandomBytes(3)) // keep our sequence code unique for shared servers
|
|
34
42
|
}
|
|
35
43
|
execReset()
|
|
@@ -52,7 +60,7 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
52
60
|
pending.signal(Error("execSend failed", error))
|
|
53
61
|
pending
|
|
54
62
|
}
|
|
55
|
-
|
|
63
|
+
|
|
56
64
|
// execReceived
|
|
57
65
|
//
|
|
58
66
|
// The specified message was received from the instance, so signal it.
|
|
@@ -65,7 +73,7 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
65
73
|
exec.reverseDispatch = require("./taskexec.nlg").TaskDispatcher(function(data) {
|
|
66
74
|
data.reverse = true
|
|
67
75
|
exec.PostMessage(data)
|
|
68
|
-
}, exec.contexts[data.contextID].coder)
|
|
76
|
+
}, exec.contexts[data.contextID].coder, "execReceived")
|
|
69
77
|
data.reverse = false
|
|
70
78
|
exec.reverseDispatch(data)
|
|
71
79
|
return
|
|
@@ -73,7 +81,7 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
73
81
|
pending = exec.pending[data.xid]
|
|
74
82
|
if !pending { // not waiting on message
|
|
75
83
|
if data.xmsg == "xready"
|
|
76
|
-
exec.
|
|
84
|
+
exec.inst_ready = true
|
|
77
85
|
if data.xmsg == "xattention"
|
|
78
86
|
{ }
|
|
79
87
|
return
|
|
@@ -81,7 +89,7 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
81
89
|
exec.pending[data.xid] = undefined
|
|
82
90
|
pending.signal(list(false, data))
|
|
83
91
|
}
|
|
84
|
-
|
|
92
|
+
|
|
85
93
|
// execSetStatus
|
|
86
94
|
//
|
|
87
95
|
// Received a status update from the instance. This makes a copy of the specified dictionary for
|
|
@@ -93,29 +101,25 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
93
101
|
exec.execSetStatus = function execSetStatus(status) {
|
|
94
102
|
exec.xstatus = new(status) // for GC (!)
|
|
95
103
|
}
|
|
96
|
-
|
|
104
|
+
|
|
97
105
|
// execFailed
|
|
98
106
|
//
|
|
99
107
|
// Communication has failed.
|
|
100
108
|
//
|
|
101
109
|
exec.execFailed = closure execFailed(error, local xid, pending) {
|
|
102
|
-
exec.
|
|
110
|
+
exec.inst_error = error
|
|
103
111
|
for `(xid, pending) in exec.pending
|
|
104
112
|
pending.signal(list(error))
|
|
105
113
|
}
|
|
106
|
-
|
|
114
|
+
|
|
107
115
|
// execClosed
|
|
108
116
|
//
|
|
109
|
-
//
|
|
110
117
|
// Note that the connection has closed, so signal all the waiters.
|
|
111
118
|
//
|
|
112
|
-
exec.execClosed = closure execClosed(error
|
|
113
|
-
|
|
114
|
-
pending.signal(list(error))
|
|
115
|
-
pending[xid] = undefined
|
|
116
|
-
}
|
|
119
|
+
exec.execClosed = closure execClosed(error) {
|
|
120
|
+
execReset(error)
|
|
117
121
|
}
|
|
118
|
-
|
|
122
|
+
|
|
119
123
|
// context
|
|
120
124
|
//
|
|
121
125
|
// Return a context object for the instance, or an error, in a result tuple. The optional state
|
|
@@ -127,7 +131,7 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
127
131
|
retries = 0
|
|
128
132
|
ms = milliseconds()
|
|
129
133
|
delta = 1
|
|
130
|
-
while !exec.
|
|
134
|
+
while !exec.inst_ready {
|
|
131
135
|
`(error) = exec.PostMessage({
|
|
132
136
|
xmsg: "xstart"
|
|
133
137
|
})
|
|
@@ -135,8 +139,8 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
135
139
|
return (Error("exec.context failed", error))
|
|
136
140
|
if ++retries > 100
|
|
137
141
|
return (list(Error("timeout creating remote context", type, name)))
|
|
138
|
-
if exec.
|
|
139
|
-
return (list(Error("cannot create remote context", exec.
|
|
142
|
+
if exec.inst_error
|
|
143
|
+
return (list(Error("cannot create remote context", exec.inst_error)))
|
|
140
144
|
sleep(delta)
|
|
141
145
|
if delta < 100
|
|
142
146
|
delta *= 2 }
|
|
@@ -157,7 +161,7 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
157
161
|
exec.attention = function attention() {
|
|
158
162
|
track.attention(exec)
|
|
159
163
|
}
|
|
160
|
-
|
|
164
|
+
|
|
161
165
|
// finis
|
|
162
166
|
exec
|
|
163
167
|
};
|
|
@@ -220,6 +224,8 @@ closure ExecutorContext(exec, state, coder, local context, util) {
|
|
|
220
224
|
// an optional tuple of symbols to retrieve after evaluation.
|
|
221
225
|
//
|
|
222
226
|
context.eval = closure evalf(expr, put, get, local roots, pkg, data, pending, result) {
|
|
227
|
+
if !exec.inst_ready
|
|
228
|
+
return (list(Error("execution context closed")))
|
|
223
229
|
if tuple(put)
|
|
224
230
|
roots = cons(`expr, put)
|
|
225
231
|
else
|
|
@@ -288,6 +294,8 @@ closure ExecutorContext(exec, state, coder, local context, util) {
|
|
|
288
294
|
// The procedure must be specified as a symbol or string.
|
|
289
295
|
//
|
|
290
296
|
context.rpc = closure rpc(proc, args, local data, pending, result) {
|
|
297
|
+
if !exec.inst_ready
|
|
298
|
+
return (list(Error("execution context closed")))
|
|
291
299
|
data = {
|
|
292
300
|
contextID: state.contextID
|
|
293
301
|
proc: proc
|
|
@@ -566,13 +574,13 @@ closure ExecutorParallel(track, options, local maxcount, parallel, state, exqueu
|
|
|
566
574
|
return (false) // already destroyed
|
|
567
575
|
crValue = cancelResult
|
|
568
576
|
maxcount = 0
|
|
569
|
-
state.available = false
|
|
570
|
-
parallel.contexts = false
|
|
571
577
|
while state.workers.length > 0 {
|
|
572
578
|
worker = state.workers.pop()
|
|
573
579
|
parallel.contexts[worker] = false
|
|
574
580
|
worker.destroy()
|
|
575
581
|
}
|
|
582
|
+
state.available = false
|
|
583
|
+
parallel.contexts = false
|
|
576
584
|
while exqueue.length > 0 {
|
|
577
585
|
next = exqueue.pop()
|
|
578
586
|
next.pending.signal(crValue)
|
|
@@ -604,12 +612,14 @@ closure ExecutorTracker(local xtrak) {
|
|
|
604
612
|
// Notify the watchers by calling a named procedure
|
|
605
613
|
|
|
606
614
|
closure notify(changes, local watch) {
|
|
607
|
-
|
|
608
|
-
|
|
615
|
+
future(function(){
|
|
616
|
+
for watch in xtrak.watchers
|
|
617
|
+
call(watch, changes)
|
|
618
|
+
}, 10)
|
|
609
619
|
}
|
|
610
620
|
|
|
611
621
|
// add
|
|
612
|
-
// Add an execution instance
|
|
622
|
+
// Add an execution instance.
|
|
613
623
|
|
|
614
624
|
xtrak.add = closure add(executor, local instance) {
|
|
615
625
|
instance = new(nonce)
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
closure InTop(track, options, local intop, nlregex, str, error) {
|
|
42
42
|
global(App)
|
|
43
43
|
intop = ExecutorBase(track, options.type, options.name)
|
|
44
|
+
intop.verbose = false
|
|
44
45
|
intop.workerID = options.workerID || undefined
|
|
45
46
|
intop.msgQueue = []
|
|
46
47
|
nlregex = RegExp("\\n", "g")
|
|
@@ -101,7 +102,7 @@ closure InTop(track, options, local intop, nlregex, str, error) {
|
|
|
101
102
|
// Received an unknown destination notice from the other side.
|
|
102
103
|
//
|
|
103
104
|
intop.impUnknown = function impUnknown(unknownID, sourceID, gateway) {
|
|
104
|
-
if !gateway
|
|
105
|
+
if !gateway && intop.verbose
|
|
105
106
|
debuglog("InTop.impUnknownID:", unknownID, "sourceID:", sourceID)
|
|
106
107
|
}
|
|
107
108
|
|
|
@@ -263,8 +264,12 @@ closure InTop(track, options, local intop, nlregex, str, error) {
|
|
|
263
264
|
// A terminal was attached.
|
|
264
265
|
//
|
|
265
266
|
intop.termAttach = function termAttach(repl, db, notify, local msg) {
|
|
267
|
+
if !repl {
|
|
268
|
+
debuglog("termAttach false repl")
|
|
269
|
+
return (false)
|
|
270
|
+
}
|
|
266
271
|
if !intop.msgQueue
|
|
267
|
-
return (
|
|
272
|
+
return (intop) // already attached
|
|
268
273
|
intop.sender(intop.botDestID, {
|
|
269
274
|
id: "attached",
|
|
270
275
|
guid: intop.instanceID
|
|
@@ -294,7 +299,7 @@ closure InTop(track, options, local intop, nlregex, str, error) {
|
|
|
294
299
|
//
|
|
295
300
|
intop.termDetach = function termDetach() {
|
|
296
301
|
if intop.msgQueue
|
|
297
|
-
return
|
|
302
|
+
return // already detached
|
|
298
303
|
intop.term.SetNotify()
|
|
299
304
|
intop.msgQueue = []
|
|
300
305
|
intop.debugger.detach(intop)
|
|
@@ -310,19 +315,17 @@ closure InTop(track, options, local intop, nlregex, str, error) {
|
|
|
310
315
|
|
|
311
316
|
// close
|
|
312
317
|
//
|
|
313
|
-
// Close our access to the worker.
|
|
318
|
+
// Close our access to the worker, but it can be reopened.
|
|
314
319
|
//
|
|
315
320
|
intop.close = function close() {
|
|
316
|
-
if !intop.
|
|
321
|
+
if !intop.botDestID
|
|
317
322
|
return
|
|
318
323
|
intop.sender(intop.botDestID, {
|
|
319
324
|
id: "unsubscribe"
|
|
320
325
|
})
|
|
321
|
-
intop.
|
|
322
|
-
track.delete(intop)
|
|
323
|
-
termDetach()
|
|
326
|
+
intop.botDestID = false
|
|
324
327
|
App.imp.unregister(intop.instanceID)
|
|
325
|
-
intop.
|
|
328
|
+
intop.sender = false
|
|
326
329
|
}
|
|
327
330
|
|
|
328
331
|
// destroy
|
|
@@ -333,11 +336,17 @@ closure InTop(track, options, local intop, nlregex, str, error) {
|
|
|
333
336
|
if intop.destroyed
|
|
334
337
|
return
|
|
335
338
|
intop.destroyed = true
|
|
339
|
+
intop.execClosed(Error("instance closed"))
|
|
336
340
|
intop.sender(intop.botDestID, {
|
|
337
341
|
id: "destroy",
|
|
338
342
|
guid: intop.instanceID
|
|
339
343
|
})
|
|
340
|
-
|
|
344
|
+
track.delete(intop)
|
|
345
|
+
termDetach()
|
|
346
|
+
sleep(10)
|
|
347
|
+
App.imp.unregister(intop.instanceID)
|
|
348
|
+
intop.sender = false
|
|
349
|
+
intop.cleanup() // child classes release resources
|
|
341
350
|
}
|
|
342
351
|
|
|
343
352
|
// open
|
|
@@ -347,24 +356,27 @@ closure InTop(track, options, local intop, nlregex, str, error) {
|
|
|
347
356
|
intop.open = closure open(inbotID) {
|
|
348
357
|
if intop.destroyed
|
|
349
358
|
return (list(Error("InTop already destroyed")))
|
|
350
|
-
if intop.
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
intop.instanceID = UUID()
|
|
359
|
+
if intop.botDestID == inbotID
|
|
360
|
+
return (list(false, { reopen: true }))
|
|
361
|
+
if intop.botDestID
|
|
362
|
+
close()
|
|
355
363
|
intop.botDestID = inbotID
|
|
356
|
-
intop.
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
364
|
+
if !intop.instanceID {
|
|
365
|
+
intop.instanceID = App.imp.getUUID("InTop(${options.name}) instanceID")
|
|
366
|
+
track.add(intop)
|
|
367
|
+
}
|
|
368
|
+
if !intop.sender
|
|
369
|
+
intop.sender = App.imp.register(intop, {
|
|
370
|
+
name: options.name
|
|
371
|
+
type: options.type
|
|
372
|
+
instanceID: intop.instanceID
|
|
373
|
+
services: [ "naan-executor" ]
|
|
374
|
+
})
|
|
362
375
|
`(error) = intop.sender(intop.botDestID, {
|
|
363
376
|
id: "subscribe"
|
|
364
377
|
})
|
|
365
378
|
if error
|
|
366
379
|
return(list(error))
|
|
367
|
-
track.add(intop)
|
|
368
380
|
list(false, { ok: true })
|
|
369
381
|
}
|
|
370
382
|
|