emb 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 361d0b6f4a7719829d4e87426227fc567af79bd16862019754c19977ddd7b11d
4
- data.tar.gz: a0d165464592eaf05555ef4c8fd8400be52db48353a5f57d9e13c0e7d9b6c26a
3
+ metadata.gz: 7fa662777093c5abee44186eba00b90fde9f1d3cd7bafcde73fc88748dd45478
4
+ data.tar.gz: ba3544c2dc3e1fc875f8d86d3448b8469fd194f2f9f9a12cbf2c8a6a18353ce2
5
5
  SHA512:
6
- metadata.gz: 39ad4fa8bcf1b35d5162c503c3cafcb8a94194550c370cc5135015e3285e20cead32492ddab35306ac086d8efa51b6ec52a984aeb5e18888391edfd4c10e0d8b
7
- data.tar.gz: 86105916d29f1a8386578e15ecfd4965eb7be8aefa00cf59c5160ca93f6bd0653aac71bc762ed10e678c8c7624d1512c9c211e31bd3f22fd127457faec108624
6
+ metadata.gz: 5091504bd2fc95a74f2f0430b76a2dd029f26c3c514ecf0a1a47e8262bc21374e27786fc4f3b734c79df075d2c33794db90f3c31c5e20d45e7c10ebf99e70eec
7
+ data.tar.gz: 67fd93e9b4b45e0155d3cb1f9165f31810571d9eac1468e0bdbbfcf8429dc9089335961b7004bafa28176e2297602dbec7fcd4abdc794c15ffd5acb0f8ab024c
data/README.md CHANGED
@@ -36,8 +36,6 @@ Emb.setup(host: "localhost", port: 6379)
36
36
  Emb.setup
37
37
  ```
38
38
 
39
- `Emb.config` is an alias for `Emb.setup`.
40
-
41
39
  ### Configuration sources (priority order)
42
40
 
43
41
  1. Explicit `url:` or `host:`/`port:` arguments
@@ -160,7 +158,7 @@ Emb.setup
160
158
  Emb[:minilm]["hello"] # proxy access
161
159
  Emb.models # list models
162
160
  Emb.info(:minilm) # model info
163
- Emb.stats # server stats
161
+ Emb.stats # server stats (Hash of key => value)
164
162
  Emb.help # command reference
165
163
  Emb.ping # health check
166
164
  ```
@@ -169,6 +167,67 @@ These all delegate to a lazily-initialized default client. No explicit `setup` c
169
167
  is required for simple cases — the default client connects to `redis://localhost:6379`
170
168
  automatically.
171
169
 
