October 19, 2017·3 min read·engineeringrqliteraftbuilds

rqlite pins its Raft implementation inside the release source

rqlite 4.2.0 vendors HashiCorp Raft 0.1.0 and its BoltDB adapter while moving builds to Go 1.9.1. The change fixes the consensus dependency at a known API generation.

A distributed database depends on more than its own query code. The library that replicates its log determines how the service reaches agreement, and a changed dependency can require changes to membership or protocol handling. rqlite 4.2.0, released on 19 October, vendors its Raft implementation and moves the build toolchain to Go 1.9.1.

The implementing patch in pull request 354 identifies the chosen dependency explicitly. Raft is copied at version 0.1.0, and the raft-boltdb adapter is copied at a named commit. This release fixes an existing consensus implementation in the application source instead of adopting a newer Raft API generation implicitly.

I value this choice because the database's small deployment footprint should not conceal uncertainty about its build inputs. Shipping one executable is useful, but understanding that executable still requires knowing which consensus code it contains. Vendoring makes that part inspectable at the release tag.

Raft has an API transition of its own

The vendored Raft README provides the contemporary context. It says HashiCorp began using tags in September to distinguish major changes and recommends vendoring applications' dependencies on the library.

The document calls 0.1.0 the original stable implementation maintained without breaking API changes. It describes 1.0.0 as introducing UUID-based server identities and a versioned Raft protocol, with specific interoperability work required for older servers. Those are material changes for an application that manages a running cluster.

This makes the version selection more informative than the word vendor alone. The rqlite patch chooses the earlier API generation. Discussing newer features in the copied README does not mean rqlite 4.2.0 has adopted those features. The code selected by the patch determines the dependency actually built.

The distinction also separates source management from a cluster upgrade. Copying a known dependency into the tree changes how the build obtains it. Migrating an application to a dependency with different server identities would require additional application work. This release announcement identifies the first operation.

The storage adapter is included too

The patch includes both hashicorp/raft and hashicorp/raft-boltdb. The latter is the adapter through which Raft can use BoltDB for its log and stable key-value storage. Pinning only the consensus package while leaving its storage integration unspecified would leave another relevant part of the implementation outside that selection.

The copied adapter source describes BoltStore as implementing the log and stable-store roles. It opens a Bolt database and prepares buckets for logs and configuration. Its constructor handles initialization separately when the database opens read-only.

These details explain why the adapter belongs in the dependency discussion. The consensus library manages a replicated sequence of entries, while storage retains the local log and stable state it needs. SQLite holds the application-level relational state. The packages have different responsibilities even though they ship together in the database executable.

I find that separation useful when reading a database release. A SQL engine update and a consensus-storage adapter update affect different parts of the system. Version 4.2.0 is specifically about selecting and carrying the consensus dependencies in the source tree, not announcing a new SQLite query feature.

The toolchain selection is exact

The tagged changelog names Go 1.9.1. In agreement, the CircleCI configuration selects go1.9.1.linux-amd64.tar.gz for its build environment. The release page's broader description of Go 1.9 therefore has an exact patch-level counterpart in the build files.

CI prints the Go version before formatting, vet and test checks. Its ordinary and race-enabled test branches retain explicit timeouts. These are build-verification choices recorded with the release. They do not establish a benchmark result or promise that every application query becomes faster under the new runtime.

The contribution guide now requires Go 1.9 or later for source builds. That requirement concerns the developer's build environment. Users of the prebuilt release adopt the toolchain output selected by the release process, even if another Go version is installed separately on their machines.

A release tag carries more of the implementation

Vendoring provides a concrete answer to which Raft source the tagged application uses. It does not, by itself, prove that every input to an entire build is fixed or that independently produced binaries will match byte for byte. The patch names the selected Raft and adapter sources, while the toolchain configuration names its Go distribution.

That is still a meaningful improvement for reviewing and rebuilding this database. The application release contains the consensus code and its adapter at known revisions. The distinction between Raft 0.1.0 and the newer API remains explicit, so adopting rqlite 4.2.0 does not accidentally become an undocumented consensus-library migration.