@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,90 +0,0 @@
|
|
|
1
|
-
import { Err } from '@quenk/noni/lib/control/error';
|
|
2
|
-
|
|
3
|
-
import { Runtime } from '../system/vm/runtime';
|
|
4
|
-
import { Address } from '../address';
|
|
5
|
-
import { Spawnable } from '../template';
|
|
6
|
-
import { Api } from '../api';
|
|
7
|
-
import { Message, Actor } from '../';
|
|
8
|
-
import { TypeCase } from '.';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Resident is an actor that exists in the current runtime.
|
|
12
|
-
*/
|
|
13
|
-
export interface Resident extends Api, Actor {}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* AbstractResident is a base implementation of a Resident actor.
|
|
17
|
-
*/
|
|
18
|
-
export abstract class AbstractResident implements Resident {
|
|
19
|
-
constructor(public runtime: Runtime) {}
|
|
20
|
-
|
|
21
|
-
self = this.runtime.self;
|
|
22
|
-
|
|
23
|
-
async notify(msg: Message) {
|
|
24
|
-
await this.runtime.notify(msg);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
spawn(target: Spawnable) {
|
|
28
|
-
return this.runtime.spawn(target);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async tell<M>(addr: Address, msg: M) {
|
|
32
|
-
await this.runtime.tell(addr, msg);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async raise(err: Err) {
|
|
36
|
-
await this.runtime.raise(err);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async kill(addr: Address) {
|
|
40
|
-
await this.runtime.kill(addr);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async exit() {
|
|
44
|
-
await this.runtime.kill(this.self);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async start() {
|
|
48
|
-
return this.run();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async run() {}
|
|
52
|
-
|
|
53
|
-
async stop() {}
|
|
54
|
-
|
|
55
|
-
async receive<T>(cases: TypeCase<T>[] = []) {
|
|
56
|
-
return this.runtime.receive(cases);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
watch<T>(task: () => Promise<T>) {
|
|
60
|
-
return this.runtime.watch(task);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Mutable actors can change their behaviour after message processing.
|
|
66
|
-
*/
|
|
67
|
-
export abstract class Mutable extends AbstractResident {}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Immutable is an actor whose behaviour does not change when a message is
|
|
71
|
-
* received.
|
|
72
|
-
*
|
|
73
|
-
* For each message received, the same set of TypeCase classes are applied.
|
|
74
|
-
* This class is useful for simple request/response style actors that do
|
|
75
|
-
* not require much complicated logic.
|
|
76
|
-
*/
|
|
77
|
-
export abstract class Immutable<T> extends AbstractResident {
|
|
78
|
-
/**
|
|
79
|
-
* selectors provides the list of TypeCase classes that will be applied to
|
|
80
|
-
* all incoming messages.
|
|
81
|
-
*/
|
|
82
|
-
selectors(): TypeCase<T>[] {
|
|
83
|
-
return [];
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async start() {
|
|
87
|
-
await this.run();
|
|
88
|
-
while (this.runtime.isValid()) await this.receive(this.selectors());
|
|
89
|
-
}
|
|
90
|
-
}
|
package/lib/actor/index.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Type } from '@quenk/noni/lib/data/type';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Message is any (ideally wire-safe) value that can be sent between actors.
|
|
5
|
-
*/
|
|
6
|
-
export type Message = Type;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Actor is the main interface implemented by actors that are part of the system.
|
|
10
|
-
*/
|
|
11
|
-
export interface Actor {
|
|
12
|
-
/**
|
|
13
|
-
* start the Actor.
|
|
14
|
-
*
|
|
15
|
-
* At this point resources have been allocated within the system for the
|
|
16
|
-
* actor and it can begin sending messages.
|
|
17
|
-
*/
|
|
18
|
-
start(): Promise<void>;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* notify is called when a message is received from another actor.
|
|
22
|
-
*
|
|
23
|
-
* Some actors may process the message immediately, others may store it to
|
|
24
|
-
* a mailbox for later.
|
|
25
|
-
*/
|
|
26
|
-
notify(m: Message): Promise<void>;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* stop the Actor.
|
|
30
|
-
*
|
|
31
|
-
* A this point resources for the actor have been removed from the system
|
|
32
|
-
* and any additional clean up needed can be done.
|
|
33
|
-
*/
|
|
34
|
-
stop(): Promise<void>;
|
|
35
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Maybe } from '@quenk/noni/lib/data/maybe';
|
|
2
|
-
|
|
3
|
-
import { Address } from '../../../address';
|
|
4
|
-
import { Template } from '../../../template';
|
|
5
|
-
import { Thread } from '../thread';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Allocator is the interface the VM delegates storage of actor threads and
|
|
9
|
-
* associated information to.
|
|
10
|
-
*/
|
|
11
|
-
export interface Allocator {
|
|
12
|
-
/**
|
|
13
|
-
* getThread provides a Thread given an Address.
|
|
14
|
-
*/
|
|
15
|
-
getThread(target: Address): Maybe<Thread>;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* getThreads provides a list of Threads given a list of Addresses.
|
|
19
|
-
*/
|
|
20
|
-
getThreads(targets: Address[]): Thread[];
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* getTemplate provides a Template given an Address.
|
|
24
|
-
*/
|
|
25
|
-
getTemplate(address: Address): Maybe<Template>;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* allocate a new thread from a Template.
|
|
29
|
-
*/
|
|
30
|
-
allocate(parent: Thread, tmpl: Template): Promise<Address>;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* reallocate resources for a Thread.
|
|
34
|
-
*
|
|
35
|
-
* This essentially means the Thread has been restarted.
|
|
36
|
-
*/
|
|
37
|
-
reallocate(target: Thread): Promise<void>;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* deallocate resources for a Thread.
|
|
41
|
-
*/
|
|
42
|
-
deallocate(target: Thread): Promise<void>;
|
|
43
|
-
}
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import * as errors from '../runtime/error';
|
|
2
|
-
|
|
3
|
-
import { Maybe } from '@quenk/noni/lib/data/maybe';
|
|
4
|
-
import { Future } from '@quenk/noni/lib/control/monad/future';
|
|
5
|
-
import { distribute, empty } from '@quenk/noni/lib/data/array';
|
|
6
|
-
import { evaluate, Lazy } from '@quenk/noni/lib/data/lazy';
|
|
7
|
-
|
|
8
|
-
import { Address, isRestricted, make } from '../../../address';
|
|
9
|
-
import {
|
|
10
|
-
SharedCreateTemplate,
|
|
11
|
-
SharedRunTemplate,
|
|
12
|
-
Template
|
|
13
|
-
} from '../../../template';
|
|
14
|
-
import {
|
|
15
|
-
EVENT_ACTOR_ALLOCATED,
|
|
16
|
-
EVENT_ACTOR_DEALLOCATED,
|
|
17
|
-
EVENT_ACTOR_STARTED,
|
|
18
|
-
EVENT_ACTOR_STOPPED
|
|
19
|
-
} from '../event';
|
|
20
|
-
import { ThreadFactory } from '../thread/factory';
|
|
21
|
-
import { JSThread } from '../thread/shared/js';
|
|
22
|
-
import { Thread } from '../thread';
|
|
23
|
-
import { Actor } from '../../..';
|
|
24
|
-
import { VM } from '..';
|
|
25
|
-
import { Allocator } from './';
|
|
26
|
-
|
|
27
|
-
const MAX_THREAD_KILL_PER_CYCLE = 25;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* ActorTableEntry is the bookkeeping record for exactly one actor within the
|
|
31
|
-
* system.
|
|
32
|
-
*/
|
|
33
|
-
export interface ActorTableEntry {
|
|
34
|
-
/**
|
|
35
|
-
* address for the actor.
|
|
36
|
-
*/
|
|
37
|
-
address: Address;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* parent is the entry for the parent actor.
|
|
41
|
-
*
|
|
42
|
-
* No parent indicates the root actor.
|
|
43
|
-
*/
|
|
44
|
-
parent: Maybe<ActorTableEntry>;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* template used to create the actor.
|
|
48
|
-
*/
|
|
49
|
-
template: Template;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* actor instance for the entry.
|
|
53
|
-
*/
|
|
54
|
-
actor: Actor;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* thread for the entry.
|
|
58
|
-
*/
|
|
59
|
-
thread: Thread;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* children entries for the actor.
|
|
63
|
-
*/
|
|
64
|
-
children: ActorTableEntry[];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* MapAllocator stores actor information in a map structure where each
|
|
69
|
-
* entry points to its parent and children.
|
|
70
|
-
*/
|
|
71
|
-
export class MapAllocator implements Allocator {
|
|
72
|
-
constructor(
|
|
73
|
-
public platform: Lazy<VM>,
|
|
74
|
-
public actors = new Map(),
|
|
75
|
-
public nextAID = 1
|
|
76
|
-
) {}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* getEntry provides the entry for an actor given its thread.
|
|
80
|
-
*/
|
|
81
|
-
getEntry(thread: Thread): Maybe<ActorTableEntry> {
|
|
82
|
-
for (let entry of this.actors.values()) {
|
|
83
|
-
if (entry.thread === thread) return Maybe.of(entry);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return Maybe.nothing();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
getThread(address: Address): Maybe<Thread> {
|
|
90
|
-
for (let entry of this.actors.values()) {
|
|
91
|
-
if (entry.address === address) return Maybe.of(entry.thread);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return Maybe.nothing();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
getThreads(targets: Address[]): Thread[] {
|
|
98
|
-
let hits = [];
|
|
99
|
-
for (let entry of this.actors.values()) {
|
|
100
|
-
if (targets.includes(entry.address)) hits.push(entry.thread);
|
|
101
|
-
}
|
|
102
|
-
return hits;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
getTemplate(address: Address): Maybe<Template> {
|
|
106
|
-
return Maybe.fromNullable(this.actors.get(address)).map(
|
|
107
|
-
(entry: ActorTableEntry) => entry.template
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async allocate(parent: Thread, template: Template): Promise<Address> {
|
|
112
|
-
let platform = evaluate(this.platform);
|
|
113
|
-
|
|
114
|
-
let isRoot = parent === platform;
|
|
115
|
-
|
|
116
|
-
let parentCons = 'vm';
|
|
117
|
-
|
|
118
|
-
let mparentEntry = Maybe.nothing<ActorTableEntry>();
|
|
119
|
-
|
|
120
|
-
if (!isRoot) {
|
|
121
|
-
mparentEntry = this.getEntry(parent);
|
|
122
|
-
|
|
123
|
-
if (mparentEntry.isNothing())
|
|
124
|
-
return Future.raise(new errors.InvalidThreadErr(parent));
|
|
125
|
-
|
|
126
|
-
parentCons = mparentEntry
|
|
127
|
-
.get()
|
|
128
|
-
.actor.constructor.name.toLowerCase();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
let aid = this.nextAID++;
|
|
132
|
-
|
|
133
|
-
let id = template.id ?? `instance::${parentCons}::aid::${aid}`;
|
|
134
|
-
|
|
135
|
-
if (isRestricted(<string>id))
|
|
136
|
-
return Future.raise(new errors.InvalidIdErr(id));
|
|
137
|
-
|
|
138
|
-
let address = make(parent.address, id);
|
|
139
|
-
|
|
140
|
-
if (this.actors.has(address))
|
|
141
|
-
return Future.raise(new errors.DuplicateAddressErr(address));
|
|
142
|
-
|
|
143
|
-
let thread = ThreadFactory.create(platform, address, template);
|
|
144
|
-
|
|
145
|
-
let actor = (<SharedCreateTemplate>template).create
|
|
146
|
-
? (<SharedCreateTemplate>template).create(<JSThread>thread)
|
|
147
|
-
: thread;
|
|
148
|
-
|
|
149
|
-
let entry = {
|
|
150
|
-
address,
|
|
151
|
-
parent: mparentEntry,
|
|
152
|
-
thread,
|
|
153
|
-
template,
|
|
154
|
-
actor: actor ?? thread,
|
|
155
|
-
children: []
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
this.actors.set(address, entry);
|
|
159
|
-
|
|
160
|
-
mparentEntry.map(parentEntry => parentEntry.children.push(entry));
|
|
161
|
-
|
|
162
|
-
if (template.group) platform.groups.enroll(address, template.group);
|
|
163
|
-
|
|
164
|
-
platform.events.dispatchActorEvent(EVENT_ACTOR_ALLOCATED, address);
|
|
165
|
-
|
|
166
|
-
platform.runTask(thread, async () => {
|
|
167
|
-
platform.events.dispatchActorEvent(
|
|
168
|
-
EVENT_ACTOR_STARTED,
|
|
169
|
-
thread.address
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
await actor.start();
|
|
173
|
-
|
|
174
|
-
if ((<SharedRunTemplate>template).run) {
|
|
175
|
-
await (<SharedRunTemplate>template).run(<JSThread>thread);
|
|
176
|
-
await this.deallocate(thread);
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
return address;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async reallocate(target: Thread): Promise<void> {
|
|
184
|
-
let mentry = this.getEntry(target);
|
|
185
|
-
|
|
186
|
-
//TODO: dispatch event and ignore?
|
|
187
|
-
if (mentry.isNothing())
|
|
188
|
-
return Future.raise(new errors.InvalidThreadErr(target));
|
|
189
|
-
|
|
190
|
-
let entry = mentry.get();
|
|
191
|
-
|
|
192
|
-
await this.deallocate(entry.thread);
|
|
193
|
-
|
|
194
|
-
let mparent = entry.parent;
|
|
195
|
-
|
|
196
|
-
// TODO: dispatch event and ignore instead?
|
|
197
|
-
if (mparent.isNothing())
|
|
198
|
-
return Future.raise(new errors.UnknownAddressErr(target.address));
|
|
199
|
-
|
|
200
|
-
await this.allocate(mparent.get().thread, entry.template);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
async deallocate(target: Thread): Promise<void> {
|
|
204
|
-
let mentry = this.getEntry(target);
|
|
205
|
-
|
|
206
|
-
if (mentry.isNothing()) return; //TODO: dispatch event
|
|
207
|
-
|
|
208
|
-
let entry = mentry.get();
|
|
209
|
-
|
|
210
|
-
// Remove the subtree from the system.
|
|
211
|
-
entry.parent.map(parent => {
|
|
212
|
-
parent.children = parent.children.filter(child => child !== entry);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
let targets = [entry];
|
|
216
|
-
|
|
217
|
-
let pending = entry.children.slice();
|
|
218
|
-
|
|
219
|
-
while (!empty(pending)) {
|
|
220
|
-
let target = <ActorTableEntry>pending.shift();
|
|
221
|
-
|
|
222
|
-
pending = [...pending, ...target.children];
|
|
223
|
-
|
|
224
|
-
targets.unshift(target);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
let platform = evaluate(this.platform);
|
|
228
|
-
|
|
229
|
-
await Future.batch(
|
|
230
|
-
distribute(
|
|
231
|
-
targets.map(target =>
|
|
232
|
-
Future.do(async () => {
|
|
233
|
-
await target.actor.stop();
|
|
234
|
-
|
|
235
|
-
await target.thread.stop();
|
|
236
|
-
|
|
237
|
-
platform.events.dispatchActorEvent(
|
|
238
|
-
EVENT_ACTOR_STOPPED,
|
|
239
|
-
target.address
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
platform.groups.unenroll(target.address);
|
|
243
|
-
|
|
244
|
-
this.actors.delete(target.address);
|
|
245
|
-
|
|
246
|
-
platform.events.dispatchActorEvent(
|
|
247
|
-
EVENT_ACTOR_DEALLOCATED,
|
|
248
|
-
target.address
|
|
249
|
-
);
|
|
250
|
-
})
|
|
251
|
-
),
|
|
252
|
-
MAX_THREAD_KILL_PER_CYCLE
|
|
253
|
-
)
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { LogSink } from './log';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* PartialConf allows only some values to be specified in a Conf object
|
|
5
|
-
* instead of all.
|
|
6
|
-
*/
|
|
7
|
-
export interface PartialConf {
|
|
8
|
-
log?: Partial<Conf['log']>;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Conf objects are used to create and configue various aspects of thhe VM.
|
|
13
|
-
*/
|
|
14
|
-
export interface Conf {
|
|
15
|
-
/**
|
|
16
|
-
* log configures the logging system.
|
|
17
|
-
*/
|
|
18
|
-
log: {
|
|
19
|
-
/**
|
|
20
|
-
* level sets the maximum log level that will be written.
|
|
21
|
-
*
|
|
22
|
-
* Defaults to info.
|
|
23
|
-
*/
|
|
24
|
-
level: string;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* sink is the destination logs will be written to.
|
|
28
|
-
*
|
|
29
|
-
* Defaults to the console object.
|
|
30
|
-
*/
|
|
31
|
-
sink: LogSink;
|
|
32
|
-
};
|
|
33
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import * as events from './';
|
|
2
|
-
|
|
3
|
-
import { evaluate, Lazy } from '@quenk/noni/lib/data/lazy';
|
|
4
|
-
|
|
5
|
-
import { LogWritable } from '../log/writer';
|
|
6
|
-
import { Address } from '../../../address';
|
|
7
|
-
import { Message } from '../../..';
|
|
8
|
-
import { EventType, InternalEvent } from './';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Handler is the type of function that receives events.
|
|
12
|
-
*/
|
|
13
|
-
export type Handler = (event: InternalEvent) => void;
|
|
14
|
-
|
|
15
|
-
const eventMap = {
|
|
16
|
-
message: new Map([
|
|
17
|
-
[events.EVENT_MESSAGE_BOUNCE, events.MessageBounceEvent],
|
|
18
|
-
[events.EVENT_MESSGAE_SEND, events.MessageSendEvent]
|
|
19
|
-
]),
|
|
20
|
-
actor: new Map([
|
|
21
|
-
[events.EVENT_ACTOR_ALLOCATED, events.ActorAllocatedEvent],
|
|
22
|
-
[events.EVENT_ACTOR_STARTED, events.ActorStartedEvent],
|
|
23
|
-
[events.EVENT_ACTOR_STOPPED, events.ActorStoppedEvent],
|
|
24
|
-
[events.EVENT_ACTOR_DEALLOCATED, events.ActorDeallocatedEvent]
|
|
25
|
-
])
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* EventDispatcher is an interface used by the internal VM components to
|
|
30
|
-
* broadcast interesting events when they occur.
|
|
31
|
-
*
|
|
32
|
-
* This interface is not meant to be used for business logic in an application
|
|
33
|
-
* but rather provides a way to inspect and troubleshoot the VM. Event dispatch
|
|
34
|
-
* is centralized here to make it clearer what events the system emits.
|
|
35
|
-
*
|
|
36
|
-
* This will also make it easier to disable some events when needed in the
|
|
37
|
-
* future.
|
|
38
|
-
*
|
|
39
|
-
* @typeparam E type of event the dispatcher dispatches.
|
|
40
|
-
*/
|
|
41
|
-
export class EventDispatcher {
|
|
42
|
-
constructor(
|
|
43
|
-
public log: Lazy<LogWritable>,
|
|
44
|
-
public handlers: Map<EventType, Handler[]> = new Map()
|
|
45
|
-
) {}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* addListener to the EventDispatcher.
|
|
49
|
-
*/
|
|
50
|
-
addEventListener(type: EventType, handler: Handler) {
|
|
51
|
-
let handlers = this.handlers.get(type) || [];
|
|
52
|
-
handlers.push(handler);
|
|
53
|
-
this.handlers.set(type, handlers);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* dispatchMessageEvent dispatches events related to message sending.
|
|
58
|
-
*/
|
|
59
|
-
dispatchMessageEvent(
|
|
60
|
-
type: EventType,
|
|
61
|
-
from: Address,
|
|
62
|
-
to: Address,
|
|
63
|
-
message: Message
|
|
64
|
-
) {
|
|
65
|
-
let Cons = eventMap.message.get(type);
|
|
66
|
-
if (Cons) this.dispatch(new Cons(from, to, message));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* dispatchActorEvent dispatches events related to actor lifecycle.
|
|
71
|
-
*/
|
|
72
|
-
dispatchActorEvent(type: EventType, actor: Address) {
|
|
73
|
-
let Cons = eventMap.actor.get(type);
|
|
74
|
-
if (Cons) this.dispatch(new Cons(actor));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* dispatch is a generic function that when called will create and dispatch
|
|
79
|
-
* the event the EventDispatcher is responsible for.
|
|
80
|
-
*/
|
|
81
|
-
dispatch(event: events.InternalEvent) {
|
|
82
|
-
evaluate(this.log).writeEvent(event);
|
|
83
|
-
for (let handler of this.handlers.get(event.type) || []) handler(event);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { Address } from '../../../address';
|
|
2
|
-
import { Message } from '../../..';
|
|
3
|
-
import { LogLevelValue } from '../log';
|
|
4
|
-
|
|
5
|
-
export const EVENT_MESSGAE_SEND = 'message-send';
|
|
6
|
-
export const EVENT_MESSAGE_BOUNCE = 'message-bounce';
|
|
7
|
-
export const EVENT_MESSAGE_DROPPED = 'message-dropped';
|
|
8
|
-
export const EVENT_ACTOR_ALLOCATED = 'actor-allocated';
|
|
9
|
-
export const EVENT_ACTOR_STARTED = 'actor-started';
|
|
10
|
-
export const EVENT_ACTOR_STOPPED = 'actor-stopped';
|
|
11
|
-
export const EVENT_ACTOR_DEALLOCATED = 'actor-deallocated';
|
|
12
|
-
export const EVENT_ACTOR_RECEIVE = 'actor-receive';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* EventType identifying an event that occurred.
|
|
16
|
-
*/
|
|
17
|
-
export type EventType = string;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* InternalEvent is the base class for all potoo events.
|
|
21
|
-
*/
|
|
22
|
-
export interface InternalEvent {
|
|
23
|
-
/**
|
|
24
|
-
* type of event.
|
|
25
|
-
*/
|
|
26
|
-
type: EventType;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* level of the event.
|
|
30
|
-
*
|
|
31
|
-
* Used by the log writer to determine when to write the event.
|
|
32
|
-
*/
|
|
33
|
-
level: LogLevelValue;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* source of the event.
|
|
37
|
-
*
|
|
38
|
-
* All events are associated with either an actor or the system itself.
|
|
39
|
-
*/
|
|
40
|
-
source: Address;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* VMEvent is the parent of all events that occur in the VM.
|
|
45
|
-
*/
|
|
46
|
-
export abstract class VMEvent implements InternalEvent {
|
|
47
|
-
abstract type: EventType;
|
|
48
|
-
|
|
49
|
-
abstract level: LogLevelValue;
|
|
50
|
-
|
|
51
|
-
constructor(public source: Address) {}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* MessageEvent is the parent of events related to message sending.
|
|
56
|
-
*/
|
|
57
|
-
export abstract class MessageEvent extends VMEvent {
|
|
58
|
-
constructor(
|
|
59
|
-
public from: Address,
|
|
60
|
-
public to: Address,
|
|
61
|
-
public message: Message
|
|
62
|
-
) {
|
|
63
|
-
super(from);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* MessageSendEvent is triggered when an actor delivers a message to another
|
|
69
|
-
* actor's thread.
|
|
70
|
-
*/
|
|
71
|
-
export class MessageSendEvent extends MessageEvent {
|
|
72
|
-
type = EVENT_MESSGAE_SEND;
|
|
73
|
-
|
|
74
|
-
level = LogLevelValue.info;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* MessageBounceEvent is triggered when an actor attempts to deliver a message
|
|
79
|
-
* to a thread that no longer exists.
|
|
80
|
-
*/
|
|
81
|
-
export class MessageBounceEvent extends MessageEvent {
|
|
82
|
-
type = EVENT_MESSAGE_BOUNCE;
|
|
83
|
-
|
|
84
|
-
level = LogLevelValue.warn;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* MessageDropEvent is triggered when an actor refuses to process a message it
|
|
89
|
-
* received.
|
|
90
|
-
*/
|
|
91
|
-
export class MessageDropEvent extends MessageEvent {
|
|
92
|
-
type = EVENT_MESSAGE_DROPPED;
|
|
93
|
-
|
|
94
|
-
level = LogLevelValue.warn;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* ActorEvent are events related toe the lifecycle of an actor.
|
|
99
|
-
*/
|
|
100
|
-
export abstract class ActorEvent extends VMEvent {
|
|
101
|
-
level = LogLevelValue.info;
|
|
102
|
-
|
|
103
|
-
constructor(public address: Address) {
|
|
104
|
-
super(address);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* ActorAllocatedEvent is triggered when an actor is allocated in the system.
|
|
110
|
-
*/
|
|
111
|
-
export class ActorAllocatedEvent extends ActorEvent {
|
|
112
|
-
type = EVENT_ACTOR_ALLOCATED;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* ActorStartedEvent is triggered when an actor is about to be started by
|
|
117
|
-
* the system.
|
|
118
|
-
*/
|
|
119
|
-
export class ActorStartedEvent extends ActorEvent {
|
|
120
|
-
type = EVENT_ACTOR_STARTED;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* ActorStoppedEvent is triggered when an actor is stopped by the system.
|
|
125
|
-
*/
|
|
126
|
-
export class ActorStoppedEvent extends ActorEvent {
|
|
127
|
-
type = EVENT_ACTOR_STOPPED;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* ActorDeallocatedEvent is triggered when an actor is deallocated from the
|
|
132
|
-
* system.
|
|
133
|
-
*/
|
|
134
|
-
export class ActorDeallocatedEvent extends ActorEvent {
|
|
135
|
-
type = EVENT_ACTOR_DEALLOCATED;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* ActorReceiveEvent is triggered when an actor attempts to receive a message.
|
|
140
|
-
*/
|
|
141
|
-
export class ActorReceiveEvent extends ActorEvent {
|
|
142
|
-
type = EVENT_ACTOR_RECEIVE;
|
|
143
|
-
}
|