closes #19: kill underlings with system level interrupts
This commit is contained in:
@@ -512,8 +512,8 @@ $_.stop = function stop(actor) {
|
|||||||
throw new Error('Can only call stop on an actor.')
|
throw new Error('Can only call stop on an actor.')
|
||||||
if (!underlings.has(actor[ACTORDATA].id))
|
if (!underlings.has(actor[ACTORDATA].id))
|
||||||
throw new Error('Can only call stop on an underling or self.')
|
throw new Error('Can only call stop on an underling or self.')
|
||||||
|
|
||||||
sys_msg(actor, {kind:"stop"})
|
sys_msg(actor, "stop")
|
||||||
}
|
}
|
||||||
$_.stop[cell.DOC] = "The stop function stops an underling."
|
$_.stop[cell.DOC] = "The stop function stops an underling."
|
||||||
|
|
||||||
@@ -712,14 +712,13 @@ function handle_sysym(msg, from)
|
|||||||
{
|
{
|
||||||
switch(msg.kind) {
|
switch(msg.kind) {
|
||||||
case 'stop':
|
case 'stop':
|
||||||
if (from[ACTORDATA].id !== overling[ACTORDATA].id)
|
disrupt("got stop message")
|
||||||
log.error(`Got a message from a random actor ${msg.id} to stop`)
|
|
||||||
else
|
|
||||||
disrupt("got stop message")
|
|
||||||
break
|
break
|
||||||
case 'underling':
|
case 'underling':
|
||||||
var greeter = greeters[from[ACTORDATA].id]
|
var greeter = greeters[from[ACTORDATA].id]
|
||||||
if (greeter) greeter(msg.message)
|
if (greeter) greeter(msg.message)
|
||||||
|
if (msg.message.type == 'disrupt')
|
||||||
|
underlings.delete(from[ACTORDATA].id)
|
||||||
break
|
break
|
||||||
case 'contact':
|
case 'contact':
|
||||||
if (portal_fn) {
|
if (portal_fn) {
|
||||||
@@ -810,10 +809,14 @@ var progContent = io.slurp(prog)
|
|||||||
|
|
||||||
var prog_script = `(function ${cell.args.program.name()}_start($_, arg) { var args = arg; ${progContent} })`
|
var prog_script = `(function ${cell.args.program.name()}_start($_, arg) { var args = arg; ${progContent} })`
|
||||||
|
|
||||||
var val = js.eval(cell.args.program, prog_script)($_, cell.args.arg)
|
// queue up its first turn instead of run immediately
|
||||||
if (val)
|
|
||||||
throw new Error('Program must not return anything');
|
|
||||||
|
|
||||||
send_messages()
|
var startfn = js.eval(cell.args.program, prog_script);
|
||||||
|
$_.delay(_ => {
|
||||||
|
var val = startfn($_, cell.args.arg);
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
throw new Error('Program must not return anything');
|
||||||
|
}, 0)
|
||||||
|
|
||||||
})()
|
})()
|
||||||
@@ -14,7 +14,8 @@ if (arg.length === 0)
|
|||||||
'text',
|
'text',
|
||||||
'http',
|
'http',
|
||||||
'use',
|
'use',
|
||||||
'parseq'
|
'parseq',
|
||||||
|
'kill'
|
||||||
]
|
]
|
||||||
|
|
||||||
for (var test of def)
|
for (var test of def)
|
||||||
|
|||||||
@@ -702,8 +702,6 @@ int uncaught_exception(JSContext *js, JSValue v)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("UNCAUGHT EXCEPTION IN ACTOR %s\n", rt->id);
|
|
||||||
|
|
||||||
JSValue exp = JS_GetException(js);
|
JSValue exp = JS_GetException(js);
|
||||||
|
|
||||||
JSValue ret = JS_Call(js, rt->on_exception, JS_UNDEFINED, 1, &exp);
|
JSValue ret = JS_Call(js, rt->on_exception, JS_UNDEFINED, 1, &exp);
|
||||||
|
|||||||
@@ -88,10 +88,29 @@ JSC_CCALL(os_mailbox_push,
|
|||||||
|
|
||||||
const char *id = JS_ToCString(js, argv[0]);
|
const char *id = JS_ToCString(js, argv[0]);
|
||||||
int exist = actor_exists(id);
|
int exist = actor_exists(id);
|
||||||
JS_FreeCString(js,id);
|
|
||||||
if (!exist)
|
|
||||||
return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
|
||||||
|
|
||||||
|
if (!exist) {
|
||||||
|
JS_FreeCString(js,id);
|
||||||
|
return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_rt *target = get_actor(id);
|
||||||
|
JS_FreeCString(js,id);
|
||||||
|
|
||||||
|
JSValue sys = JS_GetPropertyStr(js, argv[1], "__SYSTEM__");
|
||||||
|
if (!JS_IsUndefined(sys)) {
|
||||||
|
const char *k = JS_ToCString(js,sys);
|
||||||
|
int stop = 0;
|
||||||
|
if (strcmp(k, "stop") == 0) {
|
||||||
|
stop = 1;
|
||||||
|
actor_disrupt(target);
|
||||||
|
}
|
||||||
|
JS_FreeValue(js,sys);
|
||||||
|
JS_FreeCString(js,k);
|
||||||
|
|
||||||
|
if (stop) return JS_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
void *data = value2wota(js, argv[1], JS_UNDEFINED);
|
void *data = value2wota(js, argv[1], JS_UNDEFINED);
|
||||||
|
|
||||||
const char *err = send_message(id, data);
|
const char *err = send_message(id, data);
|
||||||
@@ -138,11 +157,6 @@ JSC_SCALL(actor_setname,
|
|||||||
rt->name = strdup(str);
|
rt->name = strdup(str);
|
||||||
)
|
)
|
||||||
|
|
||||||
JSC_CCALL(actor_testfn,
|
|
||||||
cell_rt *crt = js2actor(js, argv[0]);
|
|
||||||
printf("actor? %p\n", crt);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(actor_on_exception,
|
JSC_CCALL(actor_on_exception,
|
||||||
cell_rt *rt = JS_GetContextOpaque(js);
|
cell_rt *rt = JS_GetContextOpaque(js);
|
||||||
JS_FreeValue(js, rt->on_exception);
|
JS_FreeValue(js, rt->on_exception);
|
||||||
@@ -159,7 +173,6 @@ static const JSCFunctionListEntry js_actor_funcs[] = {
|
|||||||
MIST_FUNC_DEF(os, unneeded, 2),
|
MIST_FUNC_DEF(os, unneeded, 2),
|
||||||
MIST_FUNC_DEF(actor, disrupt, 0),
|
MIST_FUNC_DEF(actor, disrupt, 0),
|
||||||
MIST_FUNC_DEF(actor, setname, 1),
|
MIST_FUNC_DEF(actor, setname, 1),
|
||||||
MIST_FUNC_DEF(actor, testfn, 1),
|
|
||||||
MIST_FUNC_DEF(actor, on_exception, 1),
|
MIST_FUNC_DEF(actor, on_exception, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
5
tests/hang.ce
Normal file
5
tests/hang.ce
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
log.console(`Going to start hanging ...`)
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
// hang!
|
||||||
|
}
|
||||||
15
tests/kill.ce
Normal file
15
tests/kill.ce
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// This tests forceful killing of an underling that may even be in the middle of a turn
|
||||||
|
|
||||||
|
$_.start(e => {
|
||||||
|
log.console(`got message from hanger: ${e.type}`)
|
||||||
|
if (e.type == 'greet')
|
||||||
|
$_.delay(_ => {
|
||||||
|
log.console(`sending stop message to hanger`)
|
||||||
|
$_.stop(e.actor)
|
||||||
|
}, 1)
|
||||||
|
|
||||||
|
if (e.type == 'disrupt') {
|
||||||
|
log.console(`underling successfully killed.`)
|
||||||
|
$_.stop()
|
||||||
|
}
|
||||||
|
}, 'hang')
|
||||||
Reference in New Issue
Block a user