170
+ ## Server info & config
171
+
172
+ The server exposes Redis-style `INFO` and `CONFIG` commands; the gem wraps them.
173
+
174
+ ### `Emb.stats` — server statistics as a hash
175
+
176
+ `EMB.STATS` is decoded into a Symbol-keyed Hash with values as the server sent them
177
+ (RESP integers stay Integer, everything else String):
178
+
179
+ ```ruby
180
+ Emb.stats
181
+ # => {uptime_secs: 3, total_requests: 0, active_requests: "0", total_tokens: 0,
182
+ # total_errors: 0, models_loaded: 1, per_model: "minilm: req=0 avg=0us tok=0 ...",
183
+ # cache_hits: 0, cache_misses: 0, cache_evictions: 0}
184
+ ```
185
+
186
+ > **Breaking change (gem ≥ next release):** `Emb.stats` used to return the raw
187
+ > RESP array (`["uptime_secs", 3, "total_requests", 0, ...]`). It now returns the
188
+ > Hash above. Callers using `stats.each_slice(2)` or array indexing must migrate.
189
+
190
+ ### `Emb.server_info` — sectioned INFO, parsed
191
+
192
+ The Redis-style `INFO` reply is parsed into a nested Hash. **No arguments = all
193
+ sections**; pass section names to filter (`:server`, `:cache`, `:keyspace`, `:stats`, `:clients`):
194
+
195
+ ```ruby
196
+ Emb.server_info
197
+ # => {Server: {redis_version: "0.2.4", emb_version: "0.2.4", uptime_secs: "7", ...},
198
+ # Cache: {cache_hits: 0, cache_misses: 0, cache_hit_rate: "0.0%", ...},
199
+ # Keyspace: {db0: "model=minilm,keys=0,hits=0,misses=0,hit_rate=0.0%"}, ...}
200
+
201
+ Emb.server_info(:server, :cache) # only those two sections
202
+ ```
203
+
204
+ ### `Emb.config` — hot config read & change
205
+
206
+ `Emb.config` is a Hash-like live view of the server's runtime configuration
207
+ (backed by `CONFIG GET` / `CONFIG SET`). **Note:** the former `Emb.config` alias
208
+ for `Emb.setup` is gone — use `Emb.setup` to configure the client.
209
+
210
+ ```ruby
211
+ Emb.config.to_h # all parameters
212
+ # => {"cache" => "auto", "cache_file" => "", "cache_save" => "", "listen" => ":6379",
213
+ # "password" => "", "models" => "minilm,bge", "tls_cert" => "", "tls_key" => ""}
214
+
215
+ Emb.config['cache'] # exact key => String value
216
+ # => "auto"
217
+ Emb.config['cache*'] # glob => Hash of matching parameters
218
+ Emb.config['listen'] # unknown key => nil
219
+
220
+ Emb.config['cache'] = '100MB' # live change; returns "OK"
221
+ Emb.config['cache_file'] = '/var/lib/emb/cache.rdb'
222
+ ```
223
+
224
+ Values are Strings (config is text, not metrics) and round-trip into writers
225
+ unchanged. `cache` resizes immediately, `cache_file`/`cache_save` apply at the
226
+ next snapshot save, `password` affects new connections. Errors surface as
227
+ exceptions (`RedisClient::CommandError`): read-only parameters (`listen`, `tls_*`,
228
+ `models`), invalid values, and `NOAUTH` on password-protected servers are not
229
+ swallowed.
230
+
172
231
  ## Usage
173
232
 
174
233
  ### Single text
data/lib/emb/client.rb CHANGED
@@ -5,6 +5,8 @@ require 'redis_client'
5
5
 
6
6
  module Emb
7
7
  class Client
8
+ include Commands
9
+
8
10
  attr_reader :pool
9
11
 
10
12
  def initialize(pool: nil, batch: nil, **redis_options)
@@ -45,6 +47,11 @@ module Emb
45
47
  @batch_enabled
46
48
  end
47
49
 
50
+ # Live view of the server's runtime configuration (CONFIG GET/SET).
51
+ def config
52
+ @config ||= RuntimeConfig.new(self)
53
+ end
54
+
48
55
  def models
49
56
  raw = send_command('EMB.MODELS')
50
57
  return [] if raw.nil?
@@ -63,8 +70,6 @@ module Emb
63
70
  .to_h { |k, v| [k.to_sym, v] }
64
71
  end
65
72
 
66
- def stats = send_command('EMB.STATS')
67
-
68
73
  def help = send_command('EMB.HELP')
69
74
 
70
75
  def ping = send_command('PING')
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Emb
4
+ # Server-status and runtime-config command wrappers. They only depend on
5
+ # #send_command, so they live in this module (included into Emb::Client)
6
+ # rather than growing the client class.
7
+ module Commands
8
+ # EMB.STATS as a Symbol-keyed Hash. No client-side type layer: values are
9
+ # exactly what the RESP decoder returned (Integer where the server sends
10
+ # RESP integers, String otherwise).
11
+ def stats
12
+ raw = send_command('EMB.STATS')
13
+ raw.each_slice(2).to_h { |key, value| [key.to_sym, value] }
14
+ end
15
+
16
+ # Server-wide INFO (the Redis-style sectioned command). No sections =
17
+ # all sections; any number of sections filter the reply.
18
+ def server_info(*sections)
19
+ parse_info(send_command('INFO', *sections.map(&:to_s)))
20
+ end
21
+
22
+ private
23
+
24
+ # Parse Redis INFO section text into a nested Hash:
25
+ # {Server: {redis_version: "0.2.4", uptime_secs: "7"}, Cache: {…}, …}
26
+ # Section names and keys are Symbols; values pass through as the server
27
+ # sent them. Lines that don't fit the grammar are ignored.
28
+ def parse_info(text)
29
+ sections = {}
30
+ current = nil
31
+
32
+ text.split("\r\n").each do |line|
33
+ if line.start_with?('# ')
34
+ current = line[2..].to_sym
35
+ sections[current] ||= {}
36
+ elsif current && line.include?(':')
37
+ key, value = line.split(':', 2)
38
+ sections[current][key.to_sym] = value
39
+ end
40
+ end
41
+
42
+ sections
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Emb
4
+ # Hash-like live view of the server's runtime configuration, backed by
5
+ # CONFIG GET / CONFIG SET.
6
+ #
7
+ # config.to_h # => { "cache" => "auto", "listen" => ":6379", … }
8
+ # config['cache'] # => "auto" (scalar for an exact key)
9
+ # config['cache*'] # => { "cache" => …, "cache_file" => … } (glob)
10
+ # config['cache_file'] = '/var/lib/emb/cache.rdb' # => "OK"
11
+ #
12
+ # Values are Strings (config is text, not metrics) and round-trip into
13
+ # writers unchanged. Server errors (unknown/read-only parameter, invalid
14
+ # value, NOAUTH) raise RedisClient::CommandError.
15
+ class RuntimeConfig
16
+ def initialize(client)
17
+ @client = client
18
+ end
19
+
20
+ # All parameters as a String-keyed Hash (CONFIG GET).
21
+ def to_h
22
+ pairs(@client.send_command('CONFIG', 'GET'))
23
+ end
24
+
25
+ # Read one parameter or a glob. An exact key returns its String value
26
+ # (nil when the server has no such parameter); a glob that matches
27
+ # several parameters returns a Hash.
28
+ def [](key)
29
+ key = key.to_s
30
+ map = pairs(@client.send_command('CONFIG', 'GET', key))
31
+ return map[key] if map.key?(key)
32
+
33
+ map.empty? ? nil : map
34
+ end
35
+
36
+ # Write one parameter (CONFIG SET). Returns the server's reply ("OK").
37
+ def []=(key, value)
38
+ @client.send_command('CONFIG', 'SET', key.to_s, value.to_s)
39
+ end
40
+
41
+ private
42
+
43
+ def pairs(raw)
44
+ raw.each_slice(2).to_h { |k, v| [k, v] }
45
+ end
46
+ end
47
+ end
data/lib/emb.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require_relative 'emb/version'
4
4
  require_relative 'emb/configuration'
5
+ require_relative 'emb/commands'
6
+ require_relative 'emb/runtime_config'
5
7
  require_relative 'emb/client'
6
8
  require_relative 'emb/proxy'
7
9
  require_relative 'emb/multi'
@@ -16,8 +18,6 @@ module Emb
16
18
  @default_client = Client.new(...)
17
19
  end
18
20
 
19
- alias config setup
20
-
21
21
  def configuration
22
22
  @configuration ||= Configuration.new
23
23
  end
@@ -32,6 +32,8 @@ module Emb
32
32
  def models = default_client.models
33
33
  def info(name) = default_client.info(name)
34
34
  def stats = default_client.stats
35
+ def server_info(*sections) = default_client.server_info(*sections)
36
+ def config = default_client.config
35
37
  def help = default_client.help
36
38
  def ping = default_client.ping
37
39
  def ready = default_client.ready
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: emb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - elcuervo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-26 00:00:00.000000000 Z
11
+ date: 2026-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: batch-loader
@@ -64,10 +64,12 @@ files:
64
64
  - lib/emb.rb
65
65
  - lib/emb/batch.rb
66
66
  - lib/emb/client.rb
67
+ - lib/emb/commands.rb
67
68
  - lib/emb/configuration.rb
68
69
  - lib/emb/middleware.rb
69
70
  - lib/emb/multi.rb
70
71
  - lib/emb/proxy.rb
72
+ - lib/emb/runtime_config.rb
71
73
  - lib/emb/version.rb
72
74
  homepage: https://github.com/elcuervo/emb
73
75
  licenses: