@naanlang/naan 1.3.1 → 1.4.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 +3 -3
- package/bin/index.js +2 -2
- package/dist/naan.min.js +4 -4
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +26 -11
- package/frameworks/browser/workers.nlg +3 -0
- package/frameworks/browser/ws_client.nlg +1 -1
- package/frameworks/client/psm_client.nlg +1 -1
- package/frameworks/client/relaycon.nlg +2 -1
- package/frameworks/common/common.nlg +6 -10
- package/frameworks/common/preferences.nlg +1 -1
- package/frameworks/node/apiserver.nlg +3 -3
- package/frameworks/node/https_request.nlg +97 -12
- package/frameworks/node/node.nlg +1 -0
- package/frameworks/node/worker.nlg +103 -45
- package/frameworks/project/build.nlg +12 -7
- package/frameworks/project/jszip.js +0 -0
- package/frameworks/project/projects.nlg +7 -3
- package/frameworks/running/executors.nlg +64 -28
- package/frameworks/running/running.nlg +85 -3
- package/frameworks/running/taskexec.nlg +24 -4
- package/frameworks/storage/dbt_pouch.nlg +1 -1
- package/frameworks/storage/psm.nlg +11 -1
- package/lib/browser/env_web.js +6 -6
- package/lib/browser/env_webworker.js +2 -0
- package/lib/core/naanlib.js +4 -4
- package/lib/env_nodeworker.js +2 -0
- package/package.json +1 -1
- package/plugins/gitClient/gitutils.nlg +2 -2
- package/plugins/nodeLib/node_https.nlg +2 -2
- package/plugins/serviceAws/dbt_aws.nlg +3 -0
- package/plugins/serviceAws/lambda_naan_control.nlg +3 -3
- package/plugins/serviceGC/gc_api.nlg +263 -0
- package/plugins/serviceGC/russian_trusted_root_ca_pem.crt +33 -0
- package/plugins/serviceGC/serviceGC.nlg +31 -0
- package/plugins/serviceGitHub/gitops.nlg +4 -3
- package/plugins/serviceGitHub/psm_github.nlg +1 -1
- package/plugins/serviceGitLab/gitops.nlg +2 -1
- package/plugins/serviceGitLab/psm_gitlab.nlg +1 -1
- package/plugins/serviceYC/yc_speechrec.nlg +138 -0
- package/plugins/serviceYC/yc_vm.nlg +1 -1
- package/test/test_02_context.nlg +1 -1
- package/test/test_07_lingo.nlg +3 -3
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
/*
|
|
14
|
+
* globals
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
gWorkers;
|
|
19
|
+
|
|
13
20
|
|
|
14
21
|
/*
|
|
15
22
|
* workCurrent
|
|
@@ -19,8 +26,8 @@
|
|
|
19
26
|
*/
|
|
20
27
|
|
|
21
28
|
closure workCurrent(workco, workerID, startup, local current) {
|
|
22
|
-
global()
|
|
23
|
-
current =
|
|
29
|
+
global(js)
|
|
30
|
+
current = require("../running/executors.nlg").ExecutorBase(workco, workerID, startup.name)
|
|
24
31
|
current.workerID = workerID
|
|
25
32
|
current.name = startup.name
|
|
26
33
|
current.links = []
|
|
@@ -94,6 +101,7 @@ closure workCurrent(workco, workerID, startup, local current) {
|
|
|
94
101
|
function ONmessageOut(data) {
|
|
95
102
|
if data._guid
|
|
96
103
|
return // already replied
|
|
104
|
+
current.execReceived(data)
|
|
97
105
|
sendAll({
|
|
98
106
|
id: "targetout",
|
|
99
107
|
data: data
|
|
@@ -153,7 +161,17 @@ closure workCurrent(workco, workerID, startup, local current) {
|
|
|
153
161
|
if current.links.length == 0
|
|
154
162
|
current.host.Detach(current.termif) // attached while one link is active
|
|
155
163
|
}
|
|
156
|
-
|
|
164
|
+
|
|
165
|
+
//
|
|
166
|
+
// target.PostMessage
|
|
167
|
+
//
|
|
168
|
+
// Post a message to the main thread.
|
|
169
|
+
//
|
|
170
|
+
current.PostMessage = function PostMessage(data) {
|
|
171
|
+
js.t.DispatchMessage(data)
|
|
172
|
+
list(false, { posted: true })
|
|
173
|
+
}
|
|
174
|
+
|
|
157
175
|
//
|
|
158
176
|
// msgin
|
|
159
177
|
//
|
|
@@ -188,6 +206,18 @@ closure workCurrent(workco, workerID, startup, local current) {
|
|
|
188
206
|
};
|
|
189
207
|
|
|
190
208
|
|
|
209
|
+
/*
|
|
210
|
+
* WorkerConnect
|
|
211
|
+
*
|
|
212
|
+
* Return the existing web worker for a workerGUID, or false if it does not exist.
|
|
213
|
+
*
|
|
214
|
+
*/
|
|
215
|
+
|
|
216
|
+
function WorkerConnect(workerGUID) {
|
|
217
|
+
gWorkers[workerGUID]
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
191
221
|
/*
|
|
192
222
|
* workMainProxy
|
|
193
223
|
*
|
|
@@ -270,13 +300,14 @@ closure WorkerToMain(local nideRunning, track) {
|
|
|
270
300
|
*
|
|
271
301
|
*/
|
|
272
302
|
|
|
273
|
-
closure workThread(workco, workerID, startup,
|
|
274
|
-
|
|
275
|
-
|
|
303
|
+
closure workThread(workco, workerID, startup, guid
|
|
304
|
+
local worker, options, subChannel, deathWatcher) {
|
|
305
|
+
global(js, threads, JSpath)
|
|
306
|
+
worker = require("../running/executors.nlg").ExecutorBase(workco, workerID, startup.name)
|
|
276
307
|
worker.name = startup.name
|
|
277
308
|
worker.workerID = workerID
|
|
278
309
|
worker.links = []
|
|
279
|
-
worker.guid = UUID()
|
|
310
|
+
worker.guid = guid || UUID()
|
|
280
311
|
|
|
281
312
|
// create our worker thread
|
|
282
313
|
|
|
@@ -346,6 +377,8 @@ closure workThread(workco, workerID, startup, local worker, options, subChannel,
|
|
|
346
377
|
state: false // resume state, if we have any
|
|
347
378
|
altcmd: false
|
|
348
379
|
dirpath: js.d
|
|
380
|
+
workerID: workerID
|
|
381
|
+
workerGUID: worker.guid
|
|
349
382
|
}
|
|
350
383
|
if startup.initcmds
|
|
351
384
|
startmsg.altcmd = startup.initcmds.concat("\n")
|
|
@@ -364,6 +397,8 @@ closure workThread(workco, workerID, startup, local worker, options, subChannel,
|
|
|
364
397
|
else {
|
|
365
398
|
if msg.id == "status"
|
|
366
399
|
worker.lastStatus = milliseconds()
|
|
400
|
+
else if msg.id == "targetout"
|
|
401
|
+
worker.execReceived(msg.data)
|
|
367
402
|
sendAll(msg) } // default is just return message to the client
|
|
368
403
|
})
|
|
369
404
|
|
|
@@ -401,6 +436,19 @@ closure workThread(workco, workerID, startup, local worker, options, subChannel,
|
|
|
401
436
|
removeLink(link)
|
|
402
437
|
}
|
|
403
438
|
|
|
439
|
+
//
|
|
440
|
+
// PostMessage
|
|
441
|
+
//
|
|
442
|
+
// Post a message to the main thread.
|
|
443
|
+
//
|
|
444
|
+
worker.PostMessage = function PostMessage(data) {
|
|
445
|
+
worker.msgport.postMessage({ // send data to worker
|
|
446
|
+
id: "targetin",
|
|
447
|
+
data: data
|
|
448
|
+
})
|
|
449
|
+
list(false, { posted: true })
|
|
450
|
+
}
|
|
451
|
+
|
|
404
452
|
//
|
|
405
453
|
// msgin
|
|
406
454
|
//
|
|
@@ -498,7 +546,7 @@ closure workLink(workco, conn, worker, sender, local link) {
|
|
|
498
546
|
*/
|
|
499
547
|
|
|
500
548
|
closure workController(api, local workco) {
|
|
501
|
-
global()
|
|
549
|
+
global(gWorkers)
|
|
502
550
|
workco = new(object, this)
|
|
503
551
|
workco.serverID = "Workers" // our serverID, used for communications
|
|
504
552
|
workco.workers = { } // dictionary of workers by workerID
|
|
@@ -559,12 +607,47 @@ closure workController(api, local workco) {
|
|
|
559
607
|
workco.workers[workerID] = undefined // it's like this worker has never been
|
|
560
608
|
}
|
|
561
609
|
|
|
562
|
-
//
|
|
610
|
+
// spawn
|
|
611
|
+
//
|
|
612
|
+
// Spawn a new worker with the specified configuration dictionary and optional GUID.
|
|
613
|
+
//
|
|
614
|
+
workco.spawn = closure spawn(workerID, config, guid, local worker) {
|
|
615
|
+
if !dictionary(gWorkers)
|
|
616
|
+
gWorkers = {}
|
|
617
|
+
worker = workco.workers[workerID]
|
|
618
|
+
if !worker { // create worker if needed
|
|
619
|
+
if workerID == "NideServer"
|
|
620
|
+
worker = workco.current = workCurrent(workco, workerID, config)
|
|
621
|
+
else
|
|
622
|
+
worker = workThread(workco, workerID, config, guid)
|
|
623
|
+
workco.uworkers[worker.guid] = worker
|
|
624
|
+
workco.workers[workerID] = worker
|
|
625
|
+
gWorkers[worker.guid] = worker }
|
|
626
|
+
if workerID == "NideServer"
|
|
627
|
+
workco.current.vitalUpdate({
|
|
628
|
+
id: "workerlist", // send the initial list of workers
|
|
629
|
+
workers: let(workers, workerID, worker) {
|
|
630
|
+
workers = { }
|
|
631
|
+
for `(workerID, worker) in workco.workers
|
|
632
|
+
workers[workerID] = {
|
|
633
|
+
name: worker.name
|
|
634
|
+
}
|
|
635
|
+
workers
|
|
636
|
+
}()
|
|
637
|
+
})
|
|
638
|
+
else {
|
|
639
|
+
worker.vitalWatch(termination)
|
|
640
|
+
workco.current.vitalUpdate({
|
|
641
|
+
id: "spawned", // note a new worker thread
|
|
642
|
+
name: config.name
|
|
643
|
+
workerID: workerID
|
|
644
|
+
}) }
|
|
645
|
+
}
|
|
646
|
+
|
|
563
647
|
// wsReceive
|
|
564
648
|
//
|
|
565
649
|
// Process a message from the websocket API.
|
|
566
650
|
//
|
|
567
|
-
|
|
568
651
|
workco.wsReceive = function wsReceive(message, conn, local worker, link, error) {
|
|
569
652
|
if !message.workerID
|
|
570
653
|
error = Error("workerID required", message.workerOp)
|
|
@@ -576,50 +659,25 @@ closure workController(api, local workco) {
|
|
|
576
659
|
if worker && message.payload {
|
|
577
660
|
if !link
|
|
578
661
|
makeLink(message, conn) // make sure we have a link for responses
|
|
579
|
-
worker.msgin(message.payload)
|
|
580
|
-
|
|
662
|
+
worker.msgin(message.payload) } // send message to worker
|
|
663
|
+
return }
|
|
581
664
|
else if message.workerOp == "echo" {
|
|
582
665
|
if worker && message.payload {
|
|
583
666
|
if !link
|
|
584
667
|
makeLink(message, conn) // make sure we have a link for responses
|
|
585
|
-
worker.echo(message.payload, link)
|
|
586
|
-
|
|
668
|
+
worker.echo(message.payload, link) } // echo message to other links
|
|
669
|
+
return }
|
|
587
670
|
else if message.workerOp == "spawn" {
|
|
588
|
-
|
|
589
|
-
if message.workerID == "NideServer"
|
|
590
|
-
worker = workco.current = workCurrent(workco, message.workerID, message.payload)
|
|
591
|
-
else
|
|
592
|
-
worker = workThread(workco, message.workerID, message.payload)
|
|
593
|
-
workco.uworkers[worker.guid] = worker
|
|
594
|
-
workco.workers[message.workerID] = worker }
|
|
671
|
+
spawn(message.workerID, message.payload, message.workerGUID)
|
|
595
672
|
if !link
|
|
596
673
|
makeLink(message, conn) // make sure we have a link for responses
|
|
597
|
-
if message.workerID == "NideServer"
|
|
598
|
-
workco.current.vitalUpdate({
|
|
599
|
-
id: "workerlist", // send the initial list of workers
|
|
600
|
-
workers: let(workers, workerID, worker) {
|
|
601
|
-
workers = { }
|
|
602
|
-
for `(workerID, worker) in workco.workers
|
|
603
|
-
workers[workerID] = {
|
|
604
|
-
name: worker.name
|
|
605
|
-
}
|
|
606
|
-
workers
|
|
607
|
-
}()
|
|
608
|
-
})
|
|
609
|
-
else {
|
|
610
|
-
worker.vitalWatch(termination)
|
|
611
|
-
workco.current.vitalUpdate({
|
|
612
|
-
id: "spawned", // note a new worker thread
|
|
613
|
-
name: message.payload.name
|
|
614
|
-
workerID: message.workerID
|
|
615
|
-
}) }
|
|
616
674
|
return }
|
|
617
675
|
else if message.workerOp == "terminate" {
|
|
618
676
|
if worker {
|
|
619
677
|
if !link
|
|
620
678
|
makeLink(message, conn) // make sure we have a link for responses
|
|
621
|
-
worker.terminate()
|
|
622
|
-
|
|
679
|
+
worker.terminate() } // echo message to other links
|
|
680
|
+
return }
|
|
623
681
|
error = Error("invalid parameters", message.workerOp, message.workerID)
|
|
624
682
|
}
|
|
625
683
|
ErrorDebuglog("workController.wsReceive error:", error)
|
|
@@ -663,13 +721,13 @@ closure workController(api, local workco) {
|
|
|
663
721
|
*/
|
|
664
722
|
|
|
665
723
|
function workInit(local manifest) {
|
|
666
|
-
manifest = `(workCurrent, workMainProxy, WorkerToMain, workThread, workLink,
|
|
667
|
-
workInit)
|
|
668
|
-
|
|
724
|
+
manifest = `(workCurrent, WorkerConnect, workMainProxy, WorkerToMain, workThread, workLink,
|
|
725
|
+
workController, workInit)
|
|
669
726
|
Naan.module.build(module.id, "worker", function(modobj, compobj) {
|
|
670
727
|
require("./node.nlg")
|
|
671
728
|
compobj.manifest = manifest
|
|
672
729
|
modobj.exports.WorkerController = workController
|
|
730
|
+
modobj.exports.WorkerConnect = WorkerConnect
|
|
673
731
|
modobj.exports.WorkerToMain = WorkerToMain
|
|
674
732
|
})
|
|
675
733
|
}();
|
|
@@ -142,8 +142,8 @@
|
|
|
142
142
|
|
|
143
143
|
closure Builder(rules, operation, fs, srcpath, destpath, track, local build, group, newgroup) {
|
|
144
144
|
build = new(object, this)
|
|
145
|
-
build.srcpath = srcpath
|
|
146
|
-
build.destpath = destpath
|
|
145
|
+
build.srcpath = JSpath.normalize(srcpath)
|
|
146
|
+
build.destpath = JSpath.normalize(destpath)
|
|
147
147
|
build.intpath = JSpath.join(destpath, "tmp")
|
|
148
148
|
build.tasks = { // all tasks counter
|
|
149
149
|
copy: 0,
|
|
@@ -694,13 +694,13 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
694
694
|
if !file.info.hidden
|
|
695
695
|
addgroup.sources.push(file.name) // add non-hidden files found in specified directory
|
|
696
696
|
if addgroup.input
|
|
697
|
-
addgroup.input = JSpath.join(addgroup.input, source,
|
|
697
|
+
addgroup.input = JSpath.join(addgroup.input, source, "/")
|
|
698
698
|
else
|
|
699
|
-
addgroup.input =
|
|
699
|
+
addgroup.input = JSpath.join("/")
|
|
700
700
|
if group.destfile
|
|
701
|
-
addgroup.output = JSpath.join(addgroup.output,
|
|
701
|
+
addgroup.output = JSpath.join(addgroup.output, "/")
|
|
702
702
|
else
|
|
703
|
-
addgroup.output = JSpath.join(addgroup.output, source,
|
|
703
|
+
addgroup.output = JSpath.join(addgroup.output, source, "/")
|
|
704
704
|
addgroup.groupno = build.nextgno++ // needed for concat/zip
|
|
705
705
|
groups.push(addgroup)
|
|
706
706
|
}
|
|
@@ -1145,6 +1145,11 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1145
1145
|
build.make = closure make(options, local sink, xchan, entry, outext, error) {
|
|
1146
1146
|
sink = new(textstream, "", `string) // log all output
|
|
1147
1147
|
xchan = textstreams(list(sink, sink))
|
|
1148
|
+
`(error) = fs.mkdir(build.destpath) // make sure our directory exists
|
|
1149
|
+
if error {
|
|
1150
|
+
error = Error("cannot make build products folder", error)
|
|
1151
|
+
return (list(error))
|
|
1152
|
+
}
|
|
1148
1153
|
try {
|
|
1149
1154
|
resetlist()
|
|
1150
1155
|
analyze(options.debugMake)
|
|
@@ -1201,7 +1206,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1201
1206
|
workerID: "Run-${build.buildnum}"
|
|
1202
1207
|
startup: {
|
|
1203
1208
|
initcmds: maintext
|
|
1204
|
-
dirpath: fs.path.resolve(
|
|
1209
|
+
dirpath: fs.path.resolve("/", fs.rootpath, build.destpath)
|
|
1205
1210
|
}
|
|
1206
1211
|
})
|
|
1207
1212
|
if error
|
|
File without changes
|
|
@@ -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.4.0+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
|
|
@@ -574,8 +574,12 @@ closure projConfig(projman, where, projID, local procon, fs, configpath) {
|
|
|
574
574
|
if error
|
|
575
575
|
return (list(error))
|
|
576
576
|
rules = procon.configDict."build-rules"[stage]
|
|
577
|
-
if rules.inherit
|
|
578
|
-
|
|
577
|
+
if rules.inherit {
|
|
578
|
+
data = procon.configDict."build-rules"[rules.inherit]
|
|
579
|
+
if !data
|
|
580
|
+
return (list(Error("build inherit rules '${rules.inherit}' do not exist")))
|
|
581
|
+
rules = merge(data, rules)
|
|
582
|
+
}
|
|
579
583
|
else if !rules
|
|
580
584
|
rules = procon.configDict.build // fallback to old config structure
|
|
581
585
|
rules = new(rules)
|
|
@@ -24,19 +24,20 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
24
24
|
exec.name = name
|
|
25
25
|
|
|
26
26
|
// execReset
|
|
27
|
+
//
|
|
27
28
|
// Initialize remote communications for a new or restarted instance.
|
|
28
|
-
|
|
29
|
+
//
|
|
29
30
|
exec.execReset = function execReset() {
|
|
30
31
|
exec.pending = { }
|
|
31
32
|
exec.nextSendID = toint(RandomBytes(3)) // keep our sequence code unique for shared servers
|
|
32
|
-
exec.nextContextID = 1
|
|
33
33
|
}
|
|
34
34
|
execReset()
|
|
35
35
|
|
|
36
36
|
// execSend
|
|
37
|
+
//
|
|
37
38
|
// Send a message to the running instance and return a nonce to wait on. If data is not a
|
|
38
39
|
// dictionary then it is ignored.
|
|
39
|
-
|
|
40
|
+
//
|
|
40
41
|
exec.execSend = closure execSend(msg, data, local pending, error) {
|
|
41
42
|
if !dictionary(data)
|
|
42
43
|
data = { }
|
|
@@ -52,8 +53,9 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
// execReceived
|
|
56
|
+
//
|
|
55
57
|
// The specified message was received from the instance, so signal it.
|
|
56
|
-
|
|
58
|
+
//
|
|
57
59
|
exec.execReceived = closure execReceived(data, local pending) {
|
|
58
60
|
pending = exec.pending[data.xid]
|
|
59
61
|
if !pending { // not waiting on message
|
|
@@ -68,15 +70,17 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
// execSetStatus
|
|
73
|
+
//
|
|
71
74
|
// Received a status update from the instance.
|
|
72
|
-
|
|
75
|
+
//
|
|
73
76
|
exec.execSetStatus = function execSetStatus(status) {
|
|
74
77
|
exec.xstatus = status
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
// execFailed
|
|
81
|
+
//
|
|
78
82
|
// Communication has failed.
|
|
79
|
-
|
|
83
|
+
//
|
|
80
84
|
exec.execFailed = closure execFailed(error, local xid, pending) {
|
|
81
85
|
exec.pending.error = error
|
|
82
86
|
for `(xid, pending) in exec.pending
|
|
@@ -84,8 +88,10 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
// execClosed
|
|
91
|
+
//
|
|
92
|
+
//
|
|
87
93
|
// Note that the connection has closed, so signal all the waiters.
|
|
88
|
-
|
|
94
|
+
//
|
|
89
95
|
exec.execClosed = closure execClosed(error, local xid, pending) {
|
|
90
96
|
for `(xid, pending) in exec.pending {
|
|
91
97
|
pending.signal(list(error))
|
|
@@ -94,10 +100,13 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
// context
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
103
|
+
//
|
|
104
|
+
// Return a context object for the instance, or an error, in a result tuple. The optional state
|
|
105
|
+
// dictionary argument initializes the context with the state of a previous one to facilitate
|
|
106
|
+
// persistent reconnection. Currently this does not ever reclaim old contexts on the instance
|
|
107
|
+
// end of things, but it should. ###
|
|
108
|
+
//
|
|
109
|
+
exec.context = closure context(state, local error, retries, ms, delta, excon) {
|
|
101
110
|
retries = 0
|
|
102
111
|
ms = milliseconds()
|
|
103
112
|
delta = 1
|
|
@@ -114,13 +123,14 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
114
123
|
sleep(delta)
|
|
115
124
|
if delta < 100
|
|
116
125
|
delta *= 2 }
|
|
117
|
-
excon = ExecutorContext(exec,
|
|
126
|
+
excon = ExecutorContext(exec, state)
|
|
118
127
|
excon.register()
|
|
119
128
|
}
|
|
120
129
|
|
|
121
130
|
// attention
|
|
131
|
+
//
|
|
122
132
|
// Focus the UI on this instance because something needs attention.
|
|
123
|
-
|
|
133
|
+
//
|
|
124
134
|
exec.attention = function attention() {
|
|
125
135
|
track.attention(exec)
|
|
126
136
|
}
|
|
@@ -141,20 +151,37 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
141
151
|
* ability to track namespace changes as the result of evaluating an expression. They do not override
|
|
142
152
|
* normal namespace protections. The contexts exposed here preserve the active namespace after the
|
|
143
153
|
* expression is evaluated.
|
|
154
|
+
* The optional state argument preserves the context state so that it can be restored for
|
|
155
|
+
* resuming persistent connections.
|
|
144
156
|
*
|
|
145
157
|
*/
|
|
146
158
|
|
|
147
|
-
closure ExecutorContext(exec,
|
|
159
|
+
closure ExecutorContext(exec, state, local context, coder, util) {
|
|
148
160
|
global(apply)
|
|
149
161
|
context = new(object, this)
|
|
162
|
+
if !state || !state.contextID
|
|
163
|
+
state = {
|
|
164
|
+
contextID: UUID()
|
|
165
|
+
}
|
|
166
|
+
context.state = state
|
|
167
|
+
coder = packageCoder(evalf)
|
|
150
168
|
util = modlist().Util.exports
|
|
151
169
|
|
|
170
|
+
// getState
|
|
171
|
+
//
|
|
172
|
+
// Get context state for future initialization
|
|
173
|
+
//
|
|
174
|
+
context.getState = function getState() {
|
|
175
|
+
context.state
|
|
176
|
+
}
|
|
177
|
+
|
|
152
178
|
// register
|
|
179
|
+
//
|
|
153
180
|
// Register or re-register our context with the worker.
|
|
154
|
-
|
|
181
|
+
//
|
|
155
182
|
context.register = closure register(local pending, result) {
|
|
156
183
|
pending = exec.execSend("register", {
|
|
157
|
-
contextID: contextID
|
|
184
|
+
contextID: state.contextID
|
|
158
185
|
})
|
|
159
186
|
result = pending.wait()
|
|
160
187
|
if result.1
|
|
@@ -164,10 +191,11 @@ closure ExecutorContext(exec, contextID, local context, util) {
|
|
|
164
191
|
}
|
|
165
192
|
|
|
166
193
|
// eval
|
|
194
|
+
//
|
|
167
195
|
// Evaluate the specified expression in the current worker context. The optional put argument
|
|
168
196
|
// if non-false is a tuple of symbols that should be transfered to the remote end, while get is
|
|
169
197
|
// an optional tuple of symbols to retrieve after evaluation.
|
|
170
|
-
|
|
198
|
+
//
|
|
171
199
|
context.eval = closure evalf(expr, put, get, local roots, pkg, data, pending, result) {
|
|
172
200
|
if tuple(put)
|
|
173
201
|
roots = cons(`expr, put)
|
|
@@ -175,9 +203,11 @@ closure ExecutorContext(exec, contextID, local context, util) {
|
|
|
175
203
|
roots = `(expr)
|
|
176
204
|
pkg = util.pkgSave(`expr, roots, {
|
|
177
205
|
nsignore: true
|
|
178
|
-
comments: true
|
|
206
|
+
comments: true
|
|
207
|
+
objectEncoder: coder.encodeObject
|
|
208
|
+
})
|
|
179
209
|
data = {
|
|
180
|
-
contextID: contextID
|
|
210
|
+
contextID: state.contextID
|
|
181
211
|
expr: pkg }
|
|
182
212
|
if tuple(get)
|
|
183
213
|
data.get = get
|
|
@@ -190,22 +220,25 @@ closure ExecutorContext(exec, contextID, local context, util) {
|
|
|
190
220
|
localroots: false
|
|
191
221
|
intern: false
|
|
192
222
|
execute: false
|
|
223
|
+
objectDecoder: coder.decodeObject
|
|
193
224
|
})))
|
|
194
225
|
else
|
|
195
226
|
result
|
|
196
227
|
}
|
|
197
|
-
|
|
228
|
+
|
|
198
229
|
// evalq
|
|
230
|
+
//
|
|
199
231
|
// Evaluate the specified QUOTED expression in the current worker context.
|
|
200
|
-
|
|
232
|
+
//
|
|
201
233
|
context.evalq = macro evalq(expr, put, get) {
|
|
202
234
|
evalf(expr, eval(put), eval(get))
|
|
203
235
|
}
|
|
204
|
-
|
|
236
|
+
|
|
205
237
|
// apply
|
|
238
|
+
//
|
|
206
239
|
// Apply list of arguments to the specified procure evaluated remotely. If the procedure is a
|
|
207
240
|
// not a tuple then this uses the tuple definition if there is one.
|
|
208
|
-
|
|
241
|
+
//
|
|
209
242
|
context.apply = closure applyf(proc, args, put, get) {
|
|
210
243
|
if !tuple(proc) && tuple(proc.proc)
|
|
211
244
|
proc = proc.proc
|
|
@@ -213,9 +246,10 @@ closure ExecutorContext(exec, contextID, local context, util) {
|
|
|
213
246
|
}
|
|
214
247
|
|
|
215
248
|
// call
|
|
249
|
+
//
|
|
216
250
|
// Call the specified function remotely using local arguments:
|
|
217
251
|
// context.call(proc, args...)
|
|
218
|
-
|
|
252
|
+
//
|
|
219
253
|
context.call = macro callf args {
|
|
220
254
|
closure (proc, arglist, local eargs) {
|
|
221
255
|
while arglist
|
|
@@ -225,13 +259,14 @@ closure ExecutorContext(exec, contextID, local context, util) {
|
|
|
225
259
|
}
|
|
226
260
|
|
|
227
261
|
// rpc
|
|
262
|
+
//
|
|
228
263
|
// Execute a remote procedure call without package translation, to reduce overhead. This will not
|
|
229
264
|
// properly transfer Naan-specific types like symbols, and the results will be native JavaScript.
|
|
230
265
|
// The procedure must be specified as a symbol or string.
|
|
231
|
-
|
|
266
|
+
//
|
|
232
267
|
context.rpc = closure rpc(proc, args, local data, pending, result) {
|
|
233
268
|
data = {
|
|
234
|
-
contextID: contextID
|
|
269
|
+
contextID: state.contextID
|
|
235
270
|
proc: proc
|
|
236
271
|
args: args }
|
|
237
272
|
pending = exec.execSend("rpc", data)
|
|
@@ -647,7 +682,7 @@ closure ExecutorTracker(local xtrak) {
|
|
|
647
682
|
*/
|
|
648
683
|
|
|
649
684
|
closure execLambda(track, url, name, workerID, local target, nlregex, clientID, serverID) {
|
|
650
|
-
global()
|
|
685
|
+
global(js)
|
|
651
686
|
target = ExecutorBase(track, "Lambda", name)
|
|
652
687
|
clientID = "DebugWorkers"
|
|
653
688
|
serverID = "Workers"
|
|
@@ -896,7 +931,8 @@ closure execLambda(track, url, name, workerID, local target, nlregex, clientID,
|
|
|
896
931
|
*/
|
|
897
932
|
|
|
898
933
|
function execInit(local manifest) {
|
|
899
|
-
manifest = `(ExecutorBase, ExecutorContext, ExecutorParallel, ExecutorTracker, execLambda,
|
|
934
|
+
manifest = `(ExecutorBase, ExecutorContext, ExecutorParallel, ExecutorTracker, execLambda,
|
|
935
|
+
execInit)
|
|
900
936
|
|
|
901
937
|
Naan.module.build(module.id, "executors", function(modobj, compobj) {
|
|
902
938
|
require("./running.nlg")
|