Class: Pikuri::VectorDb::Server::Qdrant
- Inherits:
-
Object
- Object
- Pikuri::VectorDb::Server::Qdrant
- Defined in:
- lib/pikuri/vector_db/server/qdrant.rb
Overview
Supervisor for a self-managed Qdrant docker container. Pairs with Backend::Qdrant exactly as Chroma pairs with Backend::Chroma: this class owns the process; the backend owns the HTTP client. #client returns a Backend::Qdrant pre-pointed at the running container.
Like Chroma, this class carries only the engine’s identity — image pin, container name, persist path, heartbeat path — and composes a DockerContainer for the docker work and the shared rationale (namespace squat, ephemeral-container-persistent-data, subprocess seam, 127.0.0.1 binding, loud boot / quiet teardown).
The port 6333 caveat
Published on 127.0.0.1:#{port} only, same privacy posture as Chroma. Note that pikuri-memory‘s Mem0Server compose stack also publishes its own internal Qdrant on host port 6333 (for inspection). The two are separate instances by design (see DESIGN.md §“Verdict”); running both on one host at the defaults collides on the port —pass a different port: to this supervisor when the mem0 stack is up.
Constant Summary collapse
- IMAGE =
Returns pinned qdrant docker image. Bumping this constant is how the codebase upgrades the qdrant version (#ensure_running! recreates the container from scratch on the next boot; the bind-mounted data dir is untouched). **Kept in lockstep with
Pikuri::Memory::Mem0Server::DEFAULT_QDRANT_IMAGE** —same tag, so a host running both stacks holds one image on disk. The gems don’t depend on each other, so the pin is a convention, not a shared constant; bump both together. Seepikuri-vectordb/DESIGN.md§“Verdict”. 'qdrant/qdrant:v1.12.4'- CONTAINER_NAME =
Returns the container name pikuri claims for its qdrant supervisor — the “pikuri-internal-” namespace squat (see DockerContainer).
'pikuri-internal-qdrant'- LABEL =
Returns docker label set on every container this class creates. Same label as Chroma::LABEL.
'pikuri.internal=true'- CONTAINER_PERSIST_DIR =
Returns path inside the container where qdrant persists its data — the
-vtarget the host’s #default_data_dir bind-mounts onto./qdrant/storageis the image’s documented storage root (the same pathpikuri-memory‘s compose file mounts). '/qdrant/storage'- DEFAULT_PORT =
Returns default host port, qdrant’s native REST port. See the class header for the collision caveat with the mem0 stack’s inspection port.
6333- DEFAULT_HEALTHCHECK_TIMEOUT =
Returns default seconds to wait for the container’s HTTP heartbeat to start returning 200 after docker run.
30
Instance Attribute Summary collapse
-
#data_dir ⇒ Pathname
readonly
Host-side data directory.
-
#port ⇒ Integer
readonly
Host-side port.
Class Method Summary collapse
-
.ensure_running(data_dir: nil, port: DEFAULT_PORT, healthcheck_timeout: DEFAULT_HEALTHCHECK_TIMEOUT) ⇒ Server::Qdrant
Construct a server and immediately ensure it’s running.
Instance Method Summary collapse
-
#client(collection:) ⇒ Backend::Qdrant
Build a Backend::Qdrant pointing at the supervised container.
-
#close ⇒ void
Remove the supervised container (+docker rm -f+), leaving the bind-mounted #data_dir — the corpus survives.
-
#default_data_dir ⇒ String
Default host-side data directory: $XDG_CACHE_HOME/pikuri/qdrant if set, else ~/.cache/pikuri/qdrant.
-
#endpoint ⇒ String
“localhost:<port>”.
-
#ensure_running! ⇒ void
Idempotent: ensure a fresh container is running and healthy (see DockerContainer#ensure_running! for the reuse-or-recreate algorithm), then register #close with Finalizers — once — so the container is removed at process exit.
- #initialize(data_dir: nil, port: DEFAULT_PORT, healthcheck_timeout: DEFAULT_HEALTHCHECK_TIMEOUT, connection: nil) ⇒ Server::Qdrant constructor
Constructor Details
#initialize(data_dir: nil, port: DEFAULT_PORT, healthcheck_timeout: DEFAULT_HEALTHCHECK_TIMEOUT, connection: nil) ⇒ Server::Qdrant
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 98 def initialize(data_dir: nil, port: DEFAULT_PORT, healthcheck_timeout: DEFAULT_HEALTHCHECK_TIMEOUT, connection: nil) @data_dir = Pathname.new(data_dir || default_data_dir). @port = port @container = DockerContainer.new( name: CONTAINER_NAME, image: IMAGE, label: LABEL, host_port: port, container_port: 6333, volume: "#{@data_dir}:#{CONTAINER_PERSIST_DIR}", health_path: '/healthz', healthcheck_timeout: healthcheck_timeout, connection: connection ) @finalizer_handle = nil end |
Instance Attribute Details
#data_dir ⇒ Pathname (readonly)
Returns host-side data directory.
115 116 117 |
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 115 def data_dir @data_dir end |
#port ⇒ Integer (readonly)
Returns host-side port.
118 119 120 |
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 118 def port @port end |
Class Method Details
.ensure_running(data_dir: nil, port: DEFAULT_PORT, healthcheck_timeout: DEFAULT_HEALTHCHECK_TIMEOUT) ⇒ Server::Qdrant
Construct a server and immediately ensure it’s running. Convenience factory — equivalent to new(…).tap(&:ensure_running!).
82 83 84 85 86 87 88 |
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 82 def self.ensure_running(data_dir: nil, port: DEFAULT_PORT, healthcheck_timeout: DEFAULT_HEALTHCHECK_TIMEOUT) new( data_dir: data_dir, port: port, healthcheck_timeout: healthcheck_timeout ).tap(&:ensure_running!) end |
Instance Method Details
#client(collection:) ⇒ Backend::Qdrant
Build a Backend::Qdrant pointing at the supervised container. Constructor convenience — the supervisor carries the host/port, the caller carries the collection name.
133 134 135 |
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 133 def client(collection:) Backend::Qdrant.new(host: 'localhost', port: @port, collection: collection) end |
#close ⇒ void
This method returns an undefined value.
Remove the supervised container (+docker rm -f+), leaving the bind-mounted #data_dir — the corpus survives. Registered with Finalizers by #ensure_running!; safe to call directly too. Best-effort and idempotent — see DockerContainer#close.
160 161 162 |
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 160 def close @container.close end |
#default_data_dir ⇒ String
Default host-side data directory: $XDG_CACHE_HOME/pikuri/qdrant if set, else ~/.cache/pikuri/qdrant. Public so tests and chapter examples can reference the same path the supervisor resolves at runtime.
171 172 173 |
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 171 def default_data_dir Pikuri::Paths.cache.join('qdrant').to_s end |
#endpoint ⇒ String
Returns “localhost:<port>”. Useful for wiring custom Backend::Qdrant constructions.
122 123 124 |
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 122 def endpoint @container.endpoint end |
#ensure_running! ⇒ void
This method returns an undefined value.
Idempotent: ensure a fresh container is running and healthy (see DockerContainer#ensure_running! for the reuse-or-recreate algorithm), then register #close with Finalizers — once — so the container is removed at process exit.
146 147 148 149 150 151 |
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 146 def ensure_running! FileUtils.mkdir_p(@data_dir) @container.ensure_running! @finalizer_handle ||= Pikuri::Finalizers.register(self) nil end |