@naanlang/naan 1.4.4 → 1.6.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 +2 -2
- package/README.md +4 -4
- package/bin/index.js +25 -3
- package/dist/env_web.js +164 -22
- package/dist/naan.min.js +5 -5
- package/frameworks/browser/browser.nlg +2 -2
- package/frameworks/browser/https_request.nlg +2 -2
- package/frameworks/browser/sworker.js +28 -26
- package/frameworks/browser/terminals.nlg +342 -700
- package/frameworks/browser/worker.nlg +255 -0
- package/frameworks/browser/workers.nlg +5 -5
- package/frameworks/browser/ws_client.nlg +15 -10
- package/frameworks/client/apiclient.nlg +204 -19
- package/frameworks/client/client.nlg +22 -2
- package/frameworks/client/psm_client.nlg +12 -3
- package/frameworks/client/relaycon.nlg +87 -161
- package/frameworks/common/events.nlg +101 -0
- package/frameworks/common/repltools.nlg +80 -1
- package/frameworks/node/apiserver.nlg +39 -246
- package/frameworks/node/filesystem.nlg +39 -12
- package/frameworks/node/gitter.nlg +9 -7
- package/frameworks/node/http_request.nlg +34 -13
- package/frameworks/node/https_request.nlg +8 -3
- package/frameworks/node/node.nlg +2 -0
- package/frameworks/node/pty.nlg +346 -0
- package/frameworks/node/shell.nlg +4 -4
- package/frameworks/node/worker.nlg +409 -539
- package/frameworks/node/ws_client.nlg +2 -2
- package/frameworks/project/build.nlg +1 -1
- package/frameworks/project/projects.nlg +2 -1
- package/frameworks/running/debugnub.nlg +17 -4
- package/frameworks/running/executors.nlg +27 -274
- package/frameworks/running/instances.nlg +393 -0
- package/frameworks/running/remote_req.nlg +143 -0
- package/frameworks/running/remote_res.nlg +89 -0
- package/frameworks/running/taskexec.nlg +2 -2
- package/frameworks/service/imp.nlg +736 -0
- package/frameworks/service/model.nlg +71 -0
- package/frameworks/service/nubnode.nlg +105 -0
- package/frameworks/service/nubweb.nlg +106 -0
- package/frameworks/service/service.nlg +28 -0
- package/frameworks/storage/dbt_pouch.nlg +26 -13
- package/frameworks/storage/psm.nlg +39 -5
- package/frameworks/storage/psm_dbtables.nlg +10 -2
- package/lib/browser/env_web.js +171 -29
- package/lib/browser/env_webworker.js +91 -5
- package/lib/core/naanlib.js +5 -5
- package/lib/env_node.js +184 -8
- package/lib/env_nodeworker.js +74 -1
- package/package.json +1 -1
- package/plugins/serviceAws/aws_cloudwatchlogs.nlg +2 -1
- package/plugins/serviceAws/aws_dynamo.nlg +1 -0
- package/plugins/serviceAws/aws_s3.nlg +3 -3
- package/plugins/serviceAws/aws_sqs.nlg +3 -1
- package/plugins/serviceAws/aws_utils.nlg +3 -1
- package/plugins/serviceAws/dbt_aws.nlg +22 -20
- package/plugins/serviceAws/psm_aws.nlg +2 -1
- package/plugins/serviceNexara/speechrec.nlg +10 -6
- package/test/test_02_context.nlg +24 -1
- package/test/test_03_jsinterop.nlg +32 -3
- package/plugins/serviceGC/russian_trusted_root_ca_pem.crt +0 -33
|
@@ -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
|
|
|
@@ -15,363 +15,375 @@
|
|
|
15
15
|
*
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
gWorkerController = false;
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
/*
|
|
22
|
-
*
|
|
22
|
+
* CurBot
|
|
23
23
|
*
|
|
24
|
-
*
|
|
24
|
+
* Attach a remote terminal interface to the current NodeJS thread.
|
|
25
|
+
*
|
|
26
|
+
* Options:
|
|
27
|
+
* {
|
|
28
|
+
* name: <string> // target name, e.g. "Play"
|
|
29
|
+
* type: <string> // target category, e.g. "Local"
|
|
30
|
+
* }
|
|
25
31
|
*
|
|
26
32
|
*/
|
|
27
33
|
|
|
28
|
-
closure
|
|
29
|
-
global(js)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
closure CurBot(options, local curbot) {
|
|
35
|
+
global(App, js)
|
|
36
|
+
curbot = new(object, this)
|
|
37
|
+
curbot.topsubs = []
|
|
38
|
+
options = merge({
|
|
39
|
+
type: "Host"
|
|
40
|
+
}, options)
|
|
41
|
+
curbot.type = options.type
|
|
42
|
+
curbot.name = options.name
|
|
43
|
+
|
|
44
|
+
curbot.termif = xnew({
|
|
35
45
|
textout: ONtextOut.proc
|
|
36
46
|
debugtext: ONdebugText.proc
|
|
37
47
|
status: ONstatus.proc
|
|
38
48
|
debugout: ONdebugOut.proc
|
|
39
49
|
messageout: ONmessageOut.proc
|
|
50
|
+
ioctl: ONioctl.proc
|
|
40
51
|
})
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
52
|
+
curbot.guid = 1
|
|
53
|
+
curbot.host = js.t // our magic Naan controller reference
|
|
54
|
+
|
|
55
|
+
curbot.instanceID = UUID()
|
|
56
|
+
curbot.sender = App.imp.register(curbot, {
|
|
57
|
+
name: curbot.name
|
|
58
|
+
type: curbot.type
|
|
59
|
+
instanceID: curbot.instanceID
|
|
60
|
+
services: ["naanide-server-main"]
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// subscribe
|
|
64
|
+
//
|
|
65
|
+
// Add an InTop to our subscribers if not already known.
|
|
66
|
+
//
|
|
67
|
+
function subscribe(destID) {
|
|
68
|
+
if !curbot.topsubs.find(function(item) { item == destID }) {
|
|
69
|
+
curbot.topsubs.push(destID)
|
|
70
|
+
curbot.sender(destID, {
|
|
71
|
+
id: "workerDestID"
|
|
72
|
+
workerDestID: App.imp.us.instanceID // our remote responder
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// unsubscribe
|
|
78
|
+
//
|
|
79
|
+
// Remove an InTop from our subscribers if present.
|
|
80
|
+
//
|
|
81
|
+
function unsubscribe(destID) {
|
|
82
|
+
curbot.topsubs = curbot.topsubs.filter(function(item) { item != destID })
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// notifyAll
|
|
86
|
+
//
|
|
87
|
+
// Send the message to all our subscribers.
|
|
88
|
+
//
|
|
89
|
+
function notifyAll(message, exceptID, local topDestID) {
|
|
90
|
+
for topDestID in curbot.topsubs
|
|
91
|
+
if topDestID != exceptID
|
|
92
|
+
curbot.sender(topDestID, message)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// impReceive
|
|
96
|
+
//
|
|
97
|
+
// Received a payload.
|
|
98
|
+
//
|
|
99
|
+
curbot.impReceive = function impReceive(message, sourceID) {
|
|
100
|
+
// js.g.console.log("CurBot.impReceive(${sourceID}):\n", Dialect.print(new(message)))
|
|
101
|
+
if message.id == "destroy"
|
|
102
|
+
{ }
|
|
103
|
+
else if message.id == "subscribe"
|
|
104
|
+
subscribe(sourceID)
|
|
105
|
+
else if message.id == "unsubscribe"
|
|
106
|
+
unsubscribe(sourceID)
|
|
107
|
+
else if message.id == "typed"
|
|
108
|
+
notifyAll(message, sourceID)
|
|
109
|
+
else {
|
|
110
|
+
message.data._guid = sourceID
|
|
111
|
+
curbot.host.DispatchMessage(message)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// impUnknown
|
|
116
|
+
//
|
|
117
|
+
// Received an unknown destination notice.
|
|
118
|
+
//
|
|
119
|
+
curbot.impUnknown = function impUnknown(unknownID, sourceID, gateway) {
|
|
120
|
+
if curbot.topsubs[unknownID] { // did not have courtesy to unsubscribe!
|
|
121
|
+
unsubscribe(unknownID)
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
if !gateway
|
|
125
|
+
debuglog("CurBot.impUnknownID:", unknownID, "sourceID:", sourceID)
|
|
126
|
+
}
|
|
127
|
+
|
|
44
128
|
// replyHook
|
|
45
129
|
//
|
|
46
130
|
// Intercept the ReplyMessage function to see if we should handle it.
|
|
47
131
|
//
|
|
48
132
|
function replyHook(data) {
|
|
133
|
+
// js.g.console.log("CurBot.replyHook:\n", Dialect.print(new(data)))
|
|
134
|
+
// debuglog("CurBot.replyHook:\n", Dialect.print(new(data)))
|
|
135
|
+
/* ###
|
|
49
136
|
if data._guid
|
|
50
137
|
workco.uworkers[data._guid].msgport.postMessage({
|
|
51
138
|
id: "targetreceive"
|
|
52
139
|
data: data
|
|
53
140
|
})
|
|
141
|
+
*/
|
|
54
142
|
}
|
|
55
|
-
|
|
143
|
+
curbot.host.OnReplyHook(replyHook.proc)
|
|
56
144
|
|
|
57
145
|
// ONtextOut
|
|
146
|
+
//
|
|
58
147
|
// Process console text output by Naan.
|
|
59
|
-
|
|
148
|
+
//
|
|
60
149
|
function ONtextOut(text) {
|
|
61
|
-
|
|
150
|
+
notifyAll({
|
|
62
151
|
id: "textout",
|
|
63
152
|
text: text,
|
|
64
153
|
})
|
|
65
154
|
}
|
|
66
|
-
|
|
155
|
+
|
|
67
156
|
// ONdebugText
|
|
157
|
+
//
|
|
68
158
|
// Process console debug text output by Naan.
|
|
69
|
-
|
|
159
|
+
//
|
|
70
160
|
function ONdebugText(text, level) {
|
|
71
|
-
|
|
161
|
+
notifyAll({
|
|
72
162
|
id: "debugtext",
|
|
73
163
|
text: text,
|
|
74
164
|
level: level
|
|
75
165
|
})
|
|
76
166
|
}
|
|
77
|
-
|
|
167
|
+
|
|
78
168
|
// ONstatus
|
|
169
|
+
//
|
|
79
170
|
// Process status update output by Naan.
|
|
80
|
-
|
|
171
|
+
//
|
|
81
172
|
function ONstatus(status) {
|
|
82
|
-
|
|
173
|
+
notifyAll({
|
|
83
174
|
id: "status",
|
|
84
175
|
status: status
|
|
85
176
|
})
|
|
86
177
|
}
|
|
87
|
-
|
|
178
|
+
|
|
88
179
|
// ONdebugOut
|
|
180
|
+
//
|
|
89
181
|
// Process debugger output.
|
|
90
|
-
|
|
182
|
+
//
|
|
91
183
|
function ONdebugOut(data) {
|
|
92
|
-
|
|
184
|
+
notifyAll({
|
|
93
185
|
id: "debugout",
|
|
94
186
|
data: data
|
|
95
187
|
})
|
|
96
188
|
}
|
|
97
|
-
|
|
98
|
-
// ONmessageOut
|
|
99
|
-
// Process message output.
|
|
100
|
-
|
|
101
|
-
function ONmessageOut(data) {
|
|
102
|
-
if data._guid
|
|
103
|
-
return // already replied
|
|
104
|
-
current.execReceived(data)
|
|
105
|
-
sendAll({
|
|
106
|
-
id: "targetout",
|
|
107
|
-
data: data
|
|
108
|
-
})
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// removeLink
|
|
112
|
-
// Remove a link.
|
|
113
|
-
|
|
114
|
-
function removeLink(link) {
|
|
115
|
-
current.links = current.links.filter(function(item) {
|
|
116
|
-
!(item.link eq link)
|
|
117
|
-
})
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// exitNotify
|
|
121
|
-
// Notify all links that we have terminated.
|
|
122
|
-
|
|
123
|
-
function exitNotify(exitCode, local link) {
|
|
124
|
-
workco.uworkers[current.guid] = undefined
|
|
125
|
-
for link in current.links
|
|
126
|
-
link.exitWorker(exitCode)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// sendAll
|
|
130
|
-
// Send a message to all links.
|
|
131
|
-
|
|
132
|
-
function sendAll(msg, local link) {
|
|
133
|
-
for link in current.links
|
|
134
|
-
link.responder(msg)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
//
|
|
138
|
-
// attach
|
|
139
|
-
//
|
|
140
|
-
// Attach a link.
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
current.attach = function attach(link, responder) {
|
|
144
|
-
removeLink(link)
|
|
145
|
-
current.links.push({
|
|
146
|
-
link: link // a link to us
|
|
147
|
-
responder: responder // link's responder
|
|
148
|
-
})
|
|
149
|
-
if current.links.length == 1
|
|
150
|
-
current.host.Attach(current.termif) // attached while one link is active
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
// detach
|
|
155
|
-
//
|
|
156
|
-
// Detach a link.
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
current.detach = function detach(link) {
|
|
160
|
-
removeLink(link)
|
|
161
|
-
if current.links.length == 0
|
|
162
|
-
current.host.Detach(current.termif) // attached while one link is active
|
|
163
|
-
}
|
|
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
189
|
|
|
190
|
+
// ONmessageOut
|
|
175
191
|
//
|
|
176
|
-
//
|
|
192
|
+
// Process message output.
|
|
177
193
|
//
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
194
|
+
function ONmessageOut(data, local _guid) {
|
|
195
|
+
if data._guid {
|
|
196
|
+
_guid = data._guid
|
|
197
|
+
data._guid = undefined
|
|
198
|
+
curbot.sender(_guid, {
|
|
199
|
+
id: "targetout",
|
|
200
|
+
data: data
|
|
201
|
+
})
|
|
202
|
+
return
|
|
203
|
+
}
|
|
182
204
|
}
|
|
183
205
|
|
|
206
|
+
// ONioctl
|
|
184
207
|
//
|
|
185
|
-
//
|
|
208
|
+
// Process ioctl.
|
|
186
209
|
//
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
210
|
+
function ONioctl(op, arg) {
|
|
211
|
+
notifyAll({
|
|
212
|
+
id: "ioctl",
|
|
213
|
+
op: op,
|
|
214
|
+
arg: arg
|
|
215
|
+
})
|
|
193
216
|
}
|
|
194
217
|
|
|
195
|
-
|
|
196
|
-
// vitalUpdate
|
|
197
|
-
//
|
|
198
|
-
// Worker thread birth/death/enumeration.
|
|
218
|
+
curbot.host.Attach(curbot.termif)
|
|
199
219
|
|
|
200
|
-
|
|
201
|
-
sendAll(msg)
|
|
202
|
-
}
|
|
220
|
+
curbot.subprocess = MakeSubProcessor(curbot) // Enable PTY subprocesses on our terminal
|
|
203
221
|
|
|
204
222
|
// finis
|
|
205
|
-
|
|
223
|
+
|
|
224
|
+
curbot
|
|
206
225
|
};
|
|
207
226
|
|
|
208
227
|
|
|
209
228
|
/*
|
|
210
|
-
*
|
|
229
|
+
* NowBot
|
|
211
230
|
*
|
|
212
|
-
*
|
|
231
|
+
* Spawn a Naan worker in its own thread.
|
|
232
|
+
*
|
|
233
|
+
* Options:
|
|
234
|
+
* {
|
|
235
|
+
* name: <string> // target name, e.g. "Play"
|
|
236
|
+
* type: <string> // target category, e.g. "Local"
|
|
237
|
+
* startup: <dictionary> // startup options
|
|
238
|
+
* topOriginID: <string> // so top can route to us through IMP
|
|
239
|
+
* }
|
|
213
240
|
*
|
|
214
241
|
*/
|
|
215
242
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
243
|
+
closure NowBot(options, local nowbot, subChannel) {
|
|
244
|
+
global(App, js, threads, JSpath)
|
|
245
|
+
nowbot = new(object, this)
|
|
246
|
+
nowbot.topsubs = []
|
|
247
|
+
options = merge({
|
|
248
|
+
type: "node-worker"
|
|
249
|
+
}, options)
|
|
220
250
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
251
|
+
// options = { execArgv: ["--inspect-brk"] } // uncomment for NodeJS debugging
|
|
252
|
+
nowbot.thread = xnew(threads.Worker, JSpath.resolve(js.d, "lib/node_worker.js"), options)
|
|
253
|
+
subChannel = xnew(threads.MessageChannel)
|
|
254
|
+
nowbot.thread.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1])
|
|
255
|
+
nowbot.msgport = subChannel.port2
|
|
256
|
+
|
|
257
|
+
nowbot.instanceID = UUID()
|
|
258
|
+
nowbot.sender = App.imp.register(nowbot, {
|
|
259
|
+
name: options.name
|
|
260
|
+
type: options.type
|
|
261
|
+
instanceID: nowbot.instanceID
|
|
262
|
+
services: ["node-worker"]
|
|
263
|
+
})
|
|
228
264
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
265
|
+
// If this NowBot is created remotely then we need to send a message from our new instanceID
|
|
266
|
+
// to the InTop origin so that it can send messages to us. The intermediate gateways save the
|
|
267
|
+
// route to allow replies.
|
|
268
|
+
if options.topOriginID && options.topOriginID != App.imp.us.instanceID
|
|
269
|
+
nowbot.sender(options.topOriginID) // create route top->bottom
|
|
270
|
+
|
|
271
|
+
// subscribe
|
|
272
|
+
//
|
|
273
|
+
// Add an InTop to our subscribers if not already known.
|
|
274
|
+
//
|
|
275
|
+
function subscribe(destID) {
|
|
276
|
+
if !nowbot.topsubs.find(function(item) { item == destID }) {
|
|
277
|
+
nowbot.topsubs.push(destID)
|
|
278
|
+
if nowbot.workerDestID {
|
|
279
|
+
App.imp.inform(nowbot.workerDestID, destID) // provide path to workerID
|
|
280
|
+
nowbot.sender(destID, { // send to new subscriber
|
|
281
|
+
id: "workerDestID"
|
|
282
|
+
workerDestID: nowbot.workerDestID
|
|
283
|
+
})
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
233
287
|
|
|
288
|
+
// unsubscribe
|
|
234
289
|
//
|
|
235
|
-
//
|
|
236
|
-
//
|
|
237
|
-
// Post a message to the main thread.
|
|
290
|
+
// Remove an InTop from our subscribers if present.
|
|
238
291
|
//
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
list(false, { posted: true })
|
|
292
|
+
function unsubscribe(destID) {
|
|
293
|
+
nowbot.topsubs = nowbot.topsubs.filter(function(item) { item != destID })
|
|
242
294
|
}
|
|
243
295
|
|
|
296
|
+
// notifyAll
|
|
244
297
|
//
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
// Process a received message from the main thread, typically in response.
|
|
298
|
+
// Send the message to all our subscribers.
|
|
248
299
|
//
|
|
249
|
-
function
|
|
250
|
-
|
|
300
|
+
nowbot.notifyAll = function notifyAll(message, exceptID, local topDestID) {
|
|
301
|
+
for topDestID in nowbot.topsubs
|
|
302
|
+
if topDestID != exceptID
|
|
303
|
+
nowbot.sender(topDestID, message)
|
|
251
304
|
}
|
|
252
|
-
|
|
253
|
-
//
|
|
305
|
+
|
|
306
|
+
// impReceive
|
|
254
307
|
//
|
|
255
|
-
//
|
|
308
|
+
// Received a payload.
|
|
256
309
|
//
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
* WorkerToMain
|
|
273
|
-
*
|
|
274
|
-
* Connect our worker to the main thread, returning a result tuple with an executor representing
|
|
275
|
-
* Main. Use this to create a context object for Main, allowing remote evaluation.
|
|
276
|
-
*
|
|
277
|
-
*/
|
|
278
|
-
|
|
279
|
-
closure WorkerToMain(local nideRunning, track) {
|
|
280
|
-
// mainProxy -- link tracker to main thread proxy
|
|
281
|
-
function mainProxy(track, name, options) {
|
|
282
|
-
workMainProxy(track, name, options)
|
|
310
|
+
nowbot.impReceive = function impReceive(message, sourceID) {
|
|
311
|
+
if message.id == "destroy"
|
|
312
|
+
terminate()
|
|
313
|
+
else if message.id == "subscribe"
|
|
314
|
+
subscribe(sourceID)
|
|
315
|
+
else if message.id == "unsubscribe"
|
|
316
|
+
unsubscribe(sourceID)
|
|
317
|
+
else if message.id == "typed"
|
|
318
|
+
notifyAll(message, sourceID)
|
|
319
|
+
else {
|
|
320
|
+
if message.id == "keyline" && nowbot.keyin
|
|
321
|
+
nowbot.keyin(message.text) // terminal keyboard -> pty subprocess
|
|
322
|
+
else
|
|
323
|
+
nowbot.msgport.postMessage(message)
|
|
324
|
+
}
|
|
283
325
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
326
|
+
|
|
327
|
+
// impUnknown
|
|
328
|
+
//
|
|
329
|
+
// Received an unknown destination notice.
|
|
330
|
+
//
|
|
331
|
+
nowbot.impUnknown = function impUnknown(unknownID, sourceID, gateway) {
|
|
332
|
+
if nowbot.topsubs[unknownID] { // did not have courtesy to unsubscribe!
|
|
333
|
+
unsubscribe(unknownID)
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
if !gateway
|
|
337
|
+
debuglog("NowBot.impUnknownID:", unknownID, "sourceID:", sourceID)
|
|
288
338
|
}
|
|
289
|
-
nideRunning = require("naanlib:frameworks/running/executors.nlg")
|
|
290
|
-
track = nideRunning.ExecutorTracker()
|
|
291
|
-
track.register(mainProxy, "proxy")
|
|
292
|
-
track.spawn("proxy") // returns result tuple
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
/*
|
|
297
|
-
* workThread
|
|
298
|
-
*
|
|
299
|
-
* Spawn a Naan worker in its own thread.
|
|
300
|
-
*
|
|
301
|
-
*/
|
|
302
|
-
|
|
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)
|
|
307
|
-
worker.name = startup.name
|
|
308
|
-
worker.workerID = workerID
|
|
309
|
-
worker.links = []
|
|
310
|
-
worker.guid = guid || UUID()
|
|
311
339
|
|
|
312
|
-
//
|
|
313
|
-
|
|
314
|
-
//
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
function removeLink(link) {
|
|
324
|
-
worker.links = worker.links.filter(function(item) {
|
|
325
|
-
!(item.link eq link)
|
|
340
|
+
// nowbot
|
|
341
|
+
//
|
|
342
|
+
// An exception occurred on the worker thread. Since Naan catches all exceptions this should
|
|
343
|
+
// not occur normally.
|
|
344
|
+
//
|
|
345
|
+
nowbot.thread.on("error", function onerror(error) {
|
|
346
|
+
debuglog("worker terminated with error", options.type, options.name, error)
|
|
347
|
+
notifyAll({
|
|
348
|
+
id: "terminated"
|
|
349
|
+
error: error
|
|
326
350
|
})
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
// exitNotify
|
|
330
|
-
// Notify all links that we have terminated.
|
|
331
|
-
|
|
332
|
-
function exitNotify(exitCode, local link) {
|
|
333
|
-
workco.uworkers[worker.guid] = undefined
|
|
334
|
-
for link in worker.links
|
|
335
|
-
link.exitWorker(exitCode)
|
|
336
|
-
worker.links = []
|
|
337
|
-
deathWatcher(workerID)
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// sendAll
|
|
341
|
-
// Send a message to all links.
|
|
351
|
+
destroy()
|
|
352
|
+
})
|
|
342
353
|
|
|
343
|
-
|
|
344
|
-
for link in worker.links
|
|
345
|
-
link.responder(msg)
|
|
346
|
-
}
|
|
347
|
-
|
|
354
|
+
// onexit
|
|
348
355
|
//
|
|
349
|
-
//
|
|
356
|
+
// Note that the worker thread has terminated.
|
|
350
357
|
//
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
358
|
+
nowbot.thread.on("exit", function onexit(exitCode) {
|
|
359
|
+
notifyAll({
|
|
360
|
+
id: "terminated"
|
|
361
|
+
exitCode: exitCode
|
|
362
|
+
})
|
|
363
|
+
destroy()
|
|
357
364
|
})
|
|
358
365
|
|
|
366
|
+
// destroy
|
|
359
367
|
//
|
|
360
|
-
//
|
|
368
|
+
// Ensure the worker is destroyed.
|
|
361
369
|
//
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
370
|
+
nowbot.destroy = function destroy() {
|
|
371
|
+
terminate()
|
|
372
|
+
nowbot.thread = false
|
|
373
|
+
nowbot.impconn.close()
|
|
374
|
+
nowbot.impconn = false
|
|
375
|
+
App.imp.unregister(nowbot.instanceID)
|
|
376
|
+
}
|
|
367
377
|
|
|
378
|
+
// NaaN message
|
|
368
379
|
//
|
|
369
|
-
//
|
|
380
|
+
// A message has been received from NaaN running on the worker thread.
|
|
370
381
|
//
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
382
|
+
nowbot.msgport.on("message", function (msg, local startmsg) {
|
|
383
|
+
if msg.id == "naan-imp-node" {
|
|
384
|
+
nowbot.impconn.dispatch(new(msg.data))
|
|
385
|
+
return
|
|
386
|
+
} else if msg.id == "loaded" {
|
|
375
387
|
startmsg = {
|
|
376
388
|
id: "start"
|
|
377
389
|
state: false // resume state, if we have any
|
|
@@ -379,338 +391,197 @@ closure workThread(workco, workerID, startup, guid
|
|
|
379
391
|
dirpath: js.d
|
|
380
392
|
workerID: workerID
|
|
381
393
|
workerGUID: worker.guid
|
|
394
|
+
metadata: {
|
|
395
|
+
mainInstanceID: App.imp.us.instanceID
|
|
396
|
+
name: options.name
|
|
397
|
+
}
|
|
382
398
|
}
|
|
383
|
-
if startup.initcmds
|
|
384
|
-
startmsg.altcmd = startup.initcmds.concat("\n")
|
|
385
|
-
if startup.dirpath
|
|
386
|
-
startmsg.dirpath = startup.dirpath
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
id: "started"
|
|
390
|
-
})
|
|
391
|
-
else if msg.id == "targetsend" {
|
|
392
|
-
msg.data._guid =
|
|
399
|
+
if options.startup.initcmds
|
|
400
|
+
startmsg.altcmd = options.startup.initcmds.concat("\n")
|
|
401
|
+
if options.startup.dirpath
|
|
402
|
+
startmsg.dirpath = options.startup.dirpath
|
|
403
|
+
nowbot.msgport.postMessage(startmsg)
|
|
404
|
+
notifyAll({
|
|
405
|
+
id: "started"
|
|
406
|
+
})
|
|
407
|
+
} else if msg.id == "targetsend" {
|
|
408
|
+
msg.data._guid = nowbot.guid
|
|
393
409
|
js.t.DispatchMessage({
|
|
394
410
|
id: "targetin"
|
|
395
411
|
data: msg.data
|
|
396
412
|
}) }
|
|
397
|
-
else
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
worker.execReceived(msg.data)
|
|
402
|
-
sendAll(msg) } // default is just return message to the client
|
|
413
|
+
else if msg.id == "textout" && nowbot.naanin
|
|
414
|
+
nowbot.naanin(msg.text) // naan output -> pty subprocess
|
|
415
|
+
else
|
|
416
|
+
notifyAll(msg)
|
|
403
417
|
})
|
|
404
418
|
|
|
405
|
-
//
|
|
406
419
|
// terminate
|
|
407
420
|
//
|
|
408
|
-
//
|
|
409
|
-
|
|
410
|
-
worker.terminate = function terminate(local error, exitCode) {
|
|
411
|
-
`(error, exitCode) = await(worker.thread.terminate())
|
|
412
|
-
exitNotify(exitCode)
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
//
|
|
416
|
-
// attach
|
|
417
|
-
//
|
|
418
|
-
// Attach a connection to our worker.
|
|
419
|
-
//
|
|
420
|
-
|
|
421
|
-
worker.attach = function attach(link, responder) {
|
|
422
|
-
removeLink(link)
|
|
423
|
-
worker.links.push({
|
|
424
|
-
link: link // a link to us
|
|
425
|
-
responder: responder // link's responder
|
|
426
|
-
})
|
|
427
|
-
}
|
|
428
|
-
|
|
421
|
+
// Terminate this worker asap.
|
|
429
422
|
//
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
worker.detach = function detach(link) {
|
|
436
|
-
removeLink(link)
|
|
423
|
+
nowbot.terminate = function terminate(local error, exitCode) {
|
|
424
|
+
if nowbot.thread
|
|
425
|
+
`(error, exitCode) = await(nowbot.thread.terminate()) // notified by on-error and on-exit
|
|
426
|
+
else
|
|
427
|
+
list(false, { terminated: true }) // already terminated
|
|
437
428
|
}
|
|
438
429
|
|
|
439
|
-
//
|
|
440
430
|
// PostMessage
|
|
441
431
|
//
|
|
442
|
-
//
|
|
432
|
+
// Post a message to the worker thread.
|
|
443
433
|
//
|
|
444
|
-
|
|
445
|
-
|
|
434
|
+
nowbot.PostMessage = function PostMessage(data) {
|
|
435
|
+
nowbot.msgport.postMessage({ // send data to worker
|
|
446
436
|
id: "targetin",
|
|
447
437
|
data: data
|
|
448
438
|
})
|
|
449
439
|
list(false, { posted: true })
|
|
450
440
|
}
|
|
451
441
|
|
|
452
|
-
//
|
|
453
|
-
// msgin
|
|
454
|
-
//
|
|
455
|
-
// Send a message to the worker thread.
|
|
456
|
-
|
|
457
|
-
worker.msgin = function msgin(msg) {
|
|
458
|
-
worker.msgport.postMessage(msg)
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
//
|
|
462
|
-
// echo
|
|
463
|
-
//
|
|
464
|
-
// Echo a message to the *other* links.
|
|
465
|
-
|
|
466
|
-
worker.echo = function echo(msg, thislink, local linkref) {
|
|
467
|
-
for linkref in worker.links
|
|
468
|
-
if !(linkref.link eq thislink)
|
|
469
|
-
linkref.responder(msg)
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
//
|
|
473
|
-
// vitalWatch
|
|
474
|
-
//
|
|
475
|
-
// Report our termination to the specified watcher.
|
|
476
|
-
|
|
477
|
-
worker.vitalWatch = function vitalWatch(watcher) {
|
|
478
|
-
deathWatcher = watcher
|
|
479
|
-
}
|
|
442
|
+
nowbot.subprocess = MakeSubProcessor(nowbot) // Enable PTY subprocesses on our terminal
|
|
480
443
|
|
|
481
444
|
// finis
|
|
482
|
-
|
|
445
|
+
|
|
446
|
+
nowbot
|
|
483
447
|
};
|
|
484
448
|
|
|
485
449
|
|
|
486
450
|
/*
|
|
487
|
-
*
|
|
451
|
+
* NobBot
|
|
488
452
|
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
* clients to create a new connection to talk with an existing worker.
|
|
453
|
+
* Create a remote interface like NowBot, but also provide messaging support for NodeWorkerNub inside
|
|
454
|
+
* the worker.
|
|
492
455
|
*
|
|
493
456
|
*/
|
|
494
457
|
|
|
495
|
-
closure
|
|
496
|
-
|
|
497
|
-
|
|
458
|
+
closure NobBot(options, local nobbot)
|
|
459
|
+
{
|
|
460
|
+
global(App)
|
|
461
|
+
nobbot = NowBot(options)
|
|
498
462
|
|
|
463
|
+
// informAll
|
|
499
464
|
//
|
|
500
|
-
//
|
|
501
|
-
//
|
|
502
|
-
// Note that the connection has closed.
|
|
465
|
+
// Inform sourceID path to all our subscribers.
|
|
503
466
|
//
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
//
|
|
510
|
-
// exitWorker
|
|
511
|
-
//
|
|
512
|
-
// Note that the worker has exited.
|
|
513
|
-
//
|
|
514
|
-
|
|
515
|
-
link.exitWorker = function exitWorker(exitCode) {
|
|
516
|
-
sender("terminated", [false, {
|
|
517
|
-
workerID: worker.workerID // notify client they've lost a worker
|
|
518
|
-
exitCode: exitCode
|
|
519
|
-
}])
|
|
520
|
-
workco.closeLink(link, conn, worker.workerID)
|
|
521
|
-
worker.detach(link)
|
|
467
|
+
function informAll(sourceID, local topDestID) {
|
|
468
|
+
for topDestID in nobbot.topsubs
|
|
469
|
+
App.imp.inform(sourceID, topDestID)
|
|
522
470
|
}
|
|
523
471
|
|
|
524
|
-
|
|
472
|
+
App.imp.addEventListener("active", function(event, info) {
|
|
473
|
+
if info.ourID == nobbot.instanceID {
|
|
474
|
+
nobbot.workerDestID = info.destID // handshake completed
|
|
475
|
+
informAll(nobbot.workerDestID) // provide path to workerID
|
|
476
|
+
nobbot.notifyAll({ // send to subscribers
|
|
477
|
+
id: "workerDestID"
|
|
478
|
+
workerDestID: nobbot.workerDestID
|
|
479
|
+
})
|
|
480
|
+
}
|
|
481
|
+
})
|
|
525
482
|
|
|
526
|
-
|
|
527
|
-
|
|
483
|
+
nobbot.impconn = App.imp.responder(function(data) {
|
|
484
|
+
nobbot.msgport.postMessage({ // send to worker
|
|
485
|
+
id: "naan-imp-node" // scoped for NodeWorkerNub
|
|
486
|
+
data: data
|
|
487
|
+
})
|
|
488
|
+
list(false, { sent: true })
|
|
489
|
+
}, {
|
|
490
|
+
ourID: nobbot.instanceID
|
|
528
491
|
})
|
|
529
|
-
sender("linked", [false, {
|
|
530
|
-
workerID: worker.workerID // notify client they've gained a worker
|
|
531
|
-
}])
|
|
532
492
|
|
|
533
493
|
// finis
|
|
534
494
|
|
|
535
|
-
|
|
495
|
+
nobbot
|
|
536
496
|
};
|
|
537
497
|
|
|
538
498
|
|
|
539
499
|
/*
|
|
540
|
-
*
|
|
500
|
+
* MakeSubProcessor
|
|
541
501
|
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
502
|
+
* Method PTY subprocess capability to CurBot and NowBot. They also need these:
|
|
503
|
+
*
|
|
504
|
+
* function impReceive(message, sourceID) { ...
|
|
505
|
+
* ...
|
|
506
|
+
* if message.id == "keyline" && nowbot.keyin
|
|
507
|
+
* execbot.keyin(message.text) // terminal keyboard -> pty subprocess
|
|
508
|
+
*
|
|
509
|
+
* function naanmsg(msg, local startmsg) { ...
|
|
510
|
+
* ...
|
|
511
|
+
* else if msg.id == "textout" && nowbot.naanin
|
|
512
|
+
* execbot.naanin(msg.text) // naan output -> pty subprocess
|
|
513
|
+
*
|
|
514
|
+
* subprocess
|
|
515
|
+
*
|
|
516
|
+
* Create a PTY subprocess and connect with the worker and terminal. You specify the path of
|
|
517
|
+
* the executable and the arguments. If no executable is specified then a shell is created. The
|
|
518
|
+
* return value is a result tuple with an object that can be used to kill or monitor the
|
|
519
|
+
* subprocess.
|
|
520
|
+
*
|
|
521
|
+
* The subprocess can be connected in a variety of ways:
|
|
522
|
+
*
|
|
523
|
+
* term-keyboard | term-display | worker-in | worker-out
|
|
524
|
+
* -------------------------------------|---------------|------------|-----------
|
|
525
|
+
* subprocess input keyboard | | | pipe
|
|
526
|
+
* subprocess output | display | tee | pipe | tee |
|
|
527
|
+
*
|
|
528
|
+
* Options:
|
|
529
|
+
* {
|
|
530
|
+
* input: false | "keyboard" | "pipe"
|
|
531
|
+
* output: false | "display" | "pipe" | "tee"
|
|
532
|
+
* spawn: <PtyManager.spawn options>
|
|
533
|
+
* }
|
|
545
534
|
*
|
|
546
535
|
*/
|
|
547
536
|
|
|
548
|
-
closure
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
iddict[workerID] = link
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
// deleteLinkForConnection
|
|
568
|
-
// Remove a link for a connection under its workerID, or false.
|
|
569
|
-
|
|
570
|
-
function deleteLinkForConnection(conn, workerID) {
|
|
571
|
-
if workco.links[conn][workerID]
|
|
572
|
-
workco.links[conn][workerID] = undefined
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
// makeSender
|
|
576
|
-
// Sender factory for specified connection and message.
|
|
577
|
-
|
|
578
|
-
closure makeSender(conn, message) {
|
|
579
|
-
function sender(respOp, payload) {
|
|
580
|
-
conn.send({
|
|
581
|
-
clientID: message.clientID
|
|
582
|
-
serverID: message.serverID
|
|
583
|
-
workerID: message.workerID
|
|
584
|
-
respOp: respOp
|
|
585
|
-
payload: payload
|
|
586
|
-
})
|
|
537
|
+
closure MakeSubProcessor(execbot) {
|
|
538
|
+
closure subprocess(
|
|
539
|
+
executable, args, options, local error, pty) {
|
|
540
|
+
|
|
541
|
+
// ptyData - text has been returned from the subprocess
|
|
542
|
+
function ptyData(text) {
|
|
543
|
+
if options.output == "display" || options.output == "tee"
|
|
544
|
+
notifyAll({ // send to display
|
|
545
|
+
id: "textout",
|
|
546
|
+
text: text
|
|
547
|
+
})
|
|
548
|
+
if options.output == "pipe" || options.output == "tee"
|
|
549
|
+
msg({ // send to NaaN worker
|
|
550
|
+
id: "keyline"
|
|
551
|
+
text: text
|
|
552
|
+
})
|
|
587
553
|
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
// makeLink
|
|
591
|
-
// Link the specified message, connection and worker.
|
|
592
|
-
|
|
593
|
-
function makeLink(message, conn, local worker, link) {
|
|
594
|
-
worker = workco.workers[message.workerID]
|
|
595
|
-
link = workLink(workco, conn, worker, makeSender(conn, message))
|
|
596
|
-
addLinkForConnection(conn, message.workerID, link)
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
// termination
|
|
600
|
-
// Note that a worker has terminated.
|
|
601
|
-
|
|
602
|
-
function termination(workerID) {
|
|
603
|
-
workco.current.vitalUpdate({
|
|
604
|
-
id: "termination", // note a thread has gone away
|
|
605
|
-
workerID: workerID
|
|
606
|
-
})
|
|
607
|
-
workco.workers[workerID] = undefined // it's like this worker has never been
|
|
608
|
-
}
|
|
609
554
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
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
|
-
list(false, worker)
|
|
646
|
-
}
|
|
555
|
+
// ptyKilled - the subprocess has terminated
|
|
556
|
+
function ptyKilled(event) {
|
|
557
|
+
if execbot.keyin === keyin
|
|
558
|
+
execbot.keyin = false
|
|
559
|
+
if execbot.naanin === naanin
|
|
560
|
+
execbot.naanin = false
|
|
561
|
+
}
|
|
647
562
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
//
|
|
652
|
-
workco.wsReceive = function wsReceive(message, conn, local worker, link, error) {
|
|
653
|
-
if !message.workerID
|
|
654
|
-
error = Error("workerID required", message.workerOp)
|
|
655
|
-
else
|
|
656
|
-
{
|
|
657
|
-
worker = workco.workers[message.workerID]
|
|
658
|
-
link = workco.links[conn][message.workerID]
|
|
659
|
-
if message.workerOp == "msgin" {
|
|
660
|
-
if worker && message.payload {
|
|
661
|
-
if !link
|
|
662
|
-
makeLink(message, conn) // make sure we have a link for responses
|
|
663
|
-
worker.msgin(message.payload) } // send message to worker
|
|
664
|
-
return }
|
|
665
|
-
else if message.workerOp == "echo" {
|
|
666
|
-
if worker && message.payload {
|
|
667
|
-
if !link
|
|
668
|
-
makeLink(message, conn) // make sure we have a link for responses
|
|
669
|
-
worker.echo(message.payload, link) } // echo message to other links
|
|
670
|
-
return }
|
|
671
|
-
else if message.workerOp == "spawn" {
|
|
672
|
-
spawn(message.workerID, message.payload, message.workerGUID)
|
|
673
|
-
if !link
|
|
674
|
-
makeLink(message, conn) // make sure we have a link for responses
|
|
675
|
-
return }
|
|
676
|
-
else if message.workerOp == "terminate" {
|
|
677
|
-
if worker {
|
|
678
|
-
if !link
|
|
679
|
-
makeLink(message, conn) // make sure we have a link for responses
|
|
680
|
-
worker.terminate() } // echo message to other links
|
|
681
|
-
return }
|
|
682
|
-
error = Error("invalid parameters", message.workerOp, message.workerID)
|
|
563
|
+
// keyin - the terminal has generated text for the subprocess
|
|
564
|
+
function keyin(text) {
|
|
565
|
+
pty.write(text)
|
|
683
566
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
// wsClose
|
|
689
|
-
//
|
|
690
|
-
// Note that the connection with the client was closed.
|
|
691
|
-
//
|
|
692
|
-
|
|
693
|
-
workco.wsClose = function wsClose(conn, local workerID, link) {
|
|
694
|
-
for workerID in workco.workers {
|
|
695
|
-
link = workco.links[conn][workerID]
|
|
696
|
-
if link
|
|
697
|
-
link.closeConn()
|
|
698
|
-
deleteLinkForConnection(conn, workerID)
|
|
567
|
+
|
|
568
|
+
// naanin - NaaN worker has generated text for the subprocess
|
|
569
|
+
function naanin(text) {
|
|
570
|
+
pty.write(text)
|
|
699
571
|
}
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
//
|
|
703
|
-
// closeLink
|
|
704
|
-
//
|
|
705
|
-
// Note that a link with the worker has closed.
|
|
706
|
-
//
|
|
707
572
|
|
|
708
|
-
|
|
709
|
-
|
|
573
|
+
`(error, pty) = PtyManager().spawn(executable, args, {
|
|
574
|
+
ptyData: ptyData
|
|
575
|
+
ptyKilled: ptyKilled
|
|
576
|
+
}, options.spawn)
|
|
577
|
+
if error
|
|
578
|
+
return (list(error))
|
|
579
|
+
if options.input == "keyboard"
|
|
580
|
+
nowbot.keyin = keyin // replace existing
|
|
581
|
+
else if options.input == "pipe"
|
|
582
|
+
execbot.naanin = naanin // replace existing
|
|
583
|
+
list(false, pty)
|
|
710
584
|
}
|
|
711
|
-
|
|
712
|
-
// finis
|
|
713
|
-
workco
|
|
714
585
|
};
|
|
715
586
|
|
|
716
587
|
|
|
@@ -722,13 +593,12 @@ closure workController(api, local workco) {
|
|
|
722
593
|
*/
|
|
723
594
|
|
|
724
595
|
function workInit(local manifest) {
|
|
725
|
-
manifest = `(
|
|
726
|
-
workController, workInit)
|
|
596
|
+
manifest = `(CurBot, NowBot, NobBot, MakeSubProcessor, workInit)
|
|
727
597
|
Naan.module.build(module.id, "worker", function(modobj, compobj) {
|
|
728
598
|
require("./node.nlg")
|
|
729
599
|
compobj.manifest = manifest
|
|
730
|
-
modobj.exports.
|
|
731
|
-
modobj.exports.
|
|
732
|
-
modobj.exports.
|
|
600
|
+
modobj.exports.CurBot = CurBot
|
|
601
|
+
modobj.exports.NowBot = NowBot
|
|
602
|
+
modobj.exports.NobBot = NobBot
|
|
733
603
|
})
|
|
734
604
|
}();
|