A Qdrant memory backend for the hive ecosystem, built to degrade instead of fail. An unreachable cluster does not turn into an exception at the call site: writes queue, reads answer degraded, and the queue drains when the circuit closes again.
;; deps.edn
io.github.hive-agi/hive-qdrant {:mvn/version "0.1.9"}
QdrantMemoryStore implements IMemoryStore from
hive-spi — the port leaf, not
hive-mcp. The published jar therefore carries no host dependency: the core
store, queue and migrate namespaces depend only on the ports, and the host
integration files (addon.clj, lifecycle.clj) are excluded from both the jar
and the pom.
That is the ecosystem rule this library exists to respect: the core owns the ports, an addon owns the adapter, and a new vector backend requires zero edits to the core.
| Namespace | Role |
|---|---|
hive-qdrant.store | IMemoryStore implementation over clj-qdrant |
hive-qdrant.circuit | Circuit breaker — :closed (normal), :open (fail fast), :half-open (probing) |
hive-qdrant.queue | JVM-wide write queue; on :open mutations enqueue rather than error, reads return a degraded response |
hive-qdrant.failure | Closed :error/* taxonomy plus translation to the legacy {:success? false :errors […]} shape |
hive-qdrant.config | Typed env wiring — host, port, api-key, TLS. Only the connection surface is operator-tunable |
hive-qdrant.deadline | Per-call gRPC deadline on every read RPC: 15 s for retrieve, scroll and count, 60 s for search (QDRANT_READ_DEADLINE_MS, QDRANT_SEARCH_DEADLINE_MS). A stalled store ends the call, and frees its thread, with DEADLINE_EXCEEDED. Writes (upsert, delete, collection and payload index creates) carry 30 s (QDRANT_WRITE_DEADLINE_MS); a write that misses it fails on the circuit and is queued for replay. An unusable value (not a whole number of ms from 1 to 3600000) falls back to the default with one warning and never stops the store from starting |
hive-qdrant.connect | What connect! does to qdrant: open the client under a 5 s health check, then ensure the collection and its payload indexes. A store that cannot be reached keeps its client, so the circuit and the queue own its writes; a store that is connected and answers nothing, at the health check or at any probe or create after it, fails connect! |
hive-qdrant.migrate | Chroma / Milvus → Qdrant migration, with the extraction step behind a pluggable :source-fn |
hive-qdrant.addon | IAddon registration (host-side, not shipped) |
hive-qdrant.lifecycle | IShutdownHook, priority 210 — the client band (host-side, not shipped) |
When the breaker transitions back to :closed, drain! flushes the queue
through a single-writer core.async pipeline, coalescing by (op, id) so only
the latest mutation for an entry is replayed.
The store slot and the addon id are both parameterizable, so several
QdrantAddon instances can coexist — carto, kanban, and so on — each backed by
its own collection, and each visible to the addon registry as distinct.
MIT.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |