struct raft_io — I/O backend interface

# `struct raft_io` — I/O backend interface

The I/O backend struct defines an interface for performing periodic ticks, log store read/write and send/receive of network RPCs.

## Data types

struct `raft_io`

  Hold pointers to an actual implementation of the I/O backend interface.

void `(*raft_io_close_cb)`(struct raft_io *io)

  Type definition for callback passed to `raft_io.close()`.

void `(*raft_io_tick_cb)`(struct raft_io *io)

  Callback invoked by the I/O implementation at regular intervals.

void `(*raft_io_recv_cb)`(struct raft_io *io, struct raft_message *msg)

  Callback invoked by the I/O implementation when an RPC message is received.

### Public members

void* `data`

  Space for user-defined arbitrary data. C-Raft does not use and does not touch this field.

int `version`

  API version implemented by this instance. Currently 1.

void* `impl`

  Implementation-defined state.

`char errmsg[RAFT_ERRMSG_BUF_SIZE]`

  Human-readable message providing diagnostic information about the last error occurred.

int `(*init)`(struct raft_io *io, raft_id id, const char *address)

  Initialize the backend with operational parameters such as server ID and address.

void `(*close)`(struct raft_io *io, raft_io_close_cb cb)

  Release all resources used by the backend.

  The `tick` and `recv` callbacks must not be invoked anymore, and pending asynchronous requests be completed or canceled as soon as possible. Invoke the close callback once the `raft_io` instance can be freed.

int `(*load)`(struct raft_io *io, raft_term *term, raft_id *voted_for, struct raft_snapshot **snapshot, raft_index *start_index, struct raft_entry *entries[], size_t *n_entries)

  Load persisted state from storage.

  The implementation must synchronously load the current state from its storage backend and return information about it through the given pointers.

  The implementation can safely assume that this method will be invoked exactly one time, before any call to `raft_io.append()` or c:func:raft_io.truncate(), and then won’t be invoked again.

  The snapshot object and entries array must be allocated and populated using `raft_malloc()`. If this function completes successfully, ownership of such memory is transfered to the caller.

int `(*start)`(struct raft_io *io, unsigned msecs, raft_io_tick_cb tick, raft_io_recv_cb recv)

  Start the backend.

  From now on the implementation must start accepting RPC requests and must invoke the `tick` callback every `msecs` milliseconds. The `recv` callback must be invoked when receiving a message.

int `(*bootstrap)`(struct raft_io *io, const struct raft_configuration *conf)

  Bootstrap a server belonging to a new cluster.

  The implementation must synchronously persist the given configuration as the first entry of the log. The current persisted term must be set to 1 and the vote to nil.

  If an attempt is made to bootstrap a server that has already some state, then RAFT_CANTBOOTSTRAP must be returned.

int `(*recover)`(struct raft_io *io, const struct raft_configuration *conf)

  Force appending a new configuration as last entry of the log.

int `(*set_term)`(struct raft_io *io, raft_term term)

  Synchronously persist current term (and nil vote).

  The implementation MUST ensure that the change is durable before returning (e.g. using `fdatasync()` or O_DSYNC).

int `(*set_vote)`(struct raft_io *io, raft_id server_id)

  Synchronously persist who we voted for.

  The implementation MUST ensure that the change is durable before returning (e.g. using `fdatasync()` or O_DSYNC).

int `(*send)`(struct raft_io *io, struct raft_io_send *req, const struct raft_message *message, raft_io_send_cb cb)

  Asynchronously send an RPC message.

  The implementation is guaranteed that the memory referenced in the given message will not be released until the `cb` callback is invoked.

int `(*append)`(struct raft_io *io, struct raft_io_append *req, const struct raft_entry entries[], unsigned n, raft_io_append_cb cb)

  Asynchronously append the given entries to the log.

  The implementation is guaranteed that the memory holding the given entries will not be released until the `cb` callback is invoked.

int `(*truncate)`(struct raft_io *io, raft_index index)

  Asynchronously truncate all log entries from the given index onwards.

int `(*snapshot_put)`(struct raft_io *io, unsigned trailing, struct raft_io_snapshot_put *req, const struct raft_snapshot *snapshot, raft_io_snapshot_put_cb cb)

  Asynchronously persist a new snapshot. If the `trailing` parameter is greater than zero, then all entries older that `snapshot->index - trailing` must be deleted. If the `trailing` parameter is `0`, then the snapshot completely replaces all existing entries, which should all be deleted. Subsequent calls to append() should append entries starting at index `snapshot->index + 1`.

  If a request is submitted, the raft engine won’t submit any other request until the original one has completed.

int `(*snapshot_get)`(struct raft_io *io, struct raft_io_snapshot_get *req, raft_io_snapshot_get_cb cb)

  Asynchronously load the last snapshot.

raft_time `(*time)`(struct raft_io *io)

  Return the current time, expressed in milliseconds.

int `(*random)`(struct raft_io *io, int min, int max)

  Generate a random integer between `min` and `max`.