Class: Pikuri::VectorDb::Server::Qdrant

Inherits:
Object
  • Object
show all
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. See pikuri-vectordb/DESIGN.md §“Verdict”.

Returns:

  • (String)

    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. See pikuri-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).

Returns:

  • (String)

    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.

Returns:

  • (String)

    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 -v target the host’s #default_data_dir bind-mounts onto. /qdrant/storage is the image’s documented storage root (the same path pikuri-memory‘s compose file mounts).

Returns:

  • (String)

    path inside the container where qdrant persists its data — the -v target the host’s #default_data_dir bind-mounts onto. /qdrant/storage is the image’s documented storage root (the same path pikuri-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.

Returns:

  • (Integer)

    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.

Returns:

  • (Integer)

    default seconds to wait for the container’s HTTP heartbeat to start returning 200 after docker run.

30

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data_dir: nil, port: DEFAULT_PORT, healthcheck_timeout: DEFAULT_HEALTHCHECK_TIMEOUT, connection: nil) ⇒ Server::Qdrant

Parameters:

  • data_dir (String, Pathname, nil) (defaults to: nil)

    host path to bind-mount as qdrant’s storage dir. nil resolves to #default_data_dir.

  • port (Integer) (defaults to: DEFAULT_PORT)

    host port to publish.

  • healthcheck_timeout (Integer) (defaults to: DEFAULT_HEALTHCHECK_TIMEOUT)
  • connection (Faraday::Connection, nil) (defaults to: nil)

    DI hook for tests. Production callers leave it nil.



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).expand_path
  @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_dirPathname (readonly)

Returns host-side data directory.

Returns:

  • (Pathname)

    host-side data directory.



115
116
117
# File 'lib/pikuri/vector_db/server/qdrant.rb', line 115

def data_dir
  @data_dir
end

#portInteger (readonly)

Returns host-side port.

Returns:

  • (Integer)

    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!).

Parameters:

  • data_dir (String, Pathname, nil) (defaults to: nil)

    host path bind-mounted into the container’s persist directory. nil resolves to #default_data_dir. Created if missing.

  • port (Integer) (defaults to: DEFAULT_PORT)

    host port bound to qdrant’s 6333. Bound to 127.0.0.1 only.

  • healthcheck_timeout (Integer) (defaults to: DEFAULT_HEALTHCHECK_TIMEOUT)

    seconds to poll /healthz before giving up.

Returns:



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.

Parameters:

  • collection (String)

    Qdrant collection name.

Returns:



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

#closevoid

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_dirString

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.

Returns:

  • (String)


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

#endpointString

Returns localhost:<port>”. Useful for wiring custom Backend::Qdrant constructions.

Returns:

  • (String)

    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.

Raises:

  • (RuntimeError)

    on missing docker, any docker command failure, or healthcheck timeout.



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