Interfaces

ztas Interface

Initializing and finilizing processes

Processes implemented on ztas are expected to implement four methods, two of them are for creating and destroying the process. ztas_init works as a sort of constructor of your process. Its counter-part is ztas_fini.

void* ztas_init(int32_t pid)

pid: is the process id

In ztas you are not allowed to use global nor static variables. Your process has to allocate all its state on the heap and return the pointer of its state to the framework. This is necessay so that framework can run multiple processes on the same operating system process.

On each callback you’ll get your state back from the framework. The return value is any data structure casted to void*.

void*
ztas_init(int32_t pid)
{
    my_state_t* my_state = (my_state_t*) malloc(sizeof(my_state_t));
    my_state->pid = pid;
    // other initializations
    return my_state;
}
void ztas_fini(void* state)

Once the process has to be terminated, ztas_fini will be called with the process state as single argument. You are responsible for free the state and any other pointer data structure to which the state points to. You can safely cast state to the type of your process state.

Sending and receiving messages

void ztas_recv(void* state, const void* data, int32_t size)

Whenever your process receive a message, ztas_recv is called with the process state, the serialized message data and its size size. data is owned by the framework, so you are not allowed to keep a reference to data. You can either memcpy data (since it is serialized) or you can use shrp_hold or shrp_holdcopy.

Todo

add link to shrp documentation

void
ztas_recv(void* state, const void* data, size_t size)
{
    my_state_t* my_state = (my_state_t*) state;
    const my_msg_t* my_msg = (const my_msg_t*) data;
    do_something(my_state, my_msg);
}

ztas can send unicast messages or broadcast messages to all locally known processes with the methods ztas_ucast and ztas_bcast, respectively.

int ztas_ucast(int32_t dst, const void* data, int32_t size, int flags)

ztas_ucast sends a serialized message given by a pointer data and a size size to a destination processes dst. data is owned by the user, so the framework copies it before adding it to the channel buffer. If the message was allocated shrp_malloc, the framework only keeps a pointer copy.

Todo

add link to shrp documentation

The return value of ztas_ucast indicates whether the message was put in the channel buffer (with ZTAS_UCAST_OK) or not (with ZTAS_UCAST_FULL or ZTAS_UCAST_DSTERR). ZTAS_UCAST_FULL means the channel buffer is full, while ZTAS_UCAST_DSTERR means that the connection to the destination process is either closed or the process is unknown. The user is responsible of retrying in case an error was returned, nevertheless, you should not busy loop around ztas_ucast.

By default, ztas_ucast uses TCP and provides the same semantics as standard frameworks/languages such as Akka or Erlang. If ZTAS_UCAST_OK is returned, ztas guarantees that the message is delivered if nothing wrong happens (destination process crashes or network connection). If something bad happens, then ZTAS_UCAST_DSTERR is returned in the next call to ztas_ucast.

flags should be always set to 0.

Todo

add external link to Akka and Erlang documentation

my_msg_t msg;
msg.information = information;

int r = ztas_ucast(dst, &msg, sizeof(my_msg_t), 0);
if (r != ZTAS_UCAST_OK)
    ztas_alarm(RETRY_ALARM, RETRY_DELAY); // see below
int ztas_bcast(const void* data, int32_t size, int flags)

ztas_bcast sends a serialized message pointed by data with size size to all known processes. It returns ZTAS_BCAST_OK if the message was put in the channel buffer of each known processes, and return ZTAS_BCAST_NOK if the channel of some the known processes was full or closed.

ztas_bcast the same TCP sockets as ztas_ucast to transfer messages.

flags should be always set to 0.

my_msg_t msg;
msg.information = information;

ztas_bcast(&msg, sizeof(my_msg_t), 0);
// ignore return value

Scheduling and triggering alarms

ztas provides two methods to schedule alarms: ztas_alarm and ztas_sched. Besides ztas_init, ztas_fini and ztas_recv, the user is expected to implement ztas_trig, which is called when an alarm is triggerd.

void ztas_alarm(int32_t aid, int32_t time_ms)

Schedules a relative alarm, identified by aid (alarm id), to be triggered in time_ms milliseconds.

void ztas_sched(int32_t aid, ztime_t* time)

Schedules an absolute alarm, identified by aid (alarm id), to be triggered at time. time can be calculated by taking the current with with `ztas_clock`_ and adding the required time using ZTIME macros.

Todo

add link to ztime macros.

void ztas_trig(void* state, int32_t aid)

ztas_trig is called whenever an alarm scheduled with one of the methods above is triggered.

void
ztas_trig(void* state, int32_t aid)
{
    my_state_t* my_state = (my_state_t*) state;
    switch (aid) {
    case RETRY_ALARM:
        do_retry(my_state);
        break;
    case OTHER_ALARM:
        do_something_else(my_state);
        break;
    default:
        assert (0 && "should never happen");
    }
}

Reading the clock and manipulating time variables

void ztas_clock(ztime_t* ts)
ztime_t now;
ztas_clock(&now);

Todo

add documentation to most important macros.

Other methods

const char* ztas_cread(const char* key)
void ztas_term(void)

Utilities

Bounded queue

tree

idset