emb — Ruby client
Thin Ruby wrapper for emb, a Redis-compatible embedding server. Auto-decodes float32 binary responses to Ruby arrays.
Installation
Add to your Gemfile:
gem "emb"
Or install globally:
gem install emb
Setup
The client connects to an emb server via the Redis protocol (RESP2). Configure with a URL, host/port, or rely on defaults and environment variables:
require "emb"
# URL (Redis URL format)
Emb.setup(url: "redis://localhost:6379")
# Or individual params
Emb.setup(host: "localhost", port: 6379)
# Or rely on defaults
Emb.setup
Emb.config is an alias for Emb.setup.
Configuration sources (priority order)
- Explicit
url:orhost:/port:arguments EMB_URLenvironment variable- Default:
redis://localhost:6379
Connection pool
Emb.setup(url: "redis://localhost:6379", pool: 10)
Authentication
If the server is configured with a password, include it in the URL:
# Password as URL userinfo
Emb.setup(url: "redis://:hunter2@localhost:6379")
The RedisClient gem handles AUTH automatically on connect when a password
is embedded in the URL. This works correctly with connection pooling — every
connection in the pool authenticates on creation.
Manual authentication is also possible but not recommended for pooled connections:
Emb.send_command("AUTH", "hunter2") # only authenticates one connection
Redis client options
Any RedisClient option can be forwarded through Emb.setup or Emb.new:
Emb.setup(
url: "redis://localhost:6379",
pool: 10,
connect_timeout: 2,
read_timeout: 10,
write_timeout: 5,
reconnect_attempts: 5,
ssl: true,
ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_PEER },
driver: :hiredis,
inherit_socket: true
)
See the redis-client documentation for
all available options. Only pool is handled by the gem — everything else passes
through to RedisClient.new.
Instance-based clients
Create independent clients to connect to multiple servers or use different configurations:
default = Emb.setup(url: "redis://localhost:6379")
other = Emb.new(url: "redis://:hunter2@10.0.0.1:6380")
default.ping # => "PONG"
other.ping # => "PONG"
Each client has its own connection pool and model proxy registry:
c1 = Emb.new(url: "redis://server1:6379")
c2 = Emb.new(url: "redis://server2:6379")
c1[:minilm] != c2[:minilm] # separate proxies
Global convenience API
When you don't need multiple clients, use the module-level methods:
Emb.setup
Emb[:minilm]["hello"] # proxy access
Emb.models # list models
Emb.info(:minilm) # model info
Emb.stats # server stats
Emb.help # command reference
Emb.ping # health check
These all delegate to a lazily-initialized default client. No explicit setup call
is required for simple cases — the default client connects to redis://localhost:6379
automatically.
Usage
Single text
result = Emb[:minilm]["hello world"]
# => [0.0123, -0.0456, 0.0789, ...] (384 floats)
With an instance-based client:
client = Emb.new(url: "redis://localhost:6379")
result = client[:minilm]["hello world"]
Multiple texts
results = Emb[:minilm]["hello", "world"]
# => [[0.0123, ...], [-0.0456, ...]]
Multi-model queries
Send texts to different models in one round trip:
results = Emb.multi do |m|
m[:minilm]["hello"]
m[:bge]["world"]
end
# => [[0.0123, ...], [-0.0456, ...]]
# Results are unpacked from float32 binary — same format as single embeddings
Works the same on instance clients:
client.multi do |m|
m[:minilm]["hello"]
m[:bge]["world"]
end
Commands
Emb.models # => [{name: "minilm", dim: 384, status: "ready"}, ...]
Emb.info(:minilm) # => {dim: 384, workers: 10, requests: 42, ...}
Emb.stats # => server statistics hash
Emb.help # => command reference string
Emb.ping # => "PONG"
Development
Console
Start an IRB session with the gem loaded:
bundle exec rake console
Lint
bundle exec rubocop
Tests
Start the emb server, then run the test suite:
# From the repo root:
./bin/emb -config test-two-models.yaml &
# From gems/emb/:
bundle exec rake
Tests cover all commands: EMB, EMB.MODELS, EMB.INFO, EMB.HELP, PING,
and EMB.MULTI, plus instance-based clients, URL configuration, and connection pooling.