@naanlang/naan 1.2.0 → 1.2.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/naan.min.js +4 -4
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +14 -4
- package/frameworks/browser/ws_client.nlg +6 -2
- package/frameworks/client/psm_client.nlg +4 -4
- package/frameworks/client/relaycon.nlg +2 -0
- package/frameworks/common/common.nlg +10 -4
- package/frameworks/node/ws_client.nlg +7 -2
- package/frameworks/project/build.nlg +10 -10
- package/frameworks/project/projects.nlg +7 -5
- package/frameworks/running/executors.nlg +121 -33
- package/lib/browser/env_web.js +6 -6
- package/lib/core/naanlib.js +4 -4
- package/package.json +1 -1
- package/plugins/serviceAws/dbt_aws.nlg +1 -1
- package/test/test_02_context.nlg +1 -1
- package/test/test_03_jsinterop.nlg +2 -2
- package/test/test_05_strings.nlg +7 -4
|
@@ -52,7 +52,7 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// execReceived
|
|
55
|
-
//
|
|
55
|
+
// The specified message was received from the instance, so signal it.
|
|
56
56
|
|
|
57
57
|
exec.execReceived = closure execReceived(data, local pending) {
|
|
58
58
|
pending = exec.pending[data.xid]
|
|
@@ -65,6 +65,13 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
65
65
|
pending.signal(list(false, data))
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
// execSetStatus
|
|
69
|
+
// Received a status update from the instance.
|
|
70
|
+
|
|
71
|
+
exec.execSetStatus = function execSetStatus(status) {
|
|
72
|
+
exec.xstatus = status
|
|
73
|
+
}
|
|
74
|
+
|
|
68
75
|
// execFailed
|
|
69
76
|
// Communication has failed.
|
|
70
77
|
|
|
@@ -263,21 +270,22 @@ closure ExecutorContext(exec, contextID, local context, util) {
|
|
|
263
270
|
*
|
|
264
271
|
* Allowable options are:
|
|
265
272
|
* {
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
273
|
+
* spawnLoc: <string> // e.g. "Local" (default) or "Host"
|
|
274
|
+
* maxcount: <integer> // maximum workers, default 4
|
|
275
|
+
* initeval: `(<expr>, <put>, <get>) // initializes each new worker
|
|
276
|
+
* basename: <string> // worker label for UI, default "batch"
|
|
269
277
|
* }
|
|
270
278
|
*
|
|
271
279
|
*/
|
|
272
280
|
|
|
273
|
-
closure ExecutorParallel(options, local maxcount,
|
|
281
|
+
closure ExecutorParallel(track, options, local maxcount, parallel, exqueue, crValue) {
|
|
274
282
|
global()
|
|
283
|
+
options = merge({
|
|
284
|
+
spawnLoc: "Local"
|
|
285
|
+
maxcount: 4
|
|
286
|
+
basename: "batch"
|
|
287
|
+
}, options)
|
|
275
288
|
maxcount = options.maxcount
|
|
276
|
-
if !maxcount
|
|
277
|
-
maxcount = 4 // default is 4 workers
|
|
278
|
-
basename = options.basename
|
|
279
|
-
if !string(basename)
|
|
280
|
-
basename = "batch"
|
|
281
289
|
exqueue = [] // waiting for execution
|
|
282
290
|
parallel = new(object, this)
|
|
283
291
|
parallel.workers = [] // array of worker executors
|
|
@@ -288,36 +296,41 @@ closure ExecutorParallel(options, local maxcount, basename, parallel, exqueue, c
|
|
|
288
296
|
//
|
|
289
297
|
// Return the next available worker. If no workers are available and we haven't hit the maximum
|
|
290
298
|
// then create an additional worker and return it. If we cannot allocate another worker then this
|
|
291
|
-
// returns
|
|
299
|
+
// returns { wait: true }.
|
|
292
300
|
|
|
293
301
|
closure acquireWorker(local workdex, name, worker, context, result) {
|
|
294
302
|
if parallel.available.length > 0
|
|
295
|
-
return (parallel.available.pop())
|
|
303
|
+
return (list(false, parallel.available.pop()))
|
|
296
304
|
workdex = parallel.workers.length
|
|
297
305
|
if workdex >= maxcount
|
|
298
|
-
return (false)
|
|
306
|
+
return (list(false, { wait: true }))
|
|
299
307
|
parallel.workers[workdex] = false // reserve our spot
|
|
300
|
-
name = basename.concat("-", workdex+1)
|
|
301
|
-
worker =
|
|
302
|
-
|
|
308
|
+
name = options.basename.concat("-", workdex+1)
|
|
309
|
+
worker = track.spawn(options.spawnLoc, name, {
|
|
310
|
+
workerID: "ExecutorParallel"
|
|
311
|
+
})
|
|
312
|
+
if worker.0 {
|
|
313
|
+
parallel.workers.splice(workdex, 1)
|
|
303
314
|
debuglog("execParallel: cannot spawn worker:", ErrorString(worker.0))
|
|
304
|
-
return (
|
|
315
|
+
return (list(worker.0))
|
|
305
316
|
}
|
|
306
317
|
worker = worker.1
|
|
307
318
|
context = worker.context()
|
|
308
319
|
if context.0 {
|
|
309
|
-
|
|
320
|
+
parallel.workers.splice(workdex, 1)
|
|
310
321
|
worker.destroy()
|
|
311
|
-
|
|
322
|
+
debuglog("execParallel: cannot create worker context:", ErrorString(context.0))
|
|
323
|
+
return (list(context.0))
|
|
312
324
|
}
|
|
313
325
|
context = context.1
|
|
314
326
|
parallel.workers[workdex] = worker
|
|
315
327
|
parallel.contexts[worker] = context
|
|
316
328
|
if tuple(options.initeval) {
|
|
317
329
|
result = apply(context.eval, options.initeval)
|
|
318
|
-
if result.0
|
|
319
|
-
debuglog("execParallel: cannot initialize worker", name, ErrorString(result.0))
|
|
320
|
-
|
|
330
|
+
if result.0 {
|
|
331
|
+
debuglog("execParallel: cannot initialize worker", name, ErrorString(result.0))
|
|
332
|
+
return (list(result.0)) } }
|
|
333
|
+
return (list(false, worker))
|
|
321
334
|
}
|
|
322
335
|
|
|
323
336
|
// releaseWorker
|
|
@@ -337,23 +350,26 @@ closure ExecutorParallel(options, local maxcount, basename, parallel, exqueue, c
|
|
|
337
350
|
// don't remove work from the queue until we already have a worker.
|
|
338
351
|
//
|
|
339
352
|
|
|
340
|
-
closure execNext(local worker, result) {
|
|
353
|
+
closure execNext(local error, worker, result) {
|
|
341
354
|
if exqueue.length > 0 {
|
|
342
|
-
worker = acquireWorker()
|
|
343
|
-
if
|
|
344
|
-
if maxcount > 0 && parallel.workers.length == 0
|
|
345
|
-
|
|
346
|
-
|
|
355
|
+
`(error, worker) = acquireWorker()
|
|
356
|
+
if error {
|
|
357
|
+
if maxcount > 0 && parallel.workers.length == 0 {
|
|
358
|
+
exqueue = []
|
|
359
|
+
throw("execParallel: cannot allocate any workers at all") }
|
|
360
|
+
return // one failed, so try again later
|
|
347
361
|
}
|
|
362
|
+
if worker.wait
|
|
363
|
+
return // we're busy, so try again later
|
|
348
364
|
future(function(local next, context) {
|
|
349
365
|
next = exqueue.splice(0, 1).0 // remove oldest entry, from start
|
|
350
366
|
if !next {
|
|
351
367
|
releaseWorker(worker) // someone else already processed this
|
|
352
368
|
return
|
|
353
|
-
|
|
369
|
+
}
|
|
354
370
|
context = parallel.contexts[worker]
|
|
355
371
|
if next.eval
|
|
356
|
-
result = apply(context.eval, next.
|
|
372
|
+
result = apply(context.eval, next.eval)
|
|
357
373
|
else if next.proc
|
|
358
374
|
result = context.rpc(next.proc, next.args)
|
|
359
375
|
else
|
|
@@ -372,7 +388,7 @@ closure ExecutorParallel(options, local maxcount, basename, parallel, exqueue, c
|
|
|
372
388
|
//
|
|
373
389
|
|
|
374
390
|
parallel.eval = closure evalf(expr, put, get, local pending) {
|
|
375
|
-
if
|
|
391
|
+
if maxcount == 0
|
|
376
392
|
return (crValue) // already destroyed
|
|
377
393
|
pending = new(nonce)
|
|
378
394
|
exqueue.push({
|
|
@@ -392,13 +408,55 @@ closure ExecutorParallel(options, local maxcount, basename, parallel, exqueue, c
|
|
|
392
408
|
evalf(expr, eval(put), eval(get))
|
|
393
409
|
}
|
|
394
410
|
|
|
411
|
+
// exBatch
|
|
412
|
+
//
|
|
413
|
+
// Remote helper to execute a batch function.
|
|
414
|
+
//
|
|
415
|
+
|
|
416
|
+
closure exBatch(expr, local pending) {
|
|
417
|
+
// evaluate the expression in batch mode
|
|
418
|
+
function execbat() {
|
|
419
|
+
try {
|
|
420
|
+
pending.signal(list(false, evalactive(expr)))
|
|
421
|
+
} catch {
|
|
422
|
+
pending.signal(list(Error(exception)))
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
pending = new(nonce)
|
|
427
|
+
exec(list(execbat))
|
|
428
|
+
pending.wait()
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// batch
|
|
432
|
+
//
|
|
433
|
+
// Execute eval above in a remote in batch mode, waiting until it is complete.
|
|
434
|
+
//
|
|
435
|
+
|
|
436
|
+
parallel.batch = closure batchf(expr, put, get, local result) {
|
|
437
|
+
result = evalf(list(exBatch, list(quote, expr)), `(exBatch).append(put), get)
|
|
438
|
+
if result.0 // unpack our error wrapper
|
|
439
|
+
result
|
|
440
|
+
else
|
|
441
|
+
result.1
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// batchq
|
|
445
|
+
//
|
|
446
|
+
// Evaluate the specified QUOTED expression in a remote in batch mode.
|
|
447
|
+
//
|
|
448
|
+
|
|
449
|
+
parallel.batchq = macro batchq(expr, put, get) {
|
|
450
|
+
batchf(expr, eval(put), eval(get))
|
|
451
|
+
}
|
|
452
|
+
|
|
395
453
|
// rpc
|
|
396
454
|
//
|
|
397
455
|
// Execute a procedure call in a remote worker.
|
|
398
456
|
//
|
|
399
457
|
|
|
400
458
|
parallel.rpc = closure rpc(proc, args, local pending) {
|
|
401
|
-
if
|
|
459
|
+
if maxcount == 0
|
|
402
460
|
return (crValue) // already destroyed
|
|
403
461
|
pending = new(nonce)
|
|
404
462
|
exqueue.push({
|
|
@@ -410,13 +468,36 @@ closure ExecutorParallel(options, local maxcount, basename, parallel, exqueue, c
|
|
|
410
468
|
pending.wait()
|
|
411
469
|
}
|
|
412
470
|
|
|
471
|
+
// status
|
|
472
|
+
//
|
|
473
|
+
// Report status of workers. Each worker has a dictionary:
|
|
474
|
+
// {
|
|
475
|
+
// state: <string> // "active" or "idle"
|
|
476
|
+
// status: <dict> // like runaverage(1)
|
|
477
|
+
// }
|
|
478
|
+
//
|
|
479
|
+
|
|
480
|
+
parallel.status = function status(local output, worker) {
|
|
481
|
+
output = []
|
|
482
|
+
for worker in parallel.workers {
|
|
483
|
+
output.push({
|
|
484
|
+
name: worker.name
|
|
485
|
+
type: worker.type
|
|
486
|
+
state: if parallel.available.indexOf(worker) >= 0
|
|
487
|
+
"idle" else "active"
|
|
488
|
+
status: worker.xstatus
|
|
489
|
+
})
|
|
490
|
+
}
|
|
491
|
+
output
|
|
492
|
+
}
|
|
493
|
+
|
|
413
494
|
// destroy
|
|
414
495
|
//
|
|
415
496
|
// Destroy the object by destroying the workers and failing pending requests with cancelResult.
|
|
416
497
|
//
|
|
417
498
|
|
|
418
499
|
parallel.destroy = closure destroy(cancelResult, local worker, next) {
|
|
419
|
-
if
|
|
500
|
+
if maxcount == 0
|
|
420
501
|
return (false) // already destroyed
|
|
421
502
|
crValue = cancelResult
|
|
422
503
|
maxcount = 0
|
|
@@ -542,6 +623,13 @@ closure ExecutorTracker(local xtrak) {
|
|
|
542
623
|
} (pop(args), args)
|
|
543
624
|
}
|
|
544
625
|
|
|
626
|
+
// parallel
|
|
627
|
+
// Return a new parallel executor with specified options.
|
|
628
|
+
|
|
629
|
+
xtrak.parallel = function parallel(options) {
|
|
630
|
+
ExecutorParallel(xtrak, options)
|
|
631
|
+
}
|
|
632
|
+
|
|
545
633
|
xtrak.register(execLambda, "Lambda")
|
|
546
634
|
|
|
547
635
|
// finis
|
package/lib/browser/env_web.js
CHANGED
|
@@ -526,7 +526,7 @@ exports.NaanControllerWeb = function() {
|
|
|
526
526
|
statedoc.curversion = kStateCurrentVersion;
|
|
527
527
|
statedoc.firstver = kStateFirstVersion;
|
|
528
528
|
statedoc.licensee = "MIT-License";
|
|
529
|
-
statedoc.verstring = "1.2.
|
|
529
|
+
statedoc.verstring = "1.2.1+1";
|
|
530
530
|
statedoc.date = new Date().toISOString();
|
|
531
531
|
statedoc.prefs = prefs;
|
|
532
532
|
statedoc.naan = naanlib.saveState(false); // true to optimize, which is a bit slower
|
|
@@ -544,7 +544,7 @@ exports.NaanControllerWeb = function() {
|
|
|
544
544
|
|| statedoc.firstver > kStateCurrentVersion
|
|
545
545
|
|| statedoc.curversion < kStateFirstVersion
|
|
546
546
|
|| statedoc.licensee != "MIT-License"
|
|
547
|
-
|| statedoc.verstring != "1.2.
|
|
547
|
+
|| statedoc.verstring != "1.2.1+1")
|
|
548
548
|
{
|
|
549
549
|
localStorage.removeItem("NaanState_Hosted");
|
|
550
550
|
return (false);
|
|
@@ -603,7 +603,7 @@ exports.NaanControllerWeb = function() {
|
|
|
603
603
|
op: "VsiteOpen",
|
|
604
604
|
name: vsiteName,
|
|
605
605
|
naancont: contSelf,
|
|
606
|
-
title: vsiteName + " 1.2.
|
|
606
|
+
title: vsiteName + " 1.2.1+1"
|
|
607
607
|
});
|
|
608
608
|
}
|
|
609
609
|
} catch (e) {
|
|
@@ -617,7 +617,7 @@ exports.NaanControllerWeb = function() {
|
|
|
617
617
|
op: "VsiteClose",
|
|
618
618
|
name: vsiteName,
|
|
619
619
|
naancont: contSelf,
|
|
620
|
-
title: vsiteName + " 1.2.
|
|
620
|
+
title: vsiteName + " 1.2.1+1"
|
|
621
621
|
});
|
|
622
622
|
termTextOut("\x1b[90m\x1b[3m".concat("\nwindow closed", "\x1b[0m\n"));
|
|
623
623
|
}
|
|
@@ -632,8 +632,8 @@ exports.NaanControllerWeb = function() {
|
|
|
632
632
|
naanlib.banner();
|
|
633
633
|
var hostpath = naanlib.js.r("path").dirname(window.location.href);
|
|
634
634
|
naanlib.start({
|
|
635
|
-
cmd: 'App.version = "1.2.
|
|
636
|
-
+ 'App.cache = "
|
|
635
|
+
cmd: 'App.version = "1.2.1+1";;\r\n'
|
|
636
|
+
+ 'App.cache = "f22e60a842b7a65ac309da378d469eed";;\r\n'
|
|
637
637
|
+ 'Naan.module.requireQuery({ naanver: App.cache });;\r\n'
|
|
638
638
|
+ 'Naan.module.webparse("naan_init.nlg", "' + hostpath + '", { naanver: App.cache });;\r\n'
|
|
639
639
|
});
|