Scheduler#

The event scheduler gives power to the user for overriding or adding his own logic on top of Orca’s default event-emitting behavior. This section outlines the scheduler built-in methods so that the user may take full advantage of it.

Thread Pool Work Scheduling#

Orca provides a threadpool that can be used to run the event callbacks from.

The default amount of threads in the threadpool is 2, and its maximum pending tasks queue length is 8. Those values may be changed by modifying their respective environment variables: ORCA_THREADPOOL_SIZE and ORCA_THREADPOOL_QUEUE_SIZE.

Note

The threadpool is shared amongst ALL clients initialized from the same proccess.

See also

For a quick example check Example.

discord_set_event_scheduler() - set Event scheduler#

typedef enum discord_event_scheduler (*discord_on_scheduler)(struct discord *client, struct sized_buffer *event_data, enum discord_gateway_events event)#

Event Handling Mode callback.

A very important callback that enables the user with a fine-grained control of how each event is handled: blocking, non-blocking or ignored

enum discord_event_scheduler#

return value of discord_set_event_scheduler() callback

Values:

enumerator DISCORD_EVENT_IGNORE#

this event has been handled

enumerator DISCORD_EVENT_MAIN_THREAD#

handle this event in main thread

enumerator DISCORD_EVENT_WORKER_THREAD#

handle this event in a worker thread

void discord_set_event_scheduler(struct discord *client, discord_on_scheduler callback)#

Provides the user with a fine-grained control of the Discord’s event-loop.

Allows the user to specify which events should be executed from the main-thread, in parallel from a worker-thread, or completely ignored

Warning

The user is responsible for providing his own locking mechanism to avoid race-condition on sensitive data

Parameters:
  • client – the client created_with discord_init()

  • fn – the function that will be executed

Example#

discord_event_scheduler_t scheduler(struct discord *client,
                                    struct sized_buffer *data,
                                    enum discord_gateway_events event)
{
  switch (event) {
  case DISCORD_GATEWAY_EVENTS_MESSAGE_CREATE:
    return DISCORD_EVENT_WORKER_THREAD;
  case DISCORD_GATEWAY_EVENTS_MESSAGE_DELETE:
    return DISCORD_EVENT_IGNORE;
  case DISCORD_GATEWAY_EVENTS_CHANNEL_CREATE: {
    struct discord_channel channel;
    discord_channel_from_json(data->start, data->size, &channel);

    log_info("Channel %s has been created!", channel.name);

    discord_channel_cleanup(&channel);
  } return DISCORD_EVENT_IGNORE;
  case DISCORD_GATEWAY_EVENTS_READY:
  default:
    return DISCORD_EVENT_MAIN_THREAD;
  }
}

int main(void)
{
  // increase threadpool to 4 threads
  setenv("ORCA_THREADPOOL_SIZE", "4", 1);
  // increase threadpool queue length to 128 slots
  setenv("ORCA_THREADPOOL_QUEUE_SIZE", "128", 1);
  struct discord *client = discord_init(TOKEN);

  discord_set_event_scheduler(client, &scheduler);

  // Assigned to main-thread at scheduler() (single-threaded execution)
  discord_set_on_ready(client, &on_ready);
  // Assigned to a worker thread at scheduler() (parallel execution)
  discord_set_on_message_create(client, &on_message_create);
  // Will ignore the callback at scheduler()
  discord_set_on_message_delete(client, &on_message_delete);
  // Will ignore the callback at scheduler(), and include user logic for
  // printing the new channel
  discord_set_on_channel_create(client, &on_channel_create);

  discord_run(client);
}