example/

directory
v3.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2026 License: AGPL-3.0

README

Example implementation of Microcluster

This example package can be used as a starting point for creating projects with Microcluster. This package contains:

  • A Microcluster daemon command (microd) and a control command (microctl)
  • Examples for the built-in Microcluster API
  • Examples of how Microcluster can be extended with additional listeners with user-defined endpoints and schema versions

Contents

How to build and run the package

Prerequisites
Required packages
  • Go must be installed on your system.

  • Run the following commands to install the remaining required packages:

    sudo apt-get update
    sudo apt-get install --no-install-recommends -y \
              shellcheck \
              pkg-config \
              autoconf \
              automake \
              libtool \
              make \
              libuv1-dev \
              libsqlite3-dev \
              liblz4-dev
    
Environment variables

After Go is installed, ensure that the CGO_ENABLED environment variable is persistently set to 1, which allows Go programs to interface with C libraries:

go env -w CGO_ENABLED=1

Additional variables must be set in your shell to ensure that Dqlite dependencies can be loaded during the build:

ENVIRONMENT VARIABLE VALUE
CGO_CFLAGS -I$HOME/go/deps/dqlite/include/
CGO_LDFLAGS -L$HOME/go/deps/dqlite/.libs/
LD_LIBRARY_PATH $HOME/go/deps/dqlite/.libs/
CGO_LDFLAGS_ALLOW (-Wl,-wrap,pthread_create)|(-Wl,-z,now)

If you are using bash as your shell, you can set the above as persistent variables with the following commands:

cat << EOF >> ~/.bashrc
export CGO_CFLAGS="-I$HOME/go/deps/dqlite/include/"
export CGO_LDFLAGS="-L$HOME/go/deps/dqlite/.libs/"
export LD_LIBRARY_PATH="$HOME/go/deps/dqlite/.libs/"
export CGO_LDFLAGS_ALLOW="(-Wl,-wrap,pthread_create)|(-Wl,-z,now)"
EOF
source ~/.bashrc
Build

Clone this repository to your system, then run the following command from the repository's root directory:

make deps

This installs required dependencies, including Dqlite.

If the previous command is successful, then build the example package by running:

make -C example

After a successful build, test the microctl and microd commands by running:

microctl --help
microd --help

If either command returns a not found error, confirm that the microctl and microd have been generated. Typically, they are generated in the ~/go/bin/ directory. If this directory is not defined in your system path, you must add it.

If you're using bash, you can add it by running:

echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

The microd command starts the Microcluster daemon, and microctl controls it.

Note: These commands are not a core component of the Microcluster library; they are included in this example package to demonstrate how you can create similar commands for your own implementation.

Run

Use the microd command along with the --state-dir <path/to/state/directory> flag to start a Microcluster daemon with a running control socket and no database.

You must specify its state directory, the path where the daemon's information is stored. If the state directory does not exist at the path you provide, microd creates the directory.

View the microd --help documentation for other options, or view the tutorial for example usage.

Control

Use the microctl command to control the Microcluster. View microctl --help for options, or view the tutorial for example usage.

Tutorial

This tutorial walks you through using the example package to start up a Microcluster and interact with it.

Step 1: Build the package

Ensure that your system meets the prerequisites in the how-to guide above, then build the package.

Step 2: Start three Microcluster daemons

The commands below start three Microcluster daemons in the background, creating state directories for each and waiting for the daemon to be ready to process requests. Each daemon's PID is stored in a shell variable (proc1, proc2, and proc3) for later use.

Run:

microd --state-dir /tmp/mc1 & proc1=$!
microd --state-dir /tmp/mc2 & proc2=$!
microd --state-dir /tmp/mc3 & proc3=$!

You should see three "Microcluster database is uninitialized" warnings. Don't worry; this is expected.

Step 3: Start the Dqlite database

Run the following command to bootstrap the first Microcluster member, which starts a new cluster:

microctl --state-dir /tmp/mc1 init mc1 127.0.0.1:9001 --bootstrap

You might see a warning that "The 'missing_extension' is not registered". Disregard this warning.

To confirm creation of the cluster, run the following command:

microctl --state-dir /tmp/mc1 cluster list

You should see a table that displays a single cluster member with the name of mc1 and an address of 127.0.0.1:9001, along with its role, fingerprint, and status. Ensure that the status is ONLINE before you proceed.

Step 4: Join the other members to the cluster

To generate and use join tokens for the second and third Microcluster members, using the names mc2 and mc3, run:

token=$(microctl --state-dir /tmp/mc1 tokens add mc2)
microctl --state-dir /tmp/mc2 init mc2 127.0.0.1:9002 --token "$token"
token=$(microctl --state-dir /tmp/mc1 tokens add mc3)
microctl --state-dir /tmp/mc3 init mc3 127.0.0.1:9003 --token "$token"

Note: Each token can only be used once, because they are deleted from the cluster after use.

To confirm that the second and third Microcluster members have joined the cluster, view the cluster list again.

Step 5: Interact with the cluster
Step 5.1: Remove a cluster member

You have created three Microcluster daemons, used one to bootstrap a new cluster, then joined the other two daemons to that cluster. Next, remove the mc3 cluster member:

microctl --state-dir /tmp/mc1 cluster remove mc3

Note: When using cluster remove, for the --state-dir argument, you can use the state directory for any online cluster member. This includes the state directory of the cluster member being removed.

Step 5.2: Perform SQL queries

The microctl command includes an option to execute an SQL query against the cluster's Dqlite database.

Run the following command to view all available tables:

microctl --state-dir /tmp/mc1 sql "SELECT name FROM sqlite_master WHERE type='table';"

Expected output:

+----------------------+
|         name         |
+----------------------+
| sqlite_sequence      |
| schemas              |
| core_cluster_members |
| core_token_records   |
| extended_table       |
| some_other_table     |
+----------------------+

Try querying data from the core_cluster_members table:

microctl --state-dir /tmp/mc1 sql "SELECT name,address,heartbeat FROM core_cluster_members"

Expected output:

+------+----------------+--------------------------------+
| name |    address     |           heartbeat            |
+------+----------------+--------------------------------+
| mc1  | 127.0.0.1:9001 | 2025-03-20T17:52:03.101704405Z |
| mc2  | 127.0.0.1:9002 | 2025-03-20T17:52:03.125658611Z |
+------+----------------+--------------------------------+

Finally, perform an SQL query on an extended schema table called extended_table:

microctl --state-dir /tmp/mc1 sql "insert into extended_table (key, value) values ('some_key', 'some_value')"

Expected output:

Rows affected: 1

View the updated table:

microctl --state-dir /tmp/mc1 sql "select * from extended_table"

Expected output:

+----+----------+------------+
| id |   key    |   value    |
+----+----------+------------+
| 1  | some_key | some_value |
+----+----------+------------+
Step 5.3: Perform an extended API interaction

Run:

microctl --state-dir /tmp/mc2 extended 127.0.0.1:9001

Expected output:

cluster member at address "127.0.0.1:9002" received message "Testing 1 2 3..." from cluster member at address "127.0.0.1:9001"

This demonstrates using the extended API to communicate between mc1 (127.0.0.1:9001) and mc2 (127.0.0.1:9002).

Step 6: Shut down the Microcluster

To shut down the Microcluster, stop the daemons using the PID variables defined in Step 2:

kill $proc1 $proc2 $proc3

If you are done using the example package, or you want to start the tutorial over from the beginning, also remove the /tmp/mc1, /tmp/mc2, and /tmp/mc3 directories:

rm -rf /tmp/mc*

Next steps

Directories

Path Synopsis
api
Package api provides a slice of Servers
Package api provides a slice of Servers
types
Package types provides shared types and structs.
Package types provides shared types and structs.
Package client provides a full Go API client.
Package client provides a full Go API client.
cmd
microctl command
Package microctl provides the main client tool.
Package microctl provides the main client tool.
microd command
Package microd provides the daemon.
Package microd provides the daemon.
Package database provides the database access functions and schema.
Package database provides the database access functions and schema.
Package version provides shared version information.
Package version provides shared version information.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL