@quenk/potoo 4.0.7 → 4.0.11
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/lib/actor/address.js.map +1 -1
- package/lib/actor/api.d.ts +2 -2
- package/lib/actor/api.js.map +1 -1
- package/lib/actor/framework/index.js +2 -2
- package/lib/actor/framework/index.js.map +1 -1
- package/lib/actor/framework/process.d.ts +3 -2
- package/lib/actor/framework/process.js.map +1 -1
- package/lib/actor/framework/resident.d.ts +5 -3
- package/lib/actor/framework/resident.js +2 -0
- package/lib/actor/framework/resident.js.map +1 -1
- package/lib/actor/index.js.map +1 -1
- package/lib/actor/system/vm/allocator/index.js.map +1 -1
- package/lib/actor/system/vm/allocator/map.js +7 -4
- package/lib/actor/system/vm/allocator/map.js.map +1 -1
- package/lib/actor/system/vm/conf.js.map +1 -1
- package/lib/actor/system/vm/event/dispatcher.d.ts +31 -12
- package/lib/actor/system/vm/event/dispatcher.js +72 -20
- package/lib/actor/system/vm/event/dispatcher.js.map +1 -1
- package/lib/actor/system/vm/event/index.js.map +1 -1
- package/lib/actor/system/vm/frame.js.map +1 -1
- package/lib/actor/system/vm/group.js.map +1 -1
- package/lib/actor/system/vm/index.js +2 -2
- package/lib/actor/system/vm/index.js.map +1 -1
- package/lib/actor/system/vm/log/index.js.map +1 -1
- package/lib/actor/system/vm/log/writer.js.map +1 -1
- package/lib/actor/system/vm/object/foreign.js.map +1 -1
- package/lib/actor/system/vm/object/index.js.map +1 -1
- package/lib/actor/system/vm/object/list.js.map +1 -1
- package/lib/actor/system/vm/op/actor.js.map +1 -1
- package/lib/actor/system/vm/op/base.js.map +1 -1
- package/lib/actor/system/vm/op/index.js.map +1 -1
- package/lib/actor/system/vm/op/object.js.map +1 -1
- package/lib/actor/system/vm/registry.js.map +1 -1
- package/lib/actor/system/vm/runtime/error.js.map +1 -1
- package/lib/actor/system/vm/runtime.js.map +1 -1
- package/lib/actor/system/vm/scheduler.js.map +1 -1
- package/lib/actor/system/vm/script/index.js.map +1 -1
- package/lib/actor/system/vm/script/info.js.map +1 -1
- package/lib/actor/system/vm/strategy/error.js.map +1 -1
- package/lib/actor/system/vm/thread/factory.js.map +1 -1
- package/lib/actor/system/vm/thread/index.js.map +1 -1
- package/lib/actor/system/vm/thread/process.js.map +1 -1
- package/lib/actor/system/vm/thread/shared/index.js.map +1 -1
- package/lib/actor/system/vm/thread/shared/js.d.ts +2 -2
- package/lib/actor/system/vm/thread/shared/js.js +3 -3
- package/lib/actor/system/vm/thread/shared/js.js.map +1 -1
- package/lib/actor/system/vm/type.js.map +1 -1
- package/lib/actor/template.d.ts +20 -0
- package/lib/actor/template.js +17 -1
- package/lib/actor/template.js.map +1 -1
- package/package.json +11 -9
- package/lib/actor/address.ts +0 -90
- package/lib/actor/api.ts +0 -57
- package/lib/actor/framework/index.ts +0 -1
- package/lib/actor/framework/process.ts +0 -87
- package/lib/actor/framework/resident.ts +0 -90
- package/lib/actor/index.ts +0 -35
- package/lib/actor/system/vm/allocator/index.ts +0 -43
- package/lib/actor/system/vm/allocator/map.ts +0 -256
- package/lib/actor/system/vm/conf.ts +0 -33
- package/lib/actor/system/vm/event/dispatcher.ts +0 -85
- package/lib/actor/system/vm/event/index.ts +0 -143
- package/lib/actor/system/vm/frame.ts +0 -484
- package/lib/actor/system/vm/group.ts +0 -46
- package/lib/actor/system/vm/index.ts +0 -230
- package/lib/actor/system/vm/log/index.ts +0 -73
- package/lib/actor/system/vm/log/writer.ts +0 -96
- package/lib/actor/system/vm/object/foreign.ts +0 -10
- package/lib/actor/system/vm/object/index.ts +0 -4
- package/lib/actor/system/vm/object/list.ts +0 -8
- package/lib/actor/system/vm/op/actor.ts +0 -126
- package/lib/actor/system/vm/op/base.ts +0 -243
- package/lib/actor/system/vm/op/index.ts +0 -388
- package/lib/actor/system/vm/op/object.ts +0 -81
- package/lib/actor/system/vm/registry.ts +0 -223
- package/lib/actor/system/vm/runtime/error.ts +0 -248
- package/lib/actor/system/vm/runtime.ts +0 -31
- package/lib/actor/system/vm/scheduler.ts +0 -108
- package/lib/actor/system/vm/script/index.ts +0 -64
- package/lib/actor/system/vm/script/info.ts +0 -359
- package/lib/actor/system/vm/strategy/error.ts +0 -88
- package/lib/actor/system/vm/thread/factory.ts +0 -29
- package/lib/actor/system/vm/thread/index.ts +0 -29
- package/lib/actor/system/vm/thread/process.ts +0 -134
- package/lib/actor/system/vm/thread/shared/index.ts +0 -50
- package/lib/actor/system/vm/thread/shared/js.ts +0 -151
- package/lib/actor/system/vm/type.ts +0 -115
- package/lib/actor/template.ts +0 -170
- package/lib/tsconfig.json +0 -22
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
import * as types from '../type';
|
|
2
|
-
|
|
3
|
-
import { ForeignFun, TypeDescriptor } from '../type';
|
|
4
|
-
import { Instruction } from '../op';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Info objects provide important information about named identifiers appearing
|
|
8
|
-
* in the compiled source.
|
|
9
|
-
*/
|
|
10
|
-
export interface Info {
|
|
11
|
-
/**
|
|
12
|
-
* type is the TypeInfo object of the indentifier.
|
|
13
|
-
*/
|
|
14
|
-
type: TypeInfo;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* name of the identifier as it appears in source text.
|
|
18
|
-
*/
|
|
19
|
-
name: string;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* descriptor
|
|
23
|
-
*/
|
|
24
|
-
descriptor: TypeDescriptor;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* TypeInfo holds type information about a named identifier.
|
|
29
|
-
*
|
|
30
|
-
* In effect, it describes the constructor of a symbol and is itself a symbol.
|
|
31
|
-
*/
|
|
32
|
-
export interface TypeInfo extends Info {
|
|
33
|
-
/**
|
|
34
|
-
* properties is an array of property info objects that describe the
|
|
35
|
-
* properties of objects created with this constructor.
|
|
36
|
-
*/
|
|
37
|
-
properties: PropInfo[];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* ArrayTypeInfo is a TypeInfo for array types.
|
|
42
|
-
*
|
|
43
|
-
* This structure exists because arrays can be recursive and may need to
|
|
44
|
-
* retain nested type information on their elements.
|
|
45
|
-
*/
|
|
46
|
-
export interface ArrayTypeInfo extends TypeInfo {
|
|
47
|
-
/**
|
|
48
|
-
* elements indicates the type of the array's elements.
|
|
49
|
-
*/
|
|
50
|
-
elements: TypeInfo;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* FunInfo maintains information about compiled functions.
|
|
55
|
-
*/
|
|
56
|
-
export interface FunInfo extends Info {
|
|
57
|
-
/**
|
|
58
|
-
* argc is the argument count of the function.
|
|
59
|
-
*/
|
|
60
|
-
argc: number;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* code section.
|
|
64
|
-
*/
|
|
65
|
-
code: Instruction[];
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* foreign indicates whether the function is implemented using a JS
|
|
69
|
-
* function.
|
|
70
|
-
* If so, the exec property must be provided.
|
|
71
|
-
*/
|
|
72
|
-
foreign: boolean;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* ForeignFunInfo maintains information about foreigin functions.
|
|
77
|
-
*/
|
|
78
|
-
export interface ForeignFunInfo extends FunInfo {
|
|
79
|
-
/**
|
|
80
|
-
* exec (foreign only).
|
|
81
|
-
*/
|
|
82
|
-
exec: ForeignFun;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* PropInfo holds information about a property on an object.
|
|
87
|
-
*/
|
|
88
|
-
export interface PropInfo {
|
|
89
|
-
/**
|
|
90
|
-
* name of the property.
|
|
91
|
-
*/
|
|
92
|
-
name: string;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* type information about the property.
|
|
96
|
-
*/
|
|
97
|
-
type: TypeInfo;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* NewInfo
|
|
102
|
-
*/
|
|
103
|
-
export abstract class NewInfo implements Info {
|
|
104
|
-
constructor(public name: string) {}
|
|
105
|
-
|
|
106
|
-
abstract type: TypeInfo;
|
|
107
|
-
|
|
108
|
-
abstract descriptor: number;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* VoidInfo
|
|
113
|
-
*/
|
|
114
|
-
export class VoidInfo extends NewInfo {
|
|
115
|
-
type = voidType;
|
|
116
|
-
|
|
117
|
-
descriptor = types.TYPE_VOID;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* NewUInt8Info
|
|
122
|
-
*/
|
|
123
|
-
export class NewUInt8Info extends NewInfo {
|
|
124
|
-
type = uint8Type;
|
|
125
|
-
|
|
126
|
-
descriptor = types.TYPE_UINT8;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* NewUInt16Info
|
|
131
|
-
*/
|
|
132
|
-
export class NewUInt16Info extends NewInfo {
|
|
133
|
-
type = uint16Type;
|
|
134
|
-
|
|
135
|
-
descriptor = types.TYPE_UINT16;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* NewUInt32Info
|
|
140
|
-
*/
|
|
141
|
-
export class NewUInt32Info extends NewInfo {
|
|
142
|
-
type = uint32Type;
|
|
143
|
-
|
|
144
|
-
descriptor = types.TYPE_UINT32;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* NewInt8Info
|
|
149
|
-
*/
|
|
150
|
-
export class NewInt8Info extends NewInfo {
|
|
151
|
-
type = int8Type;
|
|
152
|
-
|
|
153
|
-
descriptor = types.TYPE_INT8;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* NewInt16Info
|
|
158
|
-
*/
|
|
159
|
-
export class NewInt16Info extends NewInfo {
|
|
160
|
-
type = int16Type;
|
|
161
|
-
|
|
162
|
-
descriptor = types.TYPE_INT16;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* NewInt32Info
|
|
167
|
-
*/
|
|
168
|
-
export class NewInt32Info extends NewInfo {
|
|
169
|
-
type = int32Type;
|
|
170
|
-
|
|
171
|
-
descriptor = types.TYPE_INT32;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* NewBooleanInfo
|
|
176
|
-
*/
|
|
177
|
-
export class NewBooleanInfo extends NewInfo {
|
|
178
|
-
type = booleanType;
|
|
179
|
-
|
|
180
|
-
descriptor = types.TYPE_BOOLEAN;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* NewStringInfo
|
|
185
|
-
*/
|
|
186
|
-
export class NewStringInfo extends NewInfo {
|
|
187
|
-
type = stringType;
|
|
188
|
-
|
|
189
|
-
descriptor = types.TYPE_STRING;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* NewObjectInfo
|
|
194
|
-
*/
|
|
195
|
-
export class NewObjectInfo extends NewInfo {
|
|
196
|
-
type = objectType;
|
|
197
|
-
|
|
198
|
-
descriptor = types.TYPE_OBJECT;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* NewArrayInfo
|
|
203
|
-
*/
|
|
204
|
-
export class NewArrayInfo extends NewInfo {
|
|
205
|
-
constructor(public name: string, public type: ArrayTypeInfo) {
|
|
206
|
-
super(name);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
descriptor = types.TYPE_LIST;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* NewFunInfo
|
|
214
|
-
*/
|
|
215
|
-
export class NewFunInfo extends NewInfo implements FunInfo {
|
|
216
|
-
constructor(
|
|
217
|
-
public name: string,
|
|
218
|
-
public argc: number,
|
|
219
|
-
public code: Instruction[]
|
|
220
|
-
) {
|
|
221
|
-
super(name);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
type = funType;
|
|
225
|
-
|
|
226
|
-
descriptor = types.TYPE_FUN;
|
|
227
|
-
|
|
228
|
-
foreign = false;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* NewForeignFunInfo
|
|
233
|
-
*/
|
|
234
|
-
export class NewForeignFunInfo extends NewInfo implements FunInfo {
|
|
235
|
-
constructor(
|
|
236
|
-
public name: string,
|
|
237
|
-
public argc: number,
|
|
238
|
-
public exec: ForeignFun
|
|
239
|
-
) {
|
|
240
|
-
super(name);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
type = funType;
|
|
244
|
-
|
|
245
|
-
descriptor = types.TYPE_FUN;
|
|
246
|
-
|
|
247
|
-
foreign = true;
|
|
248
|
-
|
|
249
|
-
code = [];
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* NewTypeInfo
|
|
254
|
-
*/
|
|
255
|
-
export class NewTypeInfo extends NewInfo implements TypeInfo {
|
|
256
|
-
constructor(
|
|
257
|
-
public name: string,
|
|
258
|
-
public argc: number,
|
|
259
|
-
public properties: PropInfo[],
|
|
260
|
-
public descriptor = types.TYPE_OBJECT
|
|
261
|
-
) {
|
|
262
|
-
super(name);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
type = funType;
|
|
266
|
-
|
|
267
|
-
code = [];
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* NewArrayTypeInfo
|
|
272
|
-
*/
|
|
273
|
-
export class NewArrayTypeInfo extends NewInfo implements ArrayTypeInfo {
|
|
274
|
-
constructor(public name: string, public elements: TypeInfo) {
|
|
275
|
-
super(name);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
type = funType;
|
|
279
|
-
|
|
280
|
-
argc = 0;
|
|
281
|
-
|
|
282
|
-
properties = [];
|
|
283
|
-
|
|
284
|
-
code = [];
|
|
285
|
-
|
|
286
|
-
descriptor = types.TYPE_LIST;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* NewPropInfo
|
|
291
|
-
*/
|
|
292
|
-
export class NewPropInfo implements PropInfo {
|
|
293
|
-
constructor(public name: string, public type: TypeInfo) {}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* voidType constructor.
|
|
298
|
-
*/
|
|
299
|
-
export const voidType = new NewTypeInfo('void', 0, [], types.TYPE_VOID);
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* int8Type constructor.
|
|
303
|
-
*/
|
|
304
|
-
export const int8Type = new NewTypeInfo('int8', 1, [], types.TYPE_INT8);
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* int16Type constructor.
|
|
308
|
-
*/
|
|
309
|
-
export const int16Type = new NewTypeInfo('int16', 1, [], types.TYPE_INT16);
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* int32type constructor.
|
|
313
|
-
*/
|
|
314
|
-
export const int32Type = new NewTypeInfo('int32', 1, [], types.TYPE_INT32);
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* uint8Type constructor.
|
|
318
|
-
*/
|
|
319
|
-
export const uint8Type = new NewTypeInfo('uint8', 1, [], types.TYPE_UINT8);
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* uint16Type constructor.
|
|
323
|
-
*/
|
|
324
|
-
export const uint16Type = new NewTypeInfo('uint16', 1, [], types.TYPE_UINT16);
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* uint32type constructor.
|
|
328
|
-
*/
|
|
329
|
-
export const uint32Type = new NewTypeInfo('uint32', 1, [], types.TYPE_UINT32);
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* booleanType constructor.
|
|
333
|
-
*/
|
|
334
|
-
export const booleanType = new NewTypeInfo(
|
|
335
|
-
'boolean',
|
|
336
|
-
1,
|
|
337
|
-
[],
|
|
338
|
-
types.TYPE_BOOLEAN
|
|
339
|
-
);
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* stringType constructor.
|
|
343
|
-
*/
|
|
344
|
-
export const stringType = new NewTypeInfo('string', 1, [], types.TYPE_STRING);
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* arrayType constructor.
|
|
348
|
-
*/
|
|
349
|
-
export const arrayType = new NewTypeInfo('array', 0, [], types.TYPE_LIST);
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* objectCons
|
|
353
|
-
*/
|
|
354
|
-
export const objectType = new NewTypeInfo('object', 0, [], types.TYPE_OBJECT);
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* funType
|
|
358
|
-
*/
|
|
359
|
-
export const funType = new NewTypeInfo('function', 0, [], types.TYPE_FUN);
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import * as template from '../../../template';
|
|
2
|
-
import * as errors from '../runtime/error';
|
|
3
|
-
|
|
4
|
-
import { Err, toError } from '@quenk/noni/lib/control/err';
|
|
5
|
-
|
|
6
|
-
import { ADDRESS_SYSTEM, getParent } from '../../../address';
|
|
7
|
-
import { Thread } from '../thread';
|
|
8
|
-
import { Allocator } from '../allocator';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* ErrorStrategy is the interface used by threads to communicate errors that
|
|
12
|
-
* have occurred within the system.
|
|
13
|
-
*
|
|
14
|
-
* Error handling is mostly dictated by the result of the template's trap
|
|
15
|
-
* function however, when that function is not specified, the strategy determines
|
|
16
|
-
* what to do.
|
|
17
|
-
*/
|
|
18
|
-
export interface ErrorStrategy {
|
|
19
|
-
/**
|
|
20
|
-
* raise an error within the system.
|
|
21
|
-
*
|
|
22
|
-
* The error will be subject to the strategy's error handling algorithm.
|
|
23
|
-
*/
|
|
24
|
-
raise(src: Thread, err: Err): Promise<void>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* SupervisorErrorStrategy defaults to raising the error with the parent actor
|
|
29
|
-
* if no trap function is specified.
|
|
30
|
-
*/
|
|
31
|
-
export class SupervisorErrorStrategy implements ErrorStrategy {
|
|
32
|
-
constructor(public allocator: Allocator) {}
|
|
33
|
-
|
|
34
|
-
async raise(src: Thread, error: Err) {
|
|
35
|
-
let prevThread;
|
|
36
|
-
|
|
37
|
-
let err = error;
|
|
38
|
-
|
|
39
|
-
let currentThread = src;
|
|
40
|
-
|
|
41
|
-
let allocator = this.allocator;
|
|
42
|
-
|
|
43
|
-
while (true) {
|
|
44
|
-
if (prevThread) {
|
|
45
|
-
await allocator.deallocate(prevThread);
|
|
46
|
-
let mcurrentThread = allocator.getThread(
|
|
47
|
-
getParent(prevThread.address)
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
//TODO: warn thread not found.
|
|
51
|
-
if (mcurrentThread.isNothing()) break;
|
|
52
|
-
|
|
53
|
-
currentThread = mcurrentThread.get();
|
|
54
|
-
|
|
55
|
-
err = new errors.ActorTerminatedErr(
|
|
56
|
-
currentThread.address,
|
|
57
|
-
src.address,
|
|
58
|
-
error
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
let tmpl = allocator.getTemplate(currentThread.address).get();
|
|
63
|
-
|
|
64
|
-
let trap = tmpl.trap ?? defaultTrap;
|
|
65
|
-
|
|
66
|
-
let action = trap(err);
|
|
67
|
-
|
|
68
|
-
if (action === template.ACTION_IGNORE) {
|
|
69
|
-
//TODO: Should the thread be put back in the idle state?
|
|
70
|
-
return;
|
|
71
|
-
} else if (action === template.ACTION_RESTART) {
|
|
72
|
-
await allocator.reallocate(currentThread);
|
|
73
|
-
return;
|
|
74
|
-
} else if (action === template.ACTION_STOP) {
|
|
75
|
-
await allocator.deallocate(currentThread);
|
|
76
|
-
return;
|
|
77
|
-
} else if (currentThread.address === ADDRESS_SYSTEM) {
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
prevThread = currentThread;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
throw toError(err);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const defaultTrap = () => template.ACTION_RAISE;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { Address } from '../../../address';
|
|
2
|
-
import {
|
|
3
|
-
isProcessTemplate,
|
|
4
|
-
ProcessTemplate,
|
|
5
|
-
Template
|
|
6
|
-
} from '../../../template';
|
|
7
|
-
import { VM } from '..';
|
|
8
|
-
import { JSThread } from './shared/js';
|
|
9
|
-
import { ProcessThread } from './process';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* ThreadFactory creates Thread implementations based on the provided
|
|
13
|
-
* TemplateType.
|
|
14
|
-
*/
|
|
15
|
-
export class ThreadFactory {
|
|
16
|
-
/**
|
|
17
|
-
* create a new instance of a Thread for the given TemplateType.
|
|
18
|
-
*/
|
|
19
|
-
static create(vm: VM, address: Address, template: Template) {
|
|
20
|
-
if (isProcessTemplate(template))
|
|
21
|
-
return ProcessThread.create(
|
|
22
|
-
vm,
|
|
23
|
-
address,
|
|
24
|
-
(<ProcessTemplate>template).script
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
return new JSThread(vm, address);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { Err } from '@quenk/noni/lib/control/err';
|
|
2
|
-
|
|
3
|
-
import { Address } from '../../../address';
|
|
4
|
-
import { Actor } from '../../..';
|
|
5
|
-
|
|
6
|
-
export const ERR_THREAD_INVALID = 'ERR_THREAD_INVALID';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Thread serves as the execution context for a single actor.
|
|
10
|
-
*
|
|
11
|
-
* Coincidentally, Threads are themselves actors as far as the system is
|
|
12
|
-
* concerned. This design allows any external code to simply allocate a Thread
|
|
13
|
-
* and use it to communicate with the system without having to extend internal
|
|
14
|
-
* classes or re-implement existing logic.
|
|
15
|
-
*
|
|
16
|
-
* Threads are of course, not actual OS threads but rather an abstract of the
|
|
17
|
-
* VM used to make managing actors easier.
|
|
18
|
-
*/
|
|
19
|
-
export interface Thread extends Actor {
|
|
20
|
-
/**
|
|
21
|
-
* address for the Thread (actor) within the system.
|
|
22
|
-
*/
|
|
23
|
-
address: Address;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* raise an error triggering the system's error handling machinery.
|
|
27
|
-
*/
|
|
28
|
-
raise(e: Err): Promise<void>;
|
|
29
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'path';
|
|
2
|
-
import { ChildProcess, fork } from 'child_process';
|
|
3
|
-
|
|
4
|
-
import { Err } from '@quenk/noni/lib/control/err';
|
|
5
|
-
import { Path } from '@quenk/noni/lib/data/record/path';
|
|
6
|
-
import { Any, test } from '@quenk/noni/lib/data/type';
|
|
7
|
-
|
|
8
|
-
import { Address } from '../../../address';
|
|
9
|
-
import { Message } from '../../..';
|
|
10
|
-
import { VM } from '../';
|
|
11
|
-
import { Thread } from '.';
|
|
12
|
-
|
|
13
|
-
export const CTRL_MSG_RAISE = 9;
|
|
14
|
-
export const CTRL_MSG_SEND = 1;
|
|
15
|
-
export const CTRL_MSG_DROP = 3;
|
|
16
|
-
|
|
17
|
-
const shapes = {
|
|
18
|
-
raise: {
|
|
19
|
-
code: CTRL_MSG_RAISE,
|
|
20
|
-
|
|
21
|
-
src: String,
|
|
22
|
-
|
|
23
|
-
dest: String,
|
|
24
|
-
|
|
25
|
-
message: String,
|
|
26
|
-
|
|
27
|
-
stack: String
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
send: {
|
|
31
|
-
to: String,
|
|
32
|
-
|
|
33
|
-
from: String,
|
|
34
|
-
|
|
35
|
-
message: Any
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
drop: {
|
|
39
|
-
code: CTRL_MSG_DROP,
|
|
40
|
-
|
|
41
|
-
from: String,
|
|
42
|
-
|
|
43
|
-
to: String,
|
|
44
|
-
|
|
45
|
-
message: Any
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* ProcessThread is used for actors created via ChildProcess instances.
|
|
51
|
-
*
|
|
52
|
-
* The child process script is treated as a single actor as far as the VM is
|
|
53
|
-
* concerned.
|
|
54
|
-
*/
|
|
55
|
-
export class ProcessThread implements Thread {
|
|
56
|
-
constructor(
|
|
57
|
-
public vm: VM,
|
|
58
|
-
public process: ChildProcess,
|
|
59
|
-
public address: Address
|
|
60
|
-
) {}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* create a new ProcessThread instance using the provided script path for
|
|
64
|
-
* the ChildProcess creation.
|
|
65
|
-
*
|
|
66
|
-
* The child process will have access to the following environment variables:
|
|
67
|
-
*
|
|
68
|
-
* 1. POTOO_ACTOR_ADDRESS The full address of the actor in the parent VM.
|
|
69
|
-
*/
|
|
70
|
-
static create(vm: VM, address: Address, script: Path): ProcessThread {
|
|
71
|
-
let cp = fork(resolve(script), {
|
|
72
|
-
env: { POTOO_ACTOR_ADDRESS: address }
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
let thread = new ProcessThread(vm, cp, address);
|
|
76
|
-
|
|
77
|
-
return thread;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async notify(msg: Message) {
|
|
81
|
-
this.process.send(msg);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async raise(err: Err) {
|
|
85
|
-
await this.vm.errors.raise(this, err);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* start the ProcessThread.
|
|
90
|
-
*
|
|
91
|
-
* The following event handlers are installed on the child process:
|
|
92
|
-
*
|
|
93
|
-
* 1. "error" - will raise through the error handling machinery.
|
|
94
|
-
* 2. "message - will forward messages in the correct format from the child
|
|
95
|
-
* process to other actors in the system.
|
|
96
|
-
* 3. "exit" - will signal to the VM to kill this actor.
|
|
97
|
-
*/
|
|
98
|
-
async start() {
|
|
99
|
-
let { vm, address } = this;
|
|
100
|
-
|
|
101
|
-
let cp = this.process;
|
|
102
|
-
|
|
103
|
-
cp.on('error', (err: Error) => this.raise(err));
|
|
104
|
-
|
|
105
|
-
if (cp.stderr)
|
|
106
|
-
cp.stderr.on('data', data => console.error(`${address}: ${data}`));
|
|
107
|
-
|
|
108
|
-
if (cp.stdout)
|
|
109
|
-
cp.stdout.on('data', data => console.log(`${address}: ${data}`));
|
|
110
|
-
|
|
111
|
-
cp.on('message', async (m: Message) => {
|
|
112
|
-
if (test(shapes.raise, m)) {
|
|
113
|
-
let { message, stack } = m;
|
|
114
|
-
let err = new Error(message);
|
|
115
|
-
|
|
116
|
-
err.stack = stack;
|
|
117
|
-
this.raise(err);
|
|
118
|
-
} else if (test(shapes.send, m)) {
|
|
119
|
-
let { to, message } = m;
|
|
120
|
-
await vm.sendMessage(this, to, message);
|
|
121
|
-
} else {
|
|
122
|
-
//TODO: Publish drop event.
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
cp.on('exit', () => {
|
|
127
|
-
vm.sendKillSignal(this, address);
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async stop() {
|
|
132
|
-
this.process.kill();
|
|
133
|
-
}
|
|
134
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Err } from '@quenk/noni/lib/control/error';
|
|
2
|
-
|
|
3
|
-
import { Thread } from '../';
|
|
4
|
-
|
|
5
|
-
export const THREAD_STATE_IDLE = 0;
|
|
6
|
-
export const THREAD_STATE_RUN = 1;
|
|
7
|
-
export const THREAD_STATE_MSG_WAIT = 2;
|
|
8
|
-
export const THREAD_STATE_ASYNC_WAIT = 3;
|
|
9
|
-
export const THREAD_STATE_ERROR = 4;
|
|
10
|
-
export const THREAD_STATE_INVALID = 5;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* ThreadState is a number corresponding to one of the THREAD_STATE_X constants.
|
|
14
|
-
*/
|
|
15
|
-
export enum ThreadState {
|
|
16
|
-
IDLE = THREAD_STATE_IDLE,
|
|
17
|
-
RUNNING = THREAD_STATE_RUN,
|
|
18
|
-
MSG_WAIT = THREAD_STATE_MSG_WAIT,
|
|
19
|
-
ASYNC_WAIT = THREAD_STATE_ASYNC_WAIT,
|
|
20
|
-
ERROR = THREAD_STATE_ERROR,
|
|
21
|
-
INVALID = THREAD_STATE_INVALID
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const ERR_THREAD_INVALID = 'ERR_THREAD_INVALID';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* SharedThread is one that shares the JavaScript event loop with other threads.
|
|
28
|
-
*
|
|
29
|
-
* Due to the design of JavaScript engines, only one of these threads can
|
|
30
|
-
* actively execute at a time meaning the actors have to share execution time
|
|
31
|
-
* via the Scheduler.
|
|
32
|
-
*/
|
|
33
|
-
export interface SharedThread extends Thread {
|
|
34
|
-
/**
|
|
35
|
-
* state of the Thread.
|
|
36
|
-
*
|
|
37
|
-
* Used by the scheduler to determine execution order.
|
|
38
|
-
*/
|
|
39
|
-
state: ThreadState;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* raise an error triggering the system's error handling machinery.
|
|
43
|
-
*/
|
|
44
|
-
raise(e: Err): Promise<void>;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* resume marks the Thread as ready to run again.
|
|
48
|
-
*/
|
|
49
|
-
resume(): void;
|
|
50
|
-
}
|