Bootstrap method: join
The “join” bootstrap method allows a process to dynamically join an existing Flock group. Unlike the “file” or “view” bootstrap methods which simply load a static view, “join” actively contacts existing group members and requests to be added to the group.
When to use
Use the “join” bootstrap method when:
You want to dynamically add processes to a running group
You’re implementing elastic services that scale up at runtime
You need existing group members to be notified of new members
You want the group view to be updated across all members
Prerequisites
To use the join bootstrap method, you need:
An existing Flock group with at least one member
A group view file containing addresses of current members
A backend that supports dynamic membership (use “centralized”, not “static”)
How it works
The join process:
The new process loads a view (e.g. from a file) containing addresses of existing group members
It registers a provider with
"bootstrap": "join"in the configurationThe provider contacts existing members and requests to join
The existing members add the new member to the group
All members receive an updated view with the new member
This is different from the “file” bootstrap, which simply loads a view that we expect the process to already be part of.
Configuration
In Bedrock configuration:
{
"libraries": [
"libflock-bedrock-module.so"
],
"providers": [
{
"type": "flock",
"name": "my_flock_provider",
"provider_id": 42,
"config": {
"bootstrap": "join",
"file": "mygroup.flock",
"group": {
"type": "centralized",
"config": {}
}
}
}
]
}
The configuration specifies:
bootstrap: Must be “join” to enable dynamic joiningfile: Path to a file containing the current group viewgroup.type: Must support dynamic membership (e.g. not be “static”)
In C code
To join a group programmatically:
/*
* (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)
{
if(argc != 2) {
fprintf(stderr, "Usage: %s <group_file>\n", argv[0]);
return -1;
}
const char* group_file = argv[1];
// 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;
uint16_t provider_id = 42;
int ret;
// Load the existing group view from file
// This view contains the addresses of current group members
ret = flock_group_view_init_from_file(group_file, &initial_view);
if(ret != FLOCK_SUCCESS) {
fprintf(stderr, "Failed to load group view from file: %s\n", group_file);
margo_finalize(mid);
return -1;
}
printf("Loaded group view from file: %s\n", group_file);
printf("Current group size: %zu\n", initial_view.members.size);
// Configure with centralized backend and "join" bootstrap method
// The "join" bootstrap tells the provider to contact existing members
// and request to join the group dynamically
const char* config =
"{"
" \"bootstrap\": \"join\","
" \"group\": {"
" \"type\": \"centralized\","
" \"config\": {}"
" }"
"}";
// Register provider - it will join the existing group
flock_provider_t provider;
ret = flock_provider_register(mid, provider_id, config, &args, &provider);
if(ret != FLOCK_SUCCESS) {
fprintf(stderr, "Failed to register provider and join group\n");
flock_group_view_clear(&initial_view);
margo_finalize(mid);
return -1;
}
printf("Successfully joined the group\n");
// Wait for finalize
margo_wait_for_finalize(mid);
return 0;
}
The key steps are:
Load the existing group view from a file using
flock_group_view_init_from_fileSet
"bootstrap": "join"in the configuration JSONCall
flock_provider_registerwith the configuration and initial view
The provider will then contact the members listed in the view and request to join the group.
Example workflow
Step 1: Start the initial group member with “self” bootstrap:
$ ./initial_server
Server running at address na+sm://12345-0
Flock provider registered
Group file written to: mygroup.flock
Step 2: A new process joins using the group file:
$ ./05_flock_server mygroup.flock
Server running at address na+sm://12346-0
Loaded group view from file: mygroup.flock
Current group size: 1
Successfully joined the group
After joining, all members will have an updated view containing both members.