Go SDK
Go client for the beachcomber shell-state daemon. Communicates over a Unix domain socket using newline-delimited JSON. Idiomatic Go with standard error returns and no external dependencies.
Requirements
- Go 1.21+
- A running
combdaemon
Installation
go get github.com/NavistAu/beachcomber/sdks/go
Quick start
package main
import (
"fmt"
"log"
beachcomber "github.com/NavistAu/beachcomber/sdks/go"
)
func main() {
c, err := beachcomber.NewClient()
if err != nil {
log.Fatal(err)
}
result, err := c.Get("git.branch", "/path/to/repo")
if err != nil {
log.Fatal(err)
}
if result.IsHit() {
branch, _ := result.GetString("")
fmt.Printf("branch: %s (age %dms)\n", branch, result.AgeMs)
}
}
Sessions
Open a persistent connection for multiple queries to avoid per-call socket overhead:
sess, err := c.Session()
if err != nil {
log.Fatal(err)
}
defer sess.Close()
sess.SetContext("/path/to/repo")
branchResult, err := sess.Get("git.branch", "")
dirtyResult, err := sess.Get("git.dirty", "")
API reference
Client
c, err := beachcomber.NewClient() // auto-discover socket
c := beachcomber.NewClientWithPath("/custom/path/sock") // explicit socket path
c.Get(key, path) (*Result, error)
Read a cached value. path may be "" to omit it.
result, err := c.Get("git.branch", "/path/to/repo")
result, err := c.Get("hostname", "") // global provider
result, err := c.Get("git", "/path/to/repo") // full provider object
c.Poke(key, path) error
Force the daemon to recompute a provider.
c.List() (*Result, error)
List available providers.
c.Status() (*Result, error)
Return daemon scheduler and cache status.
c.Session() (*Session, error)
Open a persistent connection.
Session
| Method | Description |
|---|---|
Get(key, path string) (*Result, error) | Read a cached value |
Poke(key, path string) error | Force recomputation |
SetContext(path string) error | Set default path for subsequent queries |
Close() error | Close the connection |
Result
| Field / method | Type | Description |
|---|---|---|
OK | bool | true when the daemon returned success |
Data | interface{} | Decoded payload (string, map, etc.) |
AgeMs | uint64 | Cache age in milliseconds |
Stale | bool | Whether the value is stale |
IsHit() bool | — | true when OK && Data != nil |
IsMiss() bool | — | true when OK && Data == nil |
GetString(field string) (string, bool) | — | Extract a string (pass "" for scalar results) |
GetInt(field string) (int64, bool) | — | Extract an integer |
GetFloat(field string) (float64, bool) | — | Extract a float |
GetBool(field string) (bool, bool) | — | Extract a boolean |
RawJSON() []byte | — | Full raw JSON response |
For full provider queries, pass a field name to the typed accessors:
result, _ := c.Get("git", "/repo")
branch, _ := result.GetString("branch") // "main"
dirty, _ := result.GetBool("dirty") // false
Errors
| Error | When returned |
|---|---|
ErrDaemonNotRunning | Unix socket cannot be reached |
*ServerError | Daemon responded with ok: false |
*ProtocolError | Response could not be parsed |
Socket discovery
The SDK discovers the daemon socket at:
$XDG_RUNTIME_DIR/beachcomber/sock(ifXDG_RUNTIME_DIRis set and the path exists)$TMPDIR/beachcomber-<uid>/sock/tmp/beachcomber-<uid>/sock