Bootstrap method: self

The “self” bootstrap method is the simplest way to initialize a Flock group. It creates a single-member group containing only the current process/provider.

When to use

Use the “self” bootstrap method when:

  • You’re starting with a single process and will dynamically add members later

  • You’re testing or prototyping

  • Your service doesn’t need initial coordination with other processes

Configuration

In Bedrock configuration:

{
    "libraries": [
        "libflock-bedrock-module.so"
    ],
    "providers": [
        {
            "type": "flock",
            "name": "my_flock_provider",
            "provider_id": 42,
            "config": {
                "bootstrap": "self",
                "group": {
                    "type": "static",
                    "config": {}
                },
                "file": "mygroup.flock"
            }
        }
    ]
}

In C code

When creating a provider programmatically, use flock_group_view_init_from_self:

/*
 * (C) 2024 The University of Chicago
 *
 * See COPYRIGHT in top-level directory.
 */
#include <assert.h>
#include <stdio.h>
#include <margo.h>
#include <flock/flock-server.h>
#include <flock/flock-bootstrap.h>

int main(int argc, char** argv)
{
    // Initialize Margo
    margo_instance_id mid = margo_init("na+sm", MARGO_SERVER_MODE, 0, 0);
    assert(mid);

    // Print server address
    hg_addr_t my_address;
    margo_addr_self(mid, &my_address);
    char addr_str[256];
    hg_size_t addr_str_size = 256;
    margo_addr_to_string(mid, addr_str, &addr_str_size, my_address);
    margo_addr_free(mid, my_address);

    printf("Server running at address %s\n", addr_str);

    // Initialize provider args
    struct flock_provider_args args = FLOCK_PROVIDER_ARGS_INIT;
    flock_group_view_t initial_view = FLOCK_GROUP_VIEW_INITIALIZER;
    args.initial_view = &initial_view;

    // Bootstrap using self method
    uint16_t provider_id = 42;
    flock_group_view_init_from_self(mid, provider_id, &initial_view);

    printf("Bootstrapped group with self method\n");
    printf("Group size: %zu\n", initial_view.members.size);

    // Configure with static backend
    const char* config = "{ \"group\":{ \"type\":\"static\", \"config\":{} } }";

    // Register provider
    flock_provider_t provider;
    int ret = flock_provider_register(mid, provider_id, config, &args, &provider);
    assert(ret == FLOCK_SUCCESS);

    printf("Flock provider registered with provider_id=%d\n", provider_id);

    // Wait for finalize
    margo_wait_for_finalize(mid);

    return 0;
}

The flock_group_view_init_from_self function takes:

  • The Margo instance

  • The provider ID

  • A pointer to the group view to initialize

This will populate the view with a single member (the current process).

Group view structure

After initialization with “self”, the group view contains:

  • A single member with the current process’s address and provider ID

  • Empty metadata

  • An initial digest for view versioning

You can persist this view to a file or share it with other processes to allow them to join the group using the “join” or “view” bootstrap methods.