turbopuffer 2.9.0 → 2.10.0
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 +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +1 -1
- data/lib/turbopuffer/internal/telemetry.rb +86 -10
- data/lib/turbopuffer/models/encryption.rb +11 -1
- data/lib/turbopuffer/models/namespace_explain_query_params.rb +50 -24
- data/lib/turbopuffer/models/namespace_multi_query_params.rb +50 -24
- data/lib/turbopuffer/models/namespace_query_params.rb +50 -24
- data/lib/turbopuffer/resources/namespaces.rb +3 -3
- data/lib/turbopuffer/version.rb +1 -1
- data/rbi/turbopuffer/internal/telemetry.rbi +43 -3
- data/rbi/turbopuffer/models/encryption.rbi +29 -2
- data/rbi/turbopuffer/models/namespace_explain_query_params.rbi +84 -71
- data/rbi/turbopuffer/models/namespace_multi_query_params.rbi +86 -71
- data/rbi/turbopuffer/models/namespace_query_params.rbi +88 -71
- data/rbi/turbopuffer/resources/namespaces.rbi +13 -3
- data/sig/turbopuffer/internal/telemetry.rbs +14 -1
- data/sig/turbopuffer/models/encryption.rbs +22 -3
- data/sig/turbopuffer/models/namespace_explain_query_params.rbs +30 -28
- data/sig/turbopuffer/models/namespace_multi_query_params.rbs +30 -28
- data/sig/turbopuffer/models/namespace_query_params.rbs +30 -26
- data/sig/turbopuffer/resources/namespaces.rbs +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b2a36dd806fc7e21775b4a0edc355e2d22a0414bbf8e9069324514177f082031
|
|
4
|
+
data.tar.gz: '099d6f2b73a34fe9485a2b36501cc26b4c9a74f4369f69d61b193b423b82e9d2'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3a2e126a3c4ae82652aebeaa7a58ecf06207780366faa8e913a598bcc49d8c6c8be90d47bfdb9059206ba03be5b8ed2425cca5004673b0914201d8e87ce9c317
|
|
7
|
+
data.tar.gz: 584446333353eced6da9ebc066231a892d6ef5a40b58d5e5c4bb260b3b4da73a6e57fe33610af6d34bcee40365024f645df5fb1a6d5caaf9f33777b6bd006742
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.10.0](https://github.com/turbopuffer/turbopuffer-ruby/compare/v2.9.0...v2.10.0) (2026-10-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* openapi: add encryption_context to customer-managed encryption ([1df756b](https://github.com/turbopuffer/turbopuffer-ruby/commit/1df756b4a97d526ced288201f8d7a5193bfd5c8b))
|
|
9
|
+
* Send client-generated request IDs ([#77](https://github.com/turbopuffer/turbopuffer-ruby/issues/77)) ([3812a2f](https://github.com/turbopuffer/turbopuffer-ruby/commit/3812a2fc924254f1c5c8b67a6f8dd6892b02e7aa))
|
|
10
|
+
* spec: split query consistency into strong and eventual variants ([2e12e6c](https://github.com/turbopuffer/turbopuffer-ruby/commit/2e12e6c36b4bb9ba8dcba9ecddfb243d4bda1dd7))
|
|
11
|
+
* tpuf-engine: add max_staleness_seconds to eventual consistency ([e77b67d](https://github.com/turbopuffer/turbopuffer-ruby/commit/e77b67dc350327860e1f2f75702b162d06cb222e))
|
|
12
|
+
|
|
3
13
|
## [2.9.0](https://github.com/turbopuffer/turbopuffer-ruby/compare/v2.8.0...v2.9.0) (2026-10-20)
|
|
4
14
|
|
|
5
15
|
|
data/README.md
CHANGED
|
@@ -9,16 +9,30 @@ module Turbopuffer
|
|
|
9
9
|
# header. The server controls how many requests are recorded by advertising a
|
|
10
10
|
# sample rate in the `X-turbopuffer-Client-Telemetry-Sample-Rate` response header.
|
|
11
11
|
#
|
|
12
|
+
# Each recorded request is sent with an `X-Request-Id` that its record repeats, so the
|
|
13
|
+
# server can show the client's timings in the same trace as its own.
|
|
14
|
+
#
|
|
12
15
|
# @api private
|
|
13
16
|
module Telemetry
|
|
14
17
|
ENV_VAR = "TURBOPUFFER_TELEMETRY"
|
|
15
18
|
HEADER = "x-turbopuffer-client-telemetry"
|
|
16
19
|
SAMPLE_RATE_HEADER = "x-turbopuffer-client-telemetry-sample-rate"
|
|
20
|
+
# Sorted by ASCII value, so that encoded IDs sort like their bytes.
|
|
21
|
+
REQUEST_ID_ALPHABET = "234567abcdefghijklmnopqrstuvwxyz"
|
|
22
|
+
# The bytes in a request ID before it's encoded. The first `REQUEST_ID_RANDOM_BYTES` are
|
|
23
|
+
# random, and the rest hold the time it was generated.
|
|
24
|
+
REQUEST_ID_BYTES = 18
|
|
25
|
+
# The request header that carries the IDs of recorded requests.
|
|
26
|
+
REQUEST_ID_HEADER = "x-request-id"
|
|
27
|
+
# The prefix of generated request IDs.
|
|
28
|
+
REQUEST_ID_PREFIX = "tpreq_"
|
|
29
|
+
# The random bytes at the start of a request ID.
|
|
30
|
+
REQUEST_ID_RANDOM_BYTES = 12
|
|
17
31
|
|
|
18
32
|
ENVELOPE_VERSION = 1
|
|
19
33
|
|
|
20
34
|
# Keeps the header well under the 8 KB per-line limit of common proxies.
|
|
21
|
-
MAX_RECORDS_PER_HEADER =
|
|
35
|
+
MAX_RECORDS_PER_HEADER = 16
|
|
22
36
|
MAX_BUFFERED_RECORDS = 1000
|
|
23
37
|
|
|
24
38
|
TRUE_VALUES = %w[1 true yes on].freeze
|
|
@@ -124,6 +138,37 @@ module Turbopuffer
|
|
|
124
138
|
# @return [Float]
|
|
125
139
|
def random = Kernel.rand
|
|
126
140
|
|
|
141
|
+
# @api private
|
|
142
|
+
#
|
|
143
|
+
# Encodes `bytes` in base32 with `REQUEST_ID_ALPHABET`, in RFC 4648's bit order without
|
|
144
|
+
# padding.
|
|
145
|
+
#
|
|
146
|
+
# @param bytes [String]
|
|
147
|
+
#
|
|
148
|
+
# @return [String]
|
|
149
|
+
def encode_base32(bytes)
|
|
150
|
+
bytes.unpack1("B*").scan(/.{1,5}/).map { REQUEST_ID_ALPHABET[_1.ljust(5, "0").to_i(2)] }.join
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# @api private
|
|
154
|
+
#
|
|
155
|
+
# Generates the ID of a request that will be recorded. Its format is private to turbopuffer,
|
|
156
|
+
# which only links IDs in the format it expects: 12 random bytes, then the 48-bit
|
|
157
|
+
# millisecond time they were generated XORed with the first 6 random bytes, in base32
|
|
158
|
+
# after a prefix.
|
|
159
|
+
#
|
|
160
|
+
# @param now [Time]
|
|
161
|
+
# @param random [String] overridden by tests
|
|
162
|
+
#
|
|
163
|
+
# @return [String]
|
|
164
|
+
def new_request_id(now, random: SecureRandom.random_bytes(REQUEST_ID_RANDOM_BYTES))
|
|
165
|
+
millis = (now.to_r * 1000).floor
|
|
166
|
+
# The low bytes of the big-endian time.
|
|
167
|
+
time = [millis].pack("Q>").bytes.last(REQUEST_ID_BYTES - REQUEST_ID_RANDOM_BYTES)
|
|
168
|
+
masked = time.zip(random.bytes).map { _1 ^ _2 }.pack("C*")
|
|
169
|
+
REQUEST_ID_PREFIX + encode_base32(random + masked)
|
|
170
|
+
end
|
|
171
|
+
|
|
127
172
|
# @api private
|
|
128
173
|
#
|
|
129
174
|
# Returns the buffer shared by clients with the same API key and base URL, or nil if
|
|
@@ -234,33 +279,48 @@ module Turbopuffer
|
|
|
234
279
|
|
|
235
280
|
# @api private
|
|
236
281
|
#
|
|
237
|
-
#
|
|
282
|
+
# Decides whether to record a request that's starting, returning the sample rate it was
|
|
283
|
+
# recorded at.
|
|
284
|
+
#
|
|
285
|
+
# @return [Float, nil]
|
|
286
|
+
def sample
|
|
287
|
+
rate = @sample_rate
|
|
288
|
+
return nil if rate <= 0.0 || (rate < 1.0 && Telemetry.random >= rate)
|
|
289
|
+
rate
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# @api private
|
|
293
|
+
#
|
|
294
|
+
# Buffers the record of a request sampled at `sample_rate`.
|
|
238
295
|
#
|
|
239
296
|
# @param method [Symbol, String]
|
|
240
297
|
# @param url [URI::Generic, String]
|
|
241
298
|
# @param status [Integer]
|
|
242
299
|
# @param retries [Integer]
|
|
243
300
|
# @param durations [Hash{Symbol=>Integer}] in nanoseconds
|
|
301
|
+
# @param sample_rate [Float]
|
|
244
302
|
# @param server_total_ms [Numeric, nil]
|
|
245
303
|
# @param error [String, nil]
|
|
246
304
|
# @param reused [Boolean, nil]
|
|
305
|
+
# @param request_id [String, nil] the `X-Request-Id` the request was sent with, when the
|
|
306
|
+
# client generated it
|
|
247
307
|
def record(
|
|
248
308
|
method:,
|
|
249
309
|
url:,
|
|
250
310
|
status:,
|
|
251
311
|
retries:,
|
|
252
312
|
durations:,
|
|
313
|
+
sample_rate:,
|
|
253
314
|
server_total_ms: nil,
|
|
254
315
|
error: nil,
|
|
255
|
-
reused: nil
|
|
316
|
+
reused: nil,
|
|
317
|
+
request_id: nil
|
|
256
318
|
)
|
|
257
|
-
rate = @sample_rate
|
|
258
|
-
return if rate <= 0.0 || (rate < 1.0 && Telemetry.random >= rate)
|
|
259
|
-
|
|
260
319
|
rec = {route: Telemetry.route_template(method, url), status: status}
|
|
261
320
|
rec[:error] = error unless error.nil?
|
|
262
321
|
rec[:retries] = retries unless retries.zero?
|
|
263
|
-
rec[:
|
|
322
|
+
rec[:request_id] = request_id unless request_id.nil?
|
|
323
|
+
rec[:sample_rate] = sample_rate if sample_rate < 1.0
|
|
264
324
|
durations.each do |name, duration|
|
|
265
325
|
# A zero compress duration means the body wasn't compressed.
|
|
266
326
|
next if name == :compress && duration.zero?
|
|
@@ -353,6 +413,11 @@ module Turbopuffer
|
|
|
353
413
|
@info = info
|
|
354
414
|
# Kept for later attempts until one of them may have reached the server.
|
|
355
415
|
@batch = nil
|
|
416
|
+
# The rate the request was recorded at, or nil if it isn't recorded. Sampled up front, so
|
|
417
|
+
# that only requests whose records the server will get are sent with request IDs.
|
|
418
|
+
@sample_rate = buffer.sample
|
|
419
|
+
# Sent with every attempt, so retries share the request's trace.
|
|
420
|
+
@request_id = @sample_rate && Telemetry.new_request_id(Time.now)
|
|
356
421
|
end
|
|
357
422
|
|
|
358
423
|
# @api private
|
|
@@ -360,9 +425,15 @@ module Turbopuffer
|
|
|
360
425
|
# @param attempt [Integer]
|
|
361
426
|
# @param request [Hash{Symbol=>Object}]
|
|
362
427
|
def attempt_begin(attempt, request)
|
|
428
|
+
headers = request.fetch(:headers)
|
|
363
429
|
# Taken only once a request is about to be sent, so one that fails before then can't lose it.
|
|
364
|
-
|
|
365
|
-
|
|
430
|
+
if attempt.zero?
|
|
431
|
+
@batch = @buffer.take
|
|
432
|
+
# An ID set by the caller is theirs to use, so the request keeps it and isn't linked.
|
|
433
|
+
@request_id = nil if headers.key?(REQUEST_ID_HEADER)
|
|
434
|
+
end
|
|
435
|
+
headers[HEADER] = @batch.header if @batch
|
|
436
|
+
headers[REQUEST_ID_HEADER] = @request_id if @request_id
|
|
366
437
|
end
|
|
367
438
|
|
|
368
439
|
# @api private
|
|
@@ -388,6 +459,9 @@ module Turbopuffer
|
|
|
388
459
|
@buffer.restore(@batch)
|
|
389
460
|
@batch = nil
|
|
390
461
|
end
|
|
462
|
+
return if @sample_rate.nil?
|
|
463
|
+
# A rate of zero asks clients to stop recording, even requests that were already sampled.
|
|
464
|
+
return if @buffer.sample_rate <= 0.0
|
|
391
465
|
|
|
392
466
|
@buffer.record(
|
|
393
467
|
method: @info.method,
|
|
@@ -395,9 +469,11 @@ module Turbopuffer
|
|
|
395
469
|
status: status(result),
|
|
396
470
|
retries: result.retries,
|
|
397
471
|
durations: durations,
|
|
472
|
+
sample_rate: @sample_rate,
|
|
398
473
|
server_total_ms: server_total_ms(result.parsed),
|
|
399
474
|
error: error_name(result.error_kind),
|
|
400
|
-
reused: timings.reused
|
|
475
|
+
reused: timings.reused,
|
|
476
|
+
request_id: @request_id
|
|
401
477
|
)
|
|
402
478
|
end
|
|
403
479
|
|
|
@@ -25,7 +25,15 @@ module Turbopuffer
|
|
|
25
25
|
# @return [Symbol, :"customer-managed"]
|
|
26
26
|
required :mode, const: :"customer-managed"
|
|
27
27
|
|
|
28
|
-
# @!
|
|
28
|
+
# @!attribute encryption_context
|
|
29
|
+
# The AWS KMS encryption context to send with every request that uses the key.
|
|
30
|
+
# Only supported on AWS, and must be enabled for your organization. Keys may not
|
|
31
|
+
# start with `tpuf:` or `aws:`.
|
|
32
|
+
#
|
|
33
|
+
# @return [Hash{Symbol=>String}, nil]
|
|
34
|
+
optional :encryption_context, Turbopuffer::Internal::Type::HashOf[String]
|
|
35
|
+
|
|
36
|
+
# @!method initialize(key_name:, encryption_context: nil, mode: :"customer-managed")
|
|
29
37
|
# Some parameter documentations has been truncated, see
|
|
30
38
|
# {Turbopuffer::Models::Encryption::CustomerManaged} for more details.
|
|
31
39
|
#
|
|
@@ -33,6 +41,8 @@ module Turbopuffer
|
|
|
33
41
|
#
|
|
34
42
|
# @param key_name [String] The identifier of the CMEK key to use for encryption. For GCP, the fully-qualifi
|
|
35
43
|
#
|
|
44
|
+
# @param encryption_context [Hash{Symbol=>String}] The AWS KMS encryption context to send with every request that uses the key. Onl
|
|
45
|
+
#
|
|
36
46
|
# @param mode [Symbol, :"customer-managed"]
|
|
37
47
|
end
|
|
38
48
|
|
|
@@ -30,8 +30,8 @@ module Turbopuffer
|
|
|
30
30
|
# @!attribute consistency
|
|
31
31
|
# The consistency level for a query.
|
|
32
32
|
#
|
|
33
|
-
# @return [Turbopuffer::Models::NamespaceExplainQueryParams::Consistency, nil]
|
|
34
|
-
optional :consistency, -> { Turbopuffer::NamespaceExplainQueryParams::Consistency }
|
|
33
|
+
# @return [Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Eventual, nil]
|
|
34
|
+
optional :consistency, union: -> { Turbopuffer::NamespaceExplainQueryParams::Consistency }
|
|
35
35
|
|
|
36
36
|
# @!attribute distance_metric
|
|
37
37
|
# A function used to calculate vector similarity.
|
|
@@ -107,7 +107,7 @@ module Turbopuffer
|
|
|
107
107
|
#
|
|
108
108
|
# @param compute_attributes [Hash{Symbol=>Object}] Computes additional values on documents returned by a query. Each key is the nam
|
|
109
109
|
#
|
|
110
|
-
# @param consistency [Turbopuffer::Models::NamespaceExplainQueryParams::Consistency] The consistency level for a query.
|
|
110
|
+
# @param consistency [Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Eventual] The consistency level for a query.
|
|
111
111
|
#
|
|
112
112
|
# @param distance_metric [Symbol, Turbopuffer::Models::DistanceMetric] A function used to calculate vector similarity.
|
|
113
113
|
#
|
|
@@ -131,33 +131,59 @@ module Turbopuffer
|
|
|
131
131
|
#
|
|
132
132
|
# @param request_options [Turbopuffer::RequestOptions, Hash{Symbol=>Object}]
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
optional :level, enum: -> { Turbopuffer::NamespaceExplainQueryParams::Consistency::Level }
|
|
134
|
+
# The consistency level for a query.
|
|
135
|
+
module Consistency
|
|
136
|
+
extend Turbopuffer::Internal::Type::Union
|
|
137
|
+
|
|
138
|
+
discriminator :level
|
|
140
139
|
|
|
141
|
-
#
|
|
142
|
-
|
|
143
|
-
#
|
|
144
|
-
# @param level [Symbol, Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Level] The query's consistency level.
|
|
140
|
+
# Strong consistency. Requires a round-trip to object storage to fetch the latest writes.
|
|
141
|
+
variant :strong, -> { Turbopuffer::NamespaceExplainQueryParams::Consistency::Strong }
|
|
145
142
|
|
|
146
|
-
#
|
|
147
|
-
|
|
148
|
-
# @see Turbopuffer::Models::NamespaceExplainQueryParams::Consistency#level
|
|
149
|
-
module Level
|
|
150
|
-
extend Turbopuffer::Internal::Type::Enum
|
|
143
|
+
# Eventual consistency. Does not require a round-trip to object storage, but may not see the latest writes.
|
|
144
|
+
variant :eventual, -> { Turbopuffer::NamespaceExplainQueryParams::Consistency::Eventual }
|
|
151
145
|
|
|
152
|
-
|
|
153
|
-
|
|
146
|
+
class Strong < Turbopuffer::Internal::Type::BaseModel
|
|
147
|
+
# @!attribute level
|
|
148
|
+
#
|
|
149
|
+
# @return [Symbol, :strong]
|
|
150
|
+
required :level, const: :strong
|
|
154
151
|
|
|
155
|
-
#
|
|
156
|
-
|
|
152
|
+
# @!method initialize(level: :strong)
|
|
153
|
+
# Strong consistency. Requires a round-trip to object storage to fetch the latest
|
|
154
|
+
# writes.
|
|
155
|
+
#
|
|
156
|
+
# @param level [Symbol, :strong]
|
|
157
|
+
end
|
|
157
158
|
|
|
158
|
-
|
|
159
|
-
#
|
|
159
|
+
class Eventual < Turbopuffer::Internal::Type::BaseModel
|
|
160
|
+
# @!attribute level
|
|
161
|
+
#
|
|
162
|
+
# @return [Symbol, :eventual]
|
|
163
|
+
required :level, const: :eventual
|
|
164
|
+
|
|
165
|
+
# @!attribute max_staleness_seconds
|
|
166
|
+
# How long the query may reuse the node's cached view of the namespace before
|
|
167
|
+
# refreshing it from object storage. Defaults to 60.
|
|
168
|
+
#
|
|
169
|
+
# @return [Integer, nil]
|
|
170
|
+
optional :max_staleness_seconds, Integer
|
|
171
|
+
|
|
172
|
+
# @!method initialize(max_staleness_seconds: nil, level: :eventual)
|
|
173
|
+
# Some parameter documentations has been truncated, see
|
|
174
|
+
# {Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Eventual} for
|
|
175
|
+
# more details.
|
|
176
|
+
#
|
|
177
|
+
# Eventual consistency. Does not require a round-trip to object storage, but may
|
|
178
|
+
# not see the latest writes.
|
|
179
|
+
#
|
|
180
|
+
# @param max_staleness_seconds [Integer] How long the query may reuse the node's cached view of the namespace before refr
|
|
181
|
+
#
|
|
182
|
+
# @param level [Symbol, :eventual]
|
|
160
183
|
end
|
|
184
|
+
|
|
185
|
+
# @!method self.variants
|
|
186
|
+
# @return [Array(Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Eventual)]
|
|
161
187
|
end
|
|
162
188
|
|
|
163
189
|
# Limits the documents returned by a query.
|
|
@@ -21,8 +21,8 @@ module Turbopuffer
|
|
|
21
21
|
# @!attribute consistency
|
|
22
22
|
# The consistency level for a query.
|
|
23
23
|
#
|
|
24
|
-
# @return [Turbopuffer::Models::NamespaceMultiQueryParams::Consistency, nil]
|
|
25
|
-
optional :consistency, -> { Turbopuffer::NamespaceMultiQueryParams::Consistency }
|
|
24
|
+
# @return [Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Eventual, nil]
|
|
25
|
+
optional :consistency, union: -> { Turbopuffer::NamespaceMultiQueryParams::Consistency }
|
|
26
26
|
|
|
27
27
|
# @!attribute limit
|
|
28
28
|
# Limits the total number of reranked documents returned.
|
|
@@ -57,7 +57,7 @@ module Turbopuffer
|
|
|
57
57
|
#
|
|
58
58
|
# @param namespace [String]
|
|
59
59
|
#
|
|
60
|
-
# @param consistency [Turbopuffer::Models::NamespaceMultiQueryParams::Consistency] The consistency level for a query.
|
|
60
|
+
# @param consistency [Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Eventual] The consistency level for a query.
|
|
61
61
|
#
|
|
62
62
|
# @param limit [Integer, Turbopuffer::Models::RerankLimit] Limits the total number of reranked documents returned.
|
|
63
63
|
#
|
|
@@ -188,33 +188,59 @@ module Turbopuffer
|
|
|
188
188
|
end
|
|
189
189
|
end
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
#
|
|
195
|
-
# @return [Symbol, Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Level, nil]
|
|
196
|
-
optional :level, enum: -> { Turbopuffer::NamespaceMultiQueryParams::Consistency::Level }
|
|
191
|
+
# The consistency level for a query.
|
|
192
|
+
module Consistency
|
|
193
|
+
extend Turbopuffer::Internal::Type::Union
|
|
197
194
|
|
|
198
|
-
|
|
199
|
-
# The consistency level for a query.
|
|
200
|
-
#
|
|
201
|
-
# @param level [Symbol, Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Level] The query's consistency level.
|
|
195
|
+
discriminator :level
|
|
202
196
|
|
|
203
|
-
#
|
|
204
|
-
|
|
205
|
-
# @see Turbopuffer::Models::NamespaceMultiQueryParams::Consistency#level
|
|
206
|
-
module Level
|
|
207
|
-
extend Turbopuffer::Internal::Type::Enum
|
|
197
|
+
# Strong consistency. Requires a round-trip to object storage to fetch the latest writes.
|
|
198
|
+
variant :strong, -> { Turbopuffer::NamespaceMultiQueryParams::Consistency::Strong }
|
|
208
199
|
|
|
209
|
-
|
|
210
|
-
|
|
200
|
+
# Eventual consistency. Does not require a round-trip to object storage, but may not see the latest writes.
|
|
201
|
+
variant :eventual, -> { Turbopuffer::NamespaceMultiQueryParams::Consistency::Eventual }
|
|
211
202
|
|
|
212
|
-
|
|
213
|
-
|
|
203
|
+
class Strong < Turbopuffer::Internal::Type::BaseModel
|
|
204
|
+
# @!attribute level
|
|
205
|
+
#
|
|
206
|
+
# @return [Symbol, :strong]
|
|
207
|
+
required :level, const: :strong
|
|
214
208
|
|
|
215
|
-
# @!method
|
|
216
|
-
#
|
|
209
|
+
# @!method initialize(level: :strong)
|
|
210
|
+
# Strong consistency. Requires a round-trip to object storage to fetch the latest
|
|
211
|
+
# writes.
|
|
212
|
+
#
|
|
213
|
+
# @param level [Symbol, :strong]
|
|
217
214
|
end
|
|
215
|
+
|
|
216
|
+
class Eventual < Turbopuffer::Internal::Type::BaseModel
|
|
217
|
+
# @!attribute level
|
|
218
|
+
#
|
|
219
|
+
# @return [Symbol, :eventual]
|
|
220
|
+
required :level, const: :eventual
|
|
221
|
+
|
|
222
|
+
# @!attribute max_staleness_seconds
|
|
223
|
+
# How long the query may reuse the node's cached view of the namespace before
|
|
224
|
+
# refreshing it from object storage. Defaults to 60.
|
|
225
|
+
#
|
|
226
|
+
# @return [Integer, nil]
|
|
227
|
+
optional :max_staleness_seconds, Integer
|
|
228
|
+
|
|
229
|
+
# @!method initialize(max_staleness_seconds: nil, level: :eventual)
|
|
230
|
+
# Some parameter documentations has been truncated, see
|
|
231
|
+
# {Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Eventual} for more
|
|
232
|
+
# details.
|
|
233
|
+
#
|
|
234
|
+
# Eventual consistency. Does not require a round-trip to object storage, but may
|
|
235
|
+
# not see the latest writes.
|
|
236
|
+
#
|
|
237
|
+
# @param max_staleness_seconds [Integer] How long the query may reuse the node's cached view of the namespace before refr
|
|
238
|
+
#
|
|
239
|
+
# @param level [Symbol, :eventual]
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# @!method self.variants
|
|
243
|
+
# @return [Array(Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Eventual)]
|
|
218
244
|
end
|
|
219
245
|
|
|
220
246
|
# Limits the total number of reranked documents returned.
|
|
@@ -30,8 +30,8 @@ module Turbopuffer
|
|
|
30
30
|
# @!attribute consistency
|
|
31
31
|
# The consistency level for a query.
|
|
32
32
|
#
|
|
33
|
-
# @return [Turbopuffer::Models::NamespaceQueryParams::Consistency, nil]
|
|
34
|
-
optional :consistency, -> { Turbopuffer::NamespaceQueryParams::Consistency }
|
|
33
|
+
# @return [Turbopuffer::Models::NamespaceQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceQueryParams::Consistency::Eventual, nil]
|
|
34
|
+
optional :consistency, union: -> { Turbopuffer::NamespaceQueryParams::Consistency }
|
|
35
35
|
|
|
36
36
|
# @!attribute distance_metric
|
|
37
37
|
# A function used to calculate vector similarity.
|
|
@@ -113,7 +113,7 @@ module Turbopuffer
|
|
|
113
113
|
#
|
|
114
114
|
# @param compute_attributes [Hash{Symbol=>Object}] Computes additional values on documents returned by a query. Each key is the nam
|
|
115
115
|
#
|
|
116
|
-
# @param consistency [Turbopuffer::Models::NamespaceQueryParams::Consistency] The consistency level for a query.
|
|
116
|
+
# @param consistency [Turbopuffer::Models::NamespaceQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceQueryParams::Consistency::Eventual] The consistency level for a query.
|
|
117
117
|
#
|
|
118
118
|
# @param distance_metric [Symbol, Turbopuffer::Models::DistanceMetric] A function used to calculate vector similarity.
|
|
119
119
|
#
|
|
@@ -139,33 +139,59 @@ module Turbopuffer
|
|
|
139
139
|
#
|
|
140
140
|
# @param request_options [Turbopuffer::RequestOptions, Hash{Symbol=>Object}]
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
optional :level, enum: -> { Turbopuffer::NamespaceQueryParams::Consistency::Level }
|
|
142
|
+
# The consistency level for a query.
|
|
143
|
+
module Consistency
|
|
144
|
+
extend Turbopuffer::Internal::Type::Union
|
|
145
|
+
|
|
146
|
+
discriminator :level
|
|
148
147
|
|
|
149
|
-
#
|
|
150
|
-
|
|
151
|
-
#
|
|
152
|
-
# @param level [Symbol, Turbopuffer::Models::NamespaceQueryParams::Consistency::Level] The query's consistency level.
|
|
148
|
+
# Strong consistency. Requires a round-trip to object storage to fetch the latest writes.
|
|
149
|
+
variant :strong, -> { Turbopuffer::NamespaceQueryParams::Consistency::Strong }
|
|
153
150
|
|
|
154
|
-
#
|
|
155
|
-
|
|
156
|
-
# @see Turbopuffer::Models::NamespaceQueryParams::Consistency#level
|
|
157
|
-
module Level
|
|
158
|
-
extend Turbopuffer::Internal::Type::Enum
|
|
151
|
+
# Eventual consistency. Does not require a round-trip to object storage, but may not see the latest writes.
|
|
152
|
+
variant :eventual, -> { Turbopuffer::NamespaceQueryParams::Consistency::Eventual }
|
|
159
153
|
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
class Strong < Turbopuffer::Internal::Type::BaseModel
|
|
155
|
+
# @!attribute level
|
|
156
|
+
#
|
|
157
|
+
# @return [Symbol, :strong]
|
|
158
|
+
required :level, const: :strong
|
|
162
159
|
|
|
163
|
-
#
|
|
164
|
-
|
|
160
|
+
# @!method initialize(level: :strong)
|
|
161
|
+
# Strong consistency. Requires a round-trip to object storage to fetch the latest
|
|
162
|
+
# writes.
|
|
163
|
+
#
|
|
164
|
+
# @param level [Symbol, :strong]
|
|
165
|
+
end
|
|
165
166
|
|
|
166
|
-
|
|
167
|
-
#
|
|
167
|
+
class Eventual < Turbopuffer::Internal::Type::BaseModel
|
|
168
|
+
# @!attribute level
|
|
169
|
+
#
|
|
170
|
+
# @return [Symbol, :eventual]
|
|
171
|
+
required :level, const: :eventual
|
|
172
|
+
|
|
173
|
+
# @!attribute max_staleness_seconds
|
|
174
|
+
# How long the query may reuse the node's cached view of the namespace before
|
|
175
|
+
# refreshing it from object storage. Defaults to 60.
|
|
176
|
+
#
|
|
177
|
+
# @return [Integer, nil]
|
|
178
|
+
optional :max_staleness_seconds, Integer
|
|
179
|
+
|
|
180
|
+
# @!method initialize(max_staleness_seconds: nil, level: :eventual)
|
|
181
|
+
# Some parameter documentations has been truncated, see
|
|
182
|
+
# {Turbopuffer::Models::NamespaceQueryParams::Consistency::Eventual} for more
|
|
183
|
+
# details.
|
|
184
|
+
#
|
|
185
|
+
# Eventual consistency. Does not require a round-trip to object storage, but may
|
|
186
|
+
# not see the latest writes.
|
|
187
|
+
#
|
|
188
|
+
# @param max_staleness_seconds [Integer] How long the query may reuse the node's cached view of the namespace before refr
|
|
189
|
+
#
|
|
190
|
+
# @param level [Symbol, :eventual]
|
|
168
191
|
end
|
|
192
|
+
|
|
193
|
+
# @!method self.variants
|
|
194
|
+
# @return [Array(Turbopuffer::Models::NamespaceQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceQueryParams::Consistency::Eventual)]
|
|
169
195
|
end
|
|
170
196
|
|
|
171
197
|
# Limits the documents returned by a query.
|
|
@@ -106,7 +106,7 @@ module Turbopuffer
|
|
|
106
106
|
#
|
|
107
107
|
# @param compute_attributes [Hash{Symbol=>Object}] Body param: Computes additional values on documents returned by a query. Each ke
|
|
108
108
|
#
|
|
109
|
-
# @param consistency [Turbopuffer::Models::NamespaceExplainQueryParams::Consistency] Body param: The consistency level for a query.
|
|
109
|
+
# @param consistency [Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceExplainQueryParams::Consistency::Eventual] Body param: The consistency level for a query.
|
|
110
110
|
#
|
|
111
111
|
# @param distance_metric [Symbol, Turbopuffer::Models::DistanceMetric] Body param: A function used to calculate vector similarity.
|
|
112
112
|
#
|
|
@@ -209,7 +209,7 @@ module Turbopuffer
|
|
|
209
209
|
#
|
|
210
210
|
# @param namespace [String] Path param: The name of the namespace.
|
|
211
211
|
#
|
|
212
|
-
# @param consistency [Turbopuffer::Models::NamespaceMultiQueryParams::Consistency] Body param: The consistency level for a query.
|
|
212
|
+
# @param consistency [Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceMultiQueryParams::Consistency::Eventual] Body param: The consistency level for a query.
|
|
213
213
|
#
|
|
214
214
|
# @param limit [Integer, Turbopuffer::Models::RerankLimit] Body param: Limits the total number of reranked documents returned.
|
|
215
215
|
#
|
|
@@ -279,7 +279,7 @@ module Turbopuffer
|
|
|
279
279
|
#
|
|
280
280
|
# @param compute_attributes [Hash{Symbol=>Object}] Body param: Computes additional values on documents returned by a query. Each ke
|
|
281
281
|
#
|
|
282
|
-
# @param consistency [Turbopuffer::Models::NamespaceQueryParams::Consistency] Body param: The consistency level for a query.
|
|
282
|
+
# @param consistency [Turbopuffer::Models::NamespaceQueryParams::Consistency::Strong, Turbopuffer::Models::NamespaceQueryParams::Consistency::Eventual] Body param: The consistency level for a query.
|
|
283
283
|
#
|
|
284
284
|
# @param distance_metric [Symbol, Turbopuffer::Models::DistanceMetric] Body param: A function used to calculate vector similarity.
|
|
285
285
|
#
|
data/lib/turbopuffer/version.rb
CHANGED
|
@@ -9,6 +9,16 @@ module Turbopuffer
|
|
|
9
9
|
ENV_VAR = T.let(T.unsafe(nil), String)
|
|
10
10
|
HEADER = T.let(T.unsafe(nil), String)
|
|
11
11
|
SAMPLE_RATE_HEADER = T.let(T.unsafe(nil), String)
|
|
12
|
+
# Sorted by ASCII value, so that encoded IDs sort like their bytes.
|
|
13
|
+
REQUEST_ID_ALPHABET = T.let(T.unsafe(nil), String)
|
|
14
|
+
# The bytes in a request ID before it's encoded.
|
|
15
|
+
REQUEST_ID_BYTES = T.let(T.unsafe(nil), Integer)
|
|
16
|
+
# The request header that carries the IDs of recorded requests.
|
|
17
|
+
REQUEST_ID_HEADER = T.let(T.unsafe(nil), String)
|
|
18
|
+
# The prefix of generated request IDs.
|
|
19
|
+
REQUEST_ID_PREFIX = T.let(T.unsafe(nil), String)
|
|
20
|
+
# The random bytes at the start of a request ID.
|
|
21
|
+
REQUEST_ID_RANDOM_BYTES = T.let(T.unsafe(nil), Integer)
|
|
12
22
|
|
|
13
23
|
ENVELOPE_VERSION = T.let(T.unsafe(nil), Integer)
|
|
14
24
|
|
|
@@ -60,6 +70,24 @@ module Turbopuffer
|
|
|
60
70
|
def random
|
|
61
71
|
end
|
|
62
72
|
|
|
73
|
+
# @api private
|
|
74
|
+
#
|
|
75
|
+
# Encodes `bytes` in base32 with `REQUEST_ID_ALPHABET`, in RFC 4648's bit order without
|
|
76
|
+
# padding.
|
|
77
|
+
sig { params(bytes: String).returns(String) }
|
|
78
|
+
def encode_base32(bytes)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @api private
|
|
82
|
+
#
|
|
83
|
+
# Generates the ID of a request that will be recorded. Its format is private to turbopuffer.
|
|
84
|
+
sig { params(now: Time, random: String).returns(String) }
|
|
85
|
+
def new_request_id(
|
|
86
|
+
now,
|
|
87
|
+
random: SecureRandom.random_bytes(REQUEST_ID_RANDOM_BYTES)
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
|
|
63
91
|
# @api private
|
|
64
92
|
#
|
|
65
93
|
# Returns the buffer shared by clients with the same API key and base URL, or nil if
|
|
@@ -129,7 +157,15 @@ module Turbopuffer
|
|
|
129
157
|
|
|
130
158
|
# @api private
|
|
131
159
|
#
|
|
132
|
-
#
|
|
160
|
+
# Decides whether to record a request that's starting, returning the sample rate it was
|
|
161
|
+
# recorded at.
|
|
162
|
+
sig { returns(T.nilable(Float)) }
|
|
163
|
+
def sample
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# @api private
|
|
167
|
+
#
|
|
168
|
+
# Buffers the record of a request sampled at `sample_rate`.
|
|
133
169
|
sig do
|
|
134
170
|
params(
|
|
135
171
|
method: T.any(Symbol, String),
|
|
@@ -137,9 +173,11 @@ module Turbopuffer
|
|
|
137
173
|
status: Integer,
|
|
138
174
|
retries: Integer,
|
|
139
175
|
durations: T::Hash[Symbol, Integer],
|
|
176
|
+
sample_rate: Float,
|
|
140
177
|
server_total_ms: T.nilable(Numeric),
|
|
141
178
|
error: T.nilable(String),
|
|
142
|
-
reused: T.nilable(T::Boolean)
|
|
179
|
+
reused: T.nilable(T::Boolean),
|
|
180
|
+
request_id: T.nilable(String)
|
|
143
181
|
).void
|
|
144
182
|
end
|
|
145
183
|
def record(
|
|
@@ -148,9 +186,11 @@ module Turbopuffer
|
|
|
148
186
|
status:,
|
|
149
187
|
retries:,
|
|
150
188
|
durations:,
|
|
189
|
+
sample_rate:,
|
|
151
190
|
server_total_ms: nil,
|
|
152
191
|
error: nil,
|
|
153
|
-
reused: nil
|
|
192
|
+
reused: nil,
|
|
193
|
+
request_id: nil
|
|
154
194
|
)
|
|
155
195
|
end
|
|
156
196
|
|