Solune is a TCP-based key-value database written in Go.
It supports multiple named stores, JSON line commands (get, set, delete), process supervision, and disk-backed persistence in db/*.solstr.
Roadmap items are tracked in doc/README.md.
- TCP server on port
9000by default - One JSON command per line
- Multiple named stores
- Auto-increment key assignment when
setis called withoutkey - Supervisor process that restarts worker on crash
- Disk-backed storage with in-memory shard cache
At runtime, Solune starts three layers:
-
Launcher (
main.go)- Builds
workerandsupervisorbinaries. - Cleans up existing supervisor processes and port
9000. - Starts the supervisor.
- Builds
-
Supervisor (
cmd/supervisor)- Starts the worker on the configured port.
- Waits for worker exit and restarts it.
- Handles shutdown signals and forwards them to worker.
-
Worker (
cmd/worker)- Loads stores from
db/*.solstr. - Starts TCP server and handles client commands.
- Loads stores from
Solune is disk-backed (not memory-only).
- Each store is persisted in
db/<store>.solstr. - File format is line-based:
key,base64(value). - On startup, stores are discovered from files in
db/. set/updateanddeletecurrently rewrite store files via temp-file + rename.- In-memory shards cache values for fast access during runtime.
Send one JSON object per line over TCP.
instruction(string, required)store(string, optional depending on instruction)key(string or number, optional depending on instruction)data(string, optional depending on instruction)
Unknown fields are rejected.
getsetdelete
Legacy non-JSON command format is rejected.
{"instruction":"get"}Lists all stores.{"instruction":"get","store":"users"}Returns all records in store.{"instruction":"get","store":"users","key":1}Returns one record by key.
{"instruction":"set","store":"users"}Creates store if it does not exist; if it already exists, returns error.{"instruction":"set","store":"users","data":"{\"name\":\"John\"}"}Auto-assigns next key and stores data.{"instruction":"set","store":"users","key":1,"data":"{\"name\":\"Jane\"}"}Upserts key1(create or update).
{"instruction":"delete","store":"users","key":1}Deletes one key.{"instruction":"delete","store":"users"}Deletes whole store and its backing file.
Responses are newline-delimited JSON objects.
-
Success write/delete:
{"status":200} -
Read single:
{"key":1,"value":"{\"name\":\"Jane\"}"} -
Read many:
- One JSON object per line.
-
Error:
{"error":"..."} -
Empty result in some read paths can return:
{"status":404}
- Go 1.20+
- Docker (optional)
go run main.goThis starts Solune on 127.0.0.1:9000.
docker compose up --buildYou can use any TCP client (for example nc):
printf '{"instruction":"set","store":"user_data"}\n' | nc 127.0.0.1 9000
printf '{"instruction":"set","store":"user_data","data":"{\"name\":\"John Doe\",\"age\":30}"}\n' | nc 127.0.0.1 9000
printf '{"instruction":"get","store":"user_data"}\n' | nc 127.0.0.1 9000There is also a helper script at scripts/communication.py.
Note: it ships with command = ''; set command to your JSON command before running.
go test ./test/unit/...go test -bench=. -benchmem ./test/unit/store/...Start server first:
go run main.goThen in another terminal:
go test ./test/integration/... -v -count=1Run only unhappy-path integration tests:
go test ./test/integration/... -run TestIntegrationUnhappyPaths -v -count=1Manual request walkthrough:
go run ./test/integration/steps.go- No authentication/authorization.
- No WAL yet.
- No replication.
- Persistence is file-based with rewrite-on-update/delete semantics.
- API is TCP JSON-line protocol only (no HTTP/gRPC layer).