Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

JS: GObject Lifecycle

GObject Lifecycle

Source code: src/gobj.js


Flags

gobj_flag_t

The features of a gobj. Each creation function below writes one combination of these, so application code rarely names them.

FlagDescription
gobj_flag_yunoThe root of the tree.
gobj_flag_default_serviceThe service that receives gobj_play() and gobj_pause().
gobj_flag_serviceA service, with a public interface of events, attributes, commands and statistics.
gobj_flag_volatilThe parent destroys it when the parent goes.
gobj_flag_pure_childIt sends its events to its parent, and nobody outside reaches it.
gobj_flag_autostartThe framework starts it.
gobj_flag_autoplayThe framework plays it.

Creation

gobj_create(gobj_name, gclass_name, kw, parent)

Builds a child gobj. It is the function that a gclass uses in mt_create.

gobj_create_yuno(gobj_name, gclass_name, kw)

Builds the root of the tree. There is one for each process.

gobj_create_service(gobj_name, gclass_name, kw, parent)

Builds a service with a name under the yuno. Only a service can be the source or the destination of a message between yunos.

gobj_create_default_service(gobj_name, gclass_name, kw, parent)

Builds the default service, which receives gobj_play() and gobj_pause().

gobj_create_volatil(gobj_name, gclass_name, kw, parent)

Builds a child that the parent destroys with itself.

gobj_create_pure_child(gobj_name, gclass_name, kw, parent)

Builds a pure child. It sends its events to its parent, and the parent must declare each one of them in its own state machine.

gobj_create2(gobj_name, gclass_name, kw, parent, gobj_flag)

Builds a gobj with the flags that the caller gives. Every function above calls it with one combination of gobj_flag_t. Use it only for a combination that no other function gives.

gobj_destroy(gobj)

Destroys a gobj. The destruction goes down: it destroys the children first. It deletes the subscriptions, and it takes the gobj out of the queue of the posted events.

Not under code that still runs on it (gobj-js 7.26.22, the same check as the C kernel’s gobj_destroy()). The runtime keeps a frame for each action, publication and framework method in progress. When gobj_destroy() finds a live frame of the gobj that it destroys, or of a gobj below it, it logs an ERROR with the stack and destroys all the same:

The line names destroying, publisher (or running), event, destroyer and inner_event. It is not an error when the innermost frame destroys its own gobj (a gobj that destroys itself in its action), or when a host destroys its transport in the transport’s EV_STOPPED.

The fix is to post an event to yourself and destroy in its action. The event is an input event of the gclass, in its FSM and in its event_types:

// A host ends the C_TIMER child that it armed. EV_TIMEOUT is PUBLISHED by
// the timer: destroying it here destroys the timer under its publication.
function ac_timeout(gobj, event, kw, src)
{
    gobj_post_event(gobj, "EV_TIMER_DONE", {timer: gobj_name(src)}, gobj);
    return 0;
}

function ac_timer_done(gobj, event, kw, src)
{
    let timer = gobj.priv.timer;
    if(timer && gobj_name(timer) === kw.timer) {
        gobj_stop(timer);
        gobj_destroy(timer);
        gobj.priv.timer = null;
    }
    return 0;
}

Start and stop

gobj_start(gobj)

Starts a gobj, and calls its mt_start method.

The function refuses to start a gobj that has an empty SDF_REQUIRED attribute, as gobj_start() in C does (gobj-js 7.26.28, BREAKING). It logs one ERROR with the names of the empty attributes, gives -1, and does not call mt_start. These values are empty:

A DTP_BOOLEAN, DTP_INTEGER or DTP_REAL is never empty.

const attrs_table = [
SDATA(data_type_t.DTP_STRING, "url", sdata_flag_t.SDF_RD|sdata_flag_t.SDF_REQUIRED, "", "Backend url"),
SDATA_END()
];
// ...
const gobj = gobj_create("backend", "C_MY_LINK", {}, parent);
gobj_start(gobj);   // -1, ERROR: "Cannot start without all required attributes: ["url"]"

const gobj2 = gobj_create("backend2", "C_MY_LINK", {url: "wss://example.com:1991"}, parent);
gobj_start(gobj2);  // 0

gobj_start_tree() does not start such a gobj, and it starts its children, as in C. Before 7.26.28 the check was not in JS, and the gobj started without the attribute.

gobj_stop(gobj)

Stops a gobj, and calls its mt_stop method.

gobj_start_children(gobj)

Starts the children of a gobj, and not the gobj.

gobj_stop_children(gobj)

Stops the children of a gobj.

gobj_start_tree(gobj)

Starts a gobj and each one of the gobjs below it. A gclass with the flag gcflag_manual_start does not start here.

gobj_stop_tree(gobj)

Stops a gobj and each one of the gobjs below it.


Play and pause

gobj_play(gobj)

Plays a gobj, and calls its mt_play method.

If the gobj is not running, gobj_play() starts it first, with a WARNING. If that start is refused (an empty SDF_REQUIRED attribute), destroys the gobj, or leaves it not running, gobj_play() gives -1 and does not call mt_play (gobj-js 7.26.29, as in C). A mt_start that returns -1 and leaves the gobj running does not stop the play.

// "url" is SDF_REQUIRED and empty: the start is refused, so the play is too.
const ws = gobj_create("ws", "C_MY_CLIENT", {}, yuno);
gobj_play(ws);  // -1; mt_play is not called, gobj_is_playing(ws) is false

gobj_pause(gobj)

Pauses a gobj, and calls its mt_pause method.


Status

gobj_is_running(gobj)

Tells if a gobj is running.

gobj_is_playing(gobj)

Tells if a gobj is playing.

gobj_is_service(gobj)

Tells if a gobj is a service.

gobj_is_volatil(gobj)

Tells if the parent destroys this gobj with itself.

gobj_is_pure_child(gobj)

Tells if a gobj is a pure child.

gobj_is_destroying(gobj)

Tells if a gobj is under destruction. Use it in a handler of a transport that can arrive late, such as the close of a websocket.