@naanlang/naan 1.7.0 → 1.7.2

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.
@@ -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.
@@ -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,7 +101,7 @@ 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.
@@ -103,19 +111,15 @@ closure ExecutorBase(track, type, name, local exec) {
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, local xid, pending) {
113
- for `(xid, pending) in exec.pending {
114
- pending.signal(list(error))
115
- exec.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
@@ -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
@@ -611,7 +619,7 @@ closure ExecutorTracker(local xtrak) {
611
619
  }
612
620
 
613
621
  // add
614
- // Add an execution instance at the specified location.
622
+ // Add an execution instance.
615
623
 
616
624
  xtrak.add = closure add(executor, local instance) {
617
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 (list(Error("already attached")))
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 (list(Error("already detached")))
302
+ return // already detached
298
303
  intop.term.SetNotify()
299
304
  intop.msgQueue = []
300
305
  intop.debugger.detach(intop)
@@ -310,20 +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.instanceID
321
+ if !intop.botDestID
317
322
  return
318
323
  intop.sender(intop.botDestID, {
319
324
  id: "unsubscribe"
320
325
  })
321
- intop.execClosed(Error("instance closed"))
322
- track.delete(intop)
323
- termDetach()
324
- sleep(10)
326
+ intop.botDestID = false
325
327
  App.imp.unregister(intop.instanceID)
326
- intop.instanceID = false
328
+ intop.sender = false
327
329
  }
328
330
 
329
331
  // destroy
@@ -334,11 +336,17 @@ closure InTop(track, options, local intop, nlregex, str, error) {
334
336
  if intop.destroyed
335
337
  return
336
338
  intop.destroyed = true
339
+ intop.execClosed(Error("instance closed"))
337
340
  intop.sender(intop.botDestID, {
338
341
  id: "destroy",
339
342
  guid: intop.instanceID
340
343
  })
341
- close()
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
342
350
  }
343
351
 
344
352
  // open
@@ -348,24 +356,27 @@ closure InTop(track, options, local intop, nlregex, str, error) {
348
356
  intop.open = closure open(inbotID) {
349
357
  if intop.destroyed
350
358
  return (list(Error("InTop already destroyed")))
351
- if intop.instanceID {
352
- if inbotID != intop.botDestID
353
- return (list(Error("InTop already open")))
354
- } else
355
- intop.instanceID = UUID()
359
+ if intop.botDestID == inbotID
360
+ return (list(false, { reopen: true }))
361
+ if intop.botDestID
362
+ close()
356
363
  intop.botDestID = inbotID
357
- intop.sender = App.imp.register(intop, {
358
- name: options.name
359
- type: options.type
360
- instanceID: intop.instanceID
361
- services: [ "naan-executor" ]
362
- })
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
+ })
363
375
  `(error) = intop.sender(intop.botDestID, {
364
376
  id: "subscribe"
365
377
  })
366
378
  if error
367
379
  return(list(error))
368
- track.add(intop)
369
380
  list(false, { ok: true })
370
381
  }
371
382
 
@@ -35,7 +35,8 @@ closure RemoteRequester(destID, options, local track)
35
35
  //
