liveBook · Manning

Bbolt

As explained in Build and Orchestrator in Go (From Scratch)

BoltDB is an embedded persistent key/value database implemented as a Go library.

bbolt is used as an embedded persistent key/value datastore for task state. Instead of running a separate database server or making network calls for reads and writes, a Go process opens a local database file and accesses data through the library. This fits an orchestrator whose manager and workers need simple, fast storage without the operational weight of a full database server. section 1.7 section 11.8

The core mental model is the same as an in-memory Go map: a task UUID is a key and the task is its value. Persistence changes the implementation, not the store-facing role. A TaskStore still satisfies the Store interface with Put, Get, List, and Count; it replaces the map with a *bolt.DB, a database-file name, file permissions, and a bucket name. section 11.8 section 11.9

A persistent task store is assembled in small, explicit steps:

  • Open a database file with bolt.Open, passing its path and file mode; report an error if it cannot be opened. section 11.9
  • Record the database handle, file metadata, and bucket name in TaskStore, then create the bucket or reuse it when it already exists. section 11.9
  • Use an Update transaction to modify a bucket. Put serializes a task as JSON and stores the resulting bytes under the task key. section 11.9
  • Use a View transaction to read a bucket. Get loads and unmarshals one task; List iterates entries and unmarshals each value; Count iterates entries to total them. section 11.9
  • Close the database handle when the store is no longer needed, because the datastore writes to a file on disk. section 11.9

Persisting tasks behind one interface

A task store can be initialized with a file, permissions, and a bucket such as tasks. Calling Put with a task UUID marshals the task to JSON and writes it into that bucket. A later Get reads the bytes for the same UUID and unmarshals them into a task. Code using Store can retain the same Put, Get, List, and Count operations used by the in-memory implementation while gaining durable state. section 11.9

Listing 11.22 The NewTaskStore helper function
func NewTaskStore(file string, mode os.FileMode, bucket string)
   (*TaskStore, error) {
    db, err := bolt.Open(file, mode, nil)                   #1
    if err != nil {
        return nil, fmt.Errorf("unable to open %v", file)
    }
    t := TaskStore{                                        #2
        DbFile:   file,
        FileMode: mode,
        Db:       db,
        Bucket:   bucket,
    }
 
    err = t.CreateBucket()                                 #3
    if err != nil {
        log.Printf("bucket already exists, will use it instead
     of creating new one")
    }
 
    return &t, nil                                         #4
}
#1 Creates a datastore by calling the BoltDB library’s Open function, passing in the file, mode, and bucket from our function signature, and checks for any errors
#2 Creates an instance of the TaskStore and assigns it to the variable t
#3 Creates the bucket by calling the CreateBucket method and checks for any errors
#4 Returns a pointer to the newly created task store

The initializer makes the persistence boundary visible: open the file, retain the bolt.DB handle and configuration, ensure a bucket exists, and return the ready-to-use store. section 11.9

This design deliberately keeps the database role narrow. It stores orchestrator tasks in a key/value model rather than modeling data as relational tables and columns. The result is a practical persistence layer for a focused Docker-container orchestrator, not an attempt to build a replacement for a full database server or production-scale orchestration platform. section 1.7 section 11.8 section 13.4

How Build and Orchestrator in Go (From Scratch) covers it

How deep it goes
Works through a TaskStore implementation: file opening, buckets, transactions, JSON serialization, iteration, and closing.
Examples
Demonstrates TaskStore fields plus NewTaskStore, CreateBucket, Put, Get, List, Count, and Close methods.
What it assumes
Assumes non-trivial programming familiarity but supplies compiling Go code and introduces the datastore incrementally.
What you can do after
Apply it via the BoltDB library to replace an in-memory task store with file-backed persistent storage.
How it connects
Connects key-value storage with Go, the Store interface, persistent storage, JSON, and task lifecycle state.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build and Orchestrator in Go (From Scratch). The section links point to the parts of the book it draws on.