36
36
  closure remoteReq(track, name, local target) {
37
37
  target = ExecutorBase(false, "proxy", options.name)
38
- target.instanceID = UUID()
38
+ target.instanceID = App.imp.getUUID("RemoteRequester(${options.name}) instanceID")
39
+
39
40
 
40
41
  target.sender = App.imp.register(target, {
41
42
  name: options.name
@@ -33,7 +33,7 @@ closure RemoteResponder(destID, options, local remo, name)
33
33
  }, options)
34
34
  remo = ExecutorBase(App.nide.track, "remote-responder", name)
35
35
  remo.dispatcher = TaskDispatcher(false, false, "RemoteResponder")
36
- remo.instanceID = destID || UUID()
36
+ remo.instanceID = destID || App.imp.getUUID("RemoteResponder(${options.name}) instanceID")
37
37
  remo.sender = App.imp.register(remo, {
38
38
  name: options.name
39
39
  type: options.type
@@ -35,8 +35,11 @@ closure Imp(us, local imp) {
35
35
  name: "imp-generic"
36
36
  type: "imp-type"
37
37
  }, us)
38
+ imp.verbose = false
38
39
  if !us.instanceID
39
- us.instanceID = UUID()
40
+ us.instanceID = getUUID("Imp(${imp.us.name}) instanceID")
41
+ else if imp.verbose >= 1
42
+ debuglog("useUUID ${us.instanceID} for: Imp(${imp.us.name}) instanceID")
40
43
  imp.direct = { } // direct-connected destinations
41
44
  imp.pipes = { } // piped connections to destinations
42
45
  imp.gateways = { } // routing gateways for next hop
@@ -395,8 +398,10 @@ closure Imp(us, local imp) {
395
398
  function open() {
396
399
  dest.handshake.reset()
397
400
  dest.state = `connected
398
- future(function() {
399
- wait()
401
+ future(function(local error, newdid) {
402
+ `(error, newdid) = wait()
403
+ if error
404
+ return // didn't succeed (yet)
400
405
  info.destID = destID
401
406
  info.defaultID = dest.defaultID || undefined
402
407
  info.name = dest.name
@@ -453,7 +458,7 @@ closure Imp(us, local imp) {
453
458
  dest.info.services = [ service ]
454
459
  destID = info.destID
455
460
  if !destID {
456
- destID = UUID() // temporary destID to be updated
461
+ destID = getUUID("imp temporary for requester") // temporary destID to be updated
457
462
  dest.idsymbol = quote(destID)
458
463
  }
459
464
  imp.pipes[destID] = dest
@@ -463,6 +468,18 @@ closure Imp(us, local imp) {
463
468
  dest.conn
464
469
  }
465
470
 
471
+ // getUUID
472
+ //
473
+ // Get a UUID for the specified purpose, which is just a comment. This makes it easy to log
474
+ // UUID assignments for debugging.
475
+ //
476
+ imp.getUUID = function getUUID(purpose, local uuid) {
477
+ uuid = UUID()
478
+ if imp.verbose >= 1
479
+ debuglog("getUUID ${uuid} for: ${purpose}")
480
+ uuid
481
+ }
482
+
466
483
  // requester
467
484
  //
468
485
  // Start a requester connection and initiate the handshake. The IMP will use the specified
@@ -526,7 +543,7 @@ closure Imp(us, local imp) {
526
543
  debuglog("Imp.register: info.meta must be a dictionary if specified")
527
544
  instanceID = info.instanceID
528
545
  if !string(instanceID) || imp.direct[instanceID] {
529
- instanceID = UUID()
546
+ instanceID = getUUID("imp.register(${info.name}) auto-assignment")
530
547
  debuglog("Imp.register: instanceID ${info.instanceID} invalid or in use - replaced with ${instanceID}")
531
548
  }
532
549
  imp.direct[info.instanceID] = {
@@ -29,7 +29,7 @@ closure NodeWorkerNub(imp, options, local nownub) {
29
29
  type: "node-worker-nub"
30
30
  }, options)
31
31
  nownub = new(object, this)
32
- nownub.instanceID = imp.us.instanceID || UUID()
32
+ nownub.instanceID = imp.us.instanceID || imp.getUUID("NodeWorkerNub(${options.name}) instanceID")
33
33
  nownub.dispatcher = require("naanlib:frameworks/running/taskexec.nlg").TaskDispatcher(false, false, "NodeWorkerNub")
34
34
 
35
35
  // impReceive
@@ -88,10 +88,10 @@ closure NodeWorkerNub(imp, options, local nownub) {
88
88
 
89
89
  // message event
90
90
  //
91
- // Incoming data.
91
+ // Incoming data to the worker.
92
92
  //
93
93
  js.t.msgPort.on("message", function(msg) {
94
- if msg.id == "naan-imp-node"
94
+ if msg.id == "naan-imp-in"
95
95
  nownub.impconn.dispatch(new(msg.data))
96
96
  })
97
97
 
@@ -106,7 +106,7 @@ closure NodeWorkerNub(imp, options, local nownub) {
106
106
  })
107
107
  nownub.impconn = imp.requester(function(data) {
108
108
  js.t.msgPort.postMessage({ // send to main
109
- id: "naan-imp-node",
109
+ id: "naan-imp-out"
110
110
  data: data
111
111
  })
112
112
  list(false, { sent: true })
@@ -29,7 +29,7 @@ closure WebWorkerNub(imp, options, local wonub) {
29
29
  type: "web-worker-nub"
30
30
  }, options)
31
31
  wonub = new(object, this)
32
- wonub.instanceID = imp.us.instanceID || UUID()
32
+ wonub.instanceID = imp.us.instanceID || imp.getUUID("WebWorkerNub(${options.name}) instanceID")
33
33
  wonub.dispatcher = require("naanlib:frameworks/running/taskexec.nlg").TaskDispatcher(false, false, "WebWorkerNub")
34
34
 
35
35
  // impReceive
@@ -75,12 +75,12 @@ closure WebWorkerNub(imp, options, local wonub) {
75
75
 
76
76
  // message event
77
77
  //
78
- // Incoming data.
78
+ // Incoming data to the worker.
79
79
  //
80
80
  js.w.addEventListener("message", function message(e, local msg) {
81
- msg = new(e.data)
82
- if msg.scope == "naan-imp-web"
83
- wonub.impconn.dispatch(msg.data)
81
+ msg = e.data
82
+ if msg.scope == "naan-imp-in"
83
+ wonub.impconn.dispatch(new(msg.data))
84
84
  })
85
85
 
86
86
  // register our connects *after* the receivers are configured above
@@ -94,7 +94,7 @@ closure WebWorkerNub(imp, options, local wonub) {
94
94
  })
95
95
  wonub.impconn = imp.requester(function(data) {
96
96
  js.w.postMessage({ // send to main
97
- scope: "naan-imp-web",
97
+ scope: "naan-imp-out"
98
98
  data: data
99
99
  })
100
100
  list(false, { sent: true })
@@ -624,7 +624,7 @@ exports.NaanControllerWeb = function() {
624
624
  statedoc.curversion = kStateCurrentVersion;
625
625
  statedoc.firstver = kStateFirstVersion;
626
626
  statedoc.licensee = "MIT-License";
627
- statedoc.verstring = "1.7.0+1";
627
+ statedoc.verstring = "1.7.2+1";
628
628
  statedoc.date = new Date().toISOString();
629
629
  statedoc.prefs = prefs;
630
630
  statedoc.naan = naanlib.saveState(false); // true to optimize, which is a bit slower
@@ -642,7 +642,7 @@ exports.NaanControllerWeb = function() {
642
642
  || statedoc.firstver > kStateCurrentVersion
643
643
  || statedoc.curversion < kStateFirstVersion
644
644
  || statedoc.licensee != "MIT-License"
645
- || statedoc.verstring != "1.7.0+1"
645
+ || statedoc.verstring != "1.7.2+1"
646
646
  || !(naanstate = statedoc.naan))
647
647
  {
648
648
  localStorage.removeItem("NaanState_Hosted");
@@ -705,7 +705,7 @@ exports.NaanControllerWeb = function() {
705
705
  op: "VsiteOpen",
706
706
  name: vsiteName,
707
707
  naancont: contSelf,
708
- title: vsiteName + " 1.7.0+1"
708
+ title: vsiteName + " 1.7.2+1"
709
709
  });
710
710
  }
711
711
  } catch (e) {
@@ -719,9 +719,8 @@ exports.NaanControllerWeb = function() {
719
719
  op: "VsiteClose",
720
720
  name: vsiteName,
721
721
  naancont: contSelf,
722
- title: vsiteName + " 1.7.0+1"
722
+ title: vsiteName + " 1.7.2+1"
723
723
  });
724
- termTextOut("\x1b[90m\x1b[3m".concat("\nwindow closed", "\x1b[0m\n"));
725
724
  }
726
725
  } catch (e) {
727
726
  }
@@ -735,7 +734,7 @@ exports.NaanControllerWeb = function() {
735
734
  op: "VsiteVisibilityChange",
736
735
  name: vsiteName,
737
736
  naancont: contSelf,
738
- title: vsiteName + " 1.7.0+1",
737
+ title: vsiteName + " 1.7.2+1",
739
738
  hidden: window.document.visibilityState == "hidden",
740
739
  window: window
741
740
  });
@@ -750,8 +749,8 @@ exports.NaanControllerWeb = function() {
750
749
  naanlib.banner();
751
750
  var hostpath = window.location.origin.concat(naanlib.js.r("path").dirname(window.location.pathname));
752
751
  naanlib.start({
753
- cmd: 'App.version = "1.7.0+1";;\r\n'
754
- + 'App.cache = "1bae92ceb3cc5eb47f6dbe8e40ceeb9f";;\r\n'
752
+ cmd: 'App.version = "1.7.2+1";;\r\n'
753
+ + 'App.cache = "9e8f87aa915943862be39d701927fbd1";;\r\n'
755
754
  + 'Naan.module.requireQuery({ naanver: App.cache });;\r\n'
756
755
  + 'Naan.module.webparse("naan_init.nlg", "' + hostpath + '", { naanver: App.cache });;\r\n'
757
756
  });