redis 3.3.5 → 5.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +290 -2
- data/README.md +146 -146
- data/lib/redis/client.rb +79 -541
- data/lib/redis/commands/bitmaps.rb +66 -0
- data/lib/redis/commands/cluster.rb +28 -0
- data/lib/redis/commands/connection.rb +53 -0
- data/lib/redis/commands/geo.rb +84 -0
- data/lib/redis/commands/hashes.rb +254 -0
- data/lib/redis/commands/hyper_log_log.rb +37 -0
- data/lib/redis/commands/keys.rb +437 -0
- data/lib/redis/commands/lists.rb +339 -0
- data/lib/redis/commands/pubsub.rb +54 -0
- data/lib/redis/commands/scripting.rb +114 -0
- data/lib/redis/commands/server.rb +188 -0
- data/lib/redis/commands/sets.rb +214 -0
- data/lib/redis/commands/sorted_sets.rb +884 -0
- data/lib/redis/commands/streams.rb +402 -0
- data/lib/redis/commands/strings.rb +314 -0
- data/lib/redis/commands/transactions.rb +115 -0
- data/lib/redis/commands.rb +237 -0
- data/lib/redis/distributed.rb +328 -108
- data/lib/redis/errors.rb +23 -1
- data/lib/redis/hash_ring.rb +36 -79
- data/lib/redis/pipeline.rb +69 -83
- data/lib/redis/subscribe.rb +26 -19
- data/lib/redis/version.rb +3 -1
- data/lib/redis.rb +115 -2695
- metadata +38 -218
- data/.gitignore +0 -16
- data/.travis/Gemfile +0 -11
- data/.travis.yml +0 -89
- data/.yardopts +0 -3
- data/Gemfile +0 -4
- data/Rakefile +0 -87
- data/benchmarking/logging.rb +0 -71
- data/benchmarking/pipeline.rb +0 -51
- data/benchmarking/speed.rb +0 -21
- data/benchmarking/suite.rb +0 -24
- data/benchmarking/worker.rb +0 -71
- data/examples/basic.rb +0 -15
- data/examples/consistency.rb +0 -114
- data/examples/dist_redis.rb +0 -43
- data/examples/incr-decr.rb +0 -17
- data/examples/list.rb +0 -26
- data/examples/pubsub.rb +0 -37
- data/examples/sentinel/sentinel.conf +0 -9
- data/examples/sentinel/start +0 -49
- data/examples/sentinel.rb +0 -41
- data/examples/sets.rb +0 -36
- data/examples/unicorn/config.ru +0 -3
- data/examples/unicorn/unicorn.rb +0 -20
- data/lib/redis/connection/command_helper.rb +0 -44
- data/lib/redis/connection/hiredis.rb +0 -66
- data/lib/redis/connection/registry.rb +0 -12
- data/lib/redis/connection/ruby.rb +0 -429
- data/lib/redis/connection/synchrony.rb +0 -133
- data/lib/redis/connection.rb +0 -9
- data/redis.gemspec +0 -44
- data/test/bitpos_test.rb +0 -69
- data/test/blocking_commands_test.rb +0 -42
- data/test/client_test.rb +0 -59
- data/test/command_map_test.rb +0 -30
- data/test/commands_on_hashes_test.rb +0 -21
- data/test/commands_on_hyper_log_log_test.rb +0 -21
- data/test/commands_on_lists_test.rb +0 -20
- data/test/commands_on_sets_test.rb +0 -77
- data/test/commands_on_sorted_sets_test.rb +0 -137
- data/test/commands_on_strings_test.rb +0 -101
- data/test/commands_on_value_types_test.rb +0 -133
- data/test/connection_handling_test.rb +0 -277
- data/test/connection_test.rb +0 -57
- data/test/db/.gitkeep +0 -0
- data/test/distributed_blocking_commands_test.rb +0 -46
- data/test/distributed_commands_on_hashes_test.rb +0 -10
- data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
- data/test/distributed_commands_on_lists_test.rb +0 -22
- data/test/distributed_commands_on_sets_test.rb +0 -83
- data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
- data/test/distributed_commands_on_strings_test.rb +0 -59
- data/test/distributed_commands_on_value_types_test.rb +0 -95
- data/test/distributed_commands_requiring_clustering_test.rb +0 -164
- data/test/distributed_connection_handling_test.rb +0 -23
- data/test/distributed_internals_test.rb +0 -79
- data/test/distributed_key_tags_test.rb +0 -52
- data/test/distributed_persistence_control_commands_test.rb +0 -26
- data/test/distributed_publish_subscribe_test.rb +0 -92
- data/test/distributed_remote_server_control_commands_test.rb +0 -66
- data/test/distributed_scripting_test.rb +0 -102
- data/test/distributed_sorting_test.rb +0 -20
- data/test/distributed_test.rb +0 -58
- data/test/distributed_transactions_test.rb +0 -32
- data/test/encoding_test.rb +0 -18
- data/test/error_replies_test.rb +0 -59
- data/test/fork_safety_test.rb +0 -65
- data/test/helper.rb +0 -232
- data/test/helper_test.rb +0 -24
- data/test/internals_test.rb +0 -417
- data/test/lint/blocking_commands.rb +0 -150
- data/test/lint/hashes.rb +0 -162
- data/test/lint/hyper_log_log.rb +0 -60
- data/test/lint/lists.rb +0 -143
- data/test/lint/sets.rb +0 -140
- data/test/lint/sorted_sets.rb +0 -316
- data/test/lint/strings.rb +0 -260
- data/test/lint/value_types.rb +0 -122
- data/test/persistence_control_commands_test.rb +0 -26
- data/test/pipelining_commands_test.rb +0 -242
- data/test/publish_subscribe_test.rb +0 -282
- data/test/remote_server_control_commands_test.rb +0 -118
- data/test/scanning_test.rb +0 -413
- data/test/scripting_test.rb +0 -78
- data/test/sentinel_command_test.rb +0 -80
- data/test/sentinel_test.rb +0 -255
- data/test/sorting_test.rb +0 -59
- data/test/ssl_test.rb +0 -73
- data/test/support/connection/hiredis.rb +0 -1
- data/test/support/connection/ruby.rb +0 -1
- data/test/support/connection/synchrony.rb +0 -17
- data/test/support/redis_mock.rb +0 -130
- data/test/support/ssl/gen_certs.sh +0 -31
- data/test/support/ssl/trusted-ca.crt +0 -25
- data/test/support/ssl/trusted-ca.key +0 -27
- data/test/support/ssl/trusted-cert.crt +0 -81
- data/test/support/ssl/trusted-cert.key +0 -28
- data/test/support/ssl/untrusted-ca.crt +0 -26
- data/test/support/ssl/untrusted-ca.key +0 -27
- data/test/support/ssl/untrusted-cert.crt +0 -82
- data/test/support/ssl/untrusted-cert.key +0 -28
- data/test/support/wire/synchrony.rb +0 -24
- data/test/support/wire/thread.rb +0 -5
- data/test/synchrony_driver.rb +0 -88
- data/test/test.conf.erb +0 -9
- data/test/thread_safety_test.rb +0 -62
- data/test/transactions_test.rb +0 -264
- data/test/unknown_commands_test.rb +0 -14
- data/test/url_param_test.rb +0 -138
@@ -0,0 +1,402 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Redis
|
4
|
+
module Commands
|
5
|
+
module Streams
|
6
|
+
# Returns the stream information each subcommand.
|
7
|
+
#
|
8
|
+
# @example stream
|
9
|
+
# redis.xinfo(:stream, 'mystream')
|
10
|
+
# @example groups
|
11
|
+
# redis.xinfo(:groups, 'mystream')
|
12
|
+
# @example consumers
|
13
|
+
# redis.xinfo(:consumers, 'mystream', 'mygroup')
|
14
|
+
#
|
15
|
+
# @param subcommand [String] e.g. `stream` `groups` `consumers`
|
16
|
+
# @param key [String] the stream key
|
17
|
+
# @param group [String] the consumer group name, required if subcommand is `consumers`
|
18
|
+
#
|
19
|
+
# @return [Hash] information of the stream if subcommand is `stream`
|
20
|
+
# @return [Array<Hash>] information of the consumer groups if subcommand is `groups`
|
21
|
+
# @return [Array<Hash>] information of the consumers if subcommand is `consumers`
|
22
|
+
def xinfo(subcommand, key, group = nil)
|
23
|
+
args = [:xinfo, subcommand, key, group].compact
|
24
|
+
block = case subcommand.to_s.downcase
|
25
|
+
when 'stream' then Hashify
|
26
|
+
when 'groups', 'consumers' then proc { |r| r.map(&Hashify) }
|
27
|
+
end
|
28
|
+
|
29
|
+
send_command(args, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Add new entry to the stream.
|
33
|
+
#
|
34
|
+
# @example Without options
|
35
|
+
# redis.xadd('mystream', f1: 'v1', f2: 'v2')
|
36
|
+
# @example With options
|
37
|
+
# redis.xadd('mystream', { f1: 'v1', f2: 'v2' }, id: '0-0', maxlen: 1000, approximate: true, nomkstream: true)
|
38
|
+
#
|
39
|
+
# @param key [String] the stream key
|
40
|
+
# @param entry [Hash] one or multiple field-value pairs
|
41
|
+
# @param opts [Hash] several options for `XADD` command
|
42
|
+
#
|
43
|
+
# @option opts [String] :id the entry id, default value is `*`, it means auto generation
|
44
|
+
# @option opts [Integer] :maxlen max length of entries
|
45
|
+
# @option opts [Boolean] :approximate whether to add `~` modifier of maxlen or not
|
46
|
+
# @option opts [Boolean] :nomkstream whether to add NOMKSTREAM, default is not to add
|
47
|
+
#
|
48
|
+
# @return [String] the entry id
|
49
|
+
def xadd(key, entry, approximate: nil, maxlen: nil, nomkstream: nil, id: '*')
|
50
|
+
args = [:xadd, key]
|
51
|
+
args << 'NOMKSTREAM' if nomkstream
|
52
|
+
if maxlen
|
53
|
+
args << "MAXLEN"
|
54
|
+
args << "~" if approximate
|
55
|
+
args << maxlen
|
56
|
+
end
|
57
|
+
args << id
|
58
|
+
args.concat(entry.flatten)
|
59
|
+
send_command(args)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Trims older entries of the stream if needed.
|
63
|
+
#
|
64
|
+
# @example Without options
|
65
|
+
# redis.xtrim('mystream', 1000)
|
66
|
+
# @example With options
|
67
|
+
# redis.xtrim('mystream', 1000, approximate: true)
|
68
|
+
# @example With strategy
|
69
|
+
# redis.xtrim('mystream', '1-0', strategy: 'MINID')
|
70
|
+
#
|
71
|
+
# @overload xtrim(key, maxlen, strategy: 'MAXLEN', approximate: true)
|
72
|
+
# @param key [String] the stream key
|
73
|
+
# @param maxlen [Integer] max length of entries
|
74
|
+
# @param strategy [String] the limit strategy, must be MAXLEN
|
75
|
+
# @param approximate [Boolean] whether to add `~` modifier of maxlen or not
|
76
|
+
# @param limit [Integer] maximum count of entries to be evicted
|
77
|
+
# @overload xtrim(key, minid, strategy: 'MINID', approximate: true)
|
78
|
+
# @param key [String] the stream key
|
79
|
+
# @param minid [String] minimum id of entries
|
80
|
+
# @param strategy [String] the limit strategy, must be MINID
|
81
|
+
# @param approximate [Boolean] whether to add `~` modifier of minid or not
|
82
|
+
# @param limit [Integer] maximum count of entries to be evicted
|
83
|
+
#
|
84
|
+
# @return [Integer] the number of entries actually deleted
|
85
|
+
def xtrim(key, len_or_id, strategy: 'MAXLEN', approximate: false, limit: nil)
|
86
|
+
strategy = strategy.to_s.upcase
|
87
|
+
|
88
|
+
args = [:xtrim, key, strategy]
|
89
|
+
args << '~' if approximate
|
90
|
+
args << len_or_id
|
91
|
+
args.concat(['LIMIT', limit]) if limit
|
92
|
+
send_command(args)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Delete entries by entry ids.
|
96
|
+
#
|
97
|
+
# @example With splatted entry ids
|
98
|
+
# redis.xdel('mystream', '0-1', '0-2')
|
99
|
+
# @example With arrayed entry ids
|
100
|
+
# redis.xdel('mystream', ['0-1', '0-2'])
|
101
|
+
#
|
102
|
+
# @param key [String] the stream key
|
103
|
+
# @param ids [Array<String>] one or multiple entry ids
|
104
|
+
#
|
105
|
+
# @return [Integer] the number of entries actually deleted
|
106
|
+
def xdel(key, *ids)
|
107
|
+
args = [:xdel, key].concat(ids.flatten)
|
108
|
+
send_command(args)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Fetches entries of the stream in ascending order.
|
112
|
+
#
|
113
|
+
# @example Without options
|
114
|
+
# redis.xrange('mystream')
|
115
|
+
# @example With a specific start
|
116
|
+
# redis.xrange('mystream', '0-1')
|
117
|
+
# @example With a specific start and end
|
118
|
+
# redis.xrange('mystream', '0-1', '0-3')
|
119
|
+
# @example With count options
|
120
|
+
# redis.xrange('mystream', count: 10)
|
121
|
+
#
|
122
|
+
# @param key [String] the stream key
|
123
|
+
# @param start [String] first entry id of range, default value is `-`
|
124
|
+
# @param end [String] last entry id of range, default value is `+`
|
125
|
+
# @param count [Integer] the number of entries as limit
|
126
|
+
#
|
127
|
+
# @return [Array<Array<String, Hash>>] the ids and entries pairs
|
128
|
+
def xrange(key, start = '-', range_end = '+', count: nil)
|
129
|
+
args = [:xrange, key, start, range_end]
|
130
|
+
args.concat(['COUNT', count]) if count
|
131
|
+
send_command(args, &HashifyStreamEntries)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Fetches entries of the stream in descending order.
|
135
|
+
#
|
136
|
+
# @example Without options
|
137
|
+
# redis.xrevrange('mystream')
|
138
|
+
# @example With a specific end
|
139
|
+
# redis.xrevrange('mystream', '0-3')
|
140
|
+
# @example With a specific end and start
|
141
|
+
# redis.xrevrange('mystream', '0-3', '0-1')
|
142
|
+
# @example With count options
|
143
|
+
# redis.xrevrange('mystream', count: 10)
|
144
|
+
#
|
145
|
+
# @param key [String] the stream key
|
146
|
+
# @param end [String] first entry id of range, default value is `+`
|
147
|
+
# @param start [String] last entry id of range, default value is `-`
|
148
|
+
# @params count [Integer] the number of entries as limit
|
149
|
+
#
|
150
|
+
# @return [Array<Array<String, Hash>>] the ids and entries pairs
|
151
|
+
def xrevrange(key, range_end = '+', start = '-', count: nil)
|
152
|
+
args = [:xrevrange, key, range_end, start]
|
153
|
+
args.concat(['COUNT', count]) if count
|
154
|
+
send_command(args, &HashifyStreamEntries)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Returns the number of entries inside a stream.
|
158
|
+
#
|
159
|
+
# @example With key
|
160
|
+
# redis.xlen('mystream')
|
161
|
+
#
|
162
|
+
# @param key [String] the stream key
|
163
|
+
#
|
164
|
+
# @return [Integer] the number of entries
|
165
|
+
def xlen(key)
|
166
|
+
send_command([:xlen, key])
|
167
|
+
end
|
168
|
+
|
169
|
+
# Fetches entries from one or multiple streams. Optionally blocking.
|
170
|
+
#
|
171
|
+
# @example With a key
|
172
|
+
# redis.xread('mystream', '0-0')
|
173
|
+
# @example With multiple keys
|
174
|
+
# redis.xread(%w[mystream1 mystream2], %w[0-0 0-0])
|
175
|
+
# @example With count option
|
176
|
+
# redis.xread('mystream', '0-0', count: 2)
|
177
|
+
# @example With block option
|
178
|
+
# redis.xread('mystream', '$', block: 1000)
|
179
|
+
#
|
180
|
+
# @param keys [Array<String>] one or multiple stream keys
|
181
|
+
# @param ids [Array<String>] one or multiple entry ids
|
182
|
+
# @param count [Integer] the number of entries as limit per stream
|
183
|
+
# @param block [Integer] the number of milliseconds as blocking timeout
|
184
|
+
#
|
185
|
+
# @return [Hash{String => Hash{String => Hash}}] the entries
|
186
|
+
def xread(keys, ids, count: nil, block: nil)
|
187
|
+
args = [:xread]
|
188
|
+
args << 'COUNT' << count if count
|
189
|
+
args << 'BLOCK' << block.to_i if block
|
190
|
+
_xread(args, keys, ids, block)
|
191
|
+
end
|
192
|
+
|
193
|
+
# Manages the consumer group of the stream.
|
194
|
+
#
|
195
|
+
# @example With `create` subcommand
|
196
|
+
# redis.xgroup(:create, 'mystream', 'mygroup', '$')
|
197
|
+
# @example With `setid` subcommand
|
198
|
+
# redis.xgroup(:setid, 'mystream', 'mygroup', '$')
|
199
|
+
# @example With `destroy` subcommand
|
200
|
+
# redis.xgroup(:destroy, 'mystream', 'mygroup')
|
201
|
+
# @example With `delconsumer` subcommand
|
202
|
+
# redis.xgroup(:delconsumer, 'mystream', 'mygroup', 'consumer1')
|
203
|
+
#
|
204
|
+
# @param subcommand [String] `create` `setid` `destroy` `delconsumer`
|
205
|
+
# @param key [String] the stream key
|
206
|
+
# @param group [String] the consumer group name
|
207
|
+
# @param id_or_consumer [String]
|
208
|
+
# * the entry id or `$`, required if subcommand is `create` or `setid`
|
209
|
+
# * the consumer name, required if subcommand is `delconsumer`
|
210
|
+
# @param mkstream [Boolean] whether to create an empty stream automatically or not
|
211
|
+
#
|
212
|
+
# @return [String] `OK` if subcommand is `create` or `setid`
|
213
|
+
# @return [Integer] effected count if subcommand is `destroy` or `delconsumer`
|
214
|
+
def xgroup(subcommand, key, group, id_or_consumer = nil, mkstream: false)
|
215
|
+
args = [:xgroup, subcommand, key, group, id_or_consumer, (mkstream ? 'MKSTREAM' : nil)].compact
|
216
|
+
send_command(args)
|
217
|
+
end
|
218
|
+
|
219
|
+
# Fetches a subset of the entries from one or multiple streams related with the consumer group.
|
220
|
+
# Optionally blocking.
|
221
|
+
#
|
222
|
+
# @example With a key
|
223
|
+
# redis.xreadgroup('mygroup', 'consumer1', 'mystream', '>')
|
224
|
+
# @example With multiple keys
|
225
|
+
# redis.xreadgroup('mygroup', 'consumer1', %w[mystream1 mystream2], %w[> >])
|
226
|
+
# @example With count option
|
227
|
+
# redis.xreadgroup('mygroup', 'consumer1', 'mystream', '>', count: 2)
|
228
|
+
# @example With block option
|
229
|
+
# redis.xreadgroup('mygroup', 'consumer1', 'mystream', '>', block: 1000)
|
230
|
+
# @example With noack option
|
231
|
+
# redis.xreadgroup('mygroup', 'consumer1', 'mystream', '>', noack: true)
|
232
|
+
#
|
233
|
+
# @param group [String] the consumer group name
|
234
|
+
# @param consumer [String] the consumer name
|
235
|
+
# @param keys [Array<String>] one or multiple stream keys
|
236
|
+
# @param ids [Array<String>] one or multiple entry ids
|
237
|
+
# @param opts [Hash] several options for `XREADGROUP` command
|
238
|
+
#
|
239
|
+
# @option opts [Integer] :count the number of entries as limit
|
240
|
+
# @option opts [Integer] :block the number of milliseconds as blocking timeout
|
241
|
+
# @option opts [Boolean] :noack whether message loss is acceptable or not
|
242
|
+
#
|
243
|
+
# @return [Hash{String => Hash{String => Hash}}] the entries
|
244
|
+
def xreadgroup(group, consumer, keys, ids, count: nil, block: nil, noack: nil)
|
245
|
+
args = [:xreadgroup, 'GROUP', group, consumer]
|
246
|
+
args << 'COUNT' << count if count
|
247
|
+
args << 'BLOCK' << block.to_i if block
|
248
|
+
args << 'NOACK' if noack
|
249
|
+
_xread(args, keys, ids, block)
|
250
|
+
end
|
251
|
+
|
252
|
+
# Removes one or multiple entries from the pending entries list of a stream consumer group.
|
253
|
+
#
|
254
|
+
# @example With a entry id
|
255
|
+
# redis.xack('mystream', 'mygroup', '1526569495631-0')
|
256
|
+
# @example With splatted entry ids
|
257
|
+
# redis.xack('mystream', 'mygroup', '0-1', '0-2')
|
258
|
+
# @example With arrayed entry ids
|
259
|
+
# redis.xack('mystream', 'mygroup', %w[0-1 0-2])
|
260
|
+
#
|
261
|
+
# @param key [String] the stream key
|
262
|
+
# @param group [String] the consumer group name
|
263
|
+
# @param ids [Array<String>] one or multiple entry ids
|
264
|
+
#
|
265
|
+
# @return [Integer] the number of entries successfully acknowledged
|
266
|
+
def xack(key, group, *ids)
|
267
|
+
args = [:xack, key, group].concat(ids.flatten)
|
268
|
+
send_command(args)
|
269
|
+
end
|
270
|
+
|
271
|
+
# Changes the ownership of a pending entry
|
272
|
+
#
|
273
|
+
# @example With splatted entry ids
|
274
|
+
# redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, '0-1', '0-2')
|
275
|
+
# @example With arrayed entry ids
|
276
|
+
# redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2])
|
277
|
+
# @example With idle option
|
278
|
+
# redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], idle: 1000)
|
279
|
+
# @example With time option
|
280
|
+
# redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], time: 1542866959000)
|
281
|
+
# @example With retrycount option
|
282
|
+
# redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], retrycount: 10)
|
283
|
+
# @example With force option
|
284
|
+
# redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], force: true)
|
285
|
+
# @example With justid option
|
286
|
+
# redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], justid: true)
|
287
|
+
#
|
288
|
+
# @param key [String] the stream key
|
289
|
+
# @param group [String] the consumer group name
|
290
|
+
# @param consumer [String] the consumer name
|
291
|
+
# @param min_idle_time [Integer] the number of milliseconds
|
292
|
+
# @param ids [Array<String>] one or multiple entry ids
|
293
|
+
# @param opts [Hash] several options for `XCLAIM` command
|
294
|
+
#
|
295
|
+
# @option opts [Integer] :idle the number of milliseconds as last time it was delivered of the entry
|
296
|
+
# @option opts [Integer] :time the number of milliseconds as a specific Unix Epoch time
|
297
|
+
# @option opts [Integer] :retrycount the number of retry counter
|
298
|
+
# @option opts [Boolean] :force whether to create the pending entry to the pending entries list or not
|
299
|
+
# @option opts [Boolean] :justid whether to fetch just an array of entry ids or not
|
300
|
+
#
|
301
|
+
# @return [Hash{String => Hash}] the entries successfully claimed
|
302
|
+
# @return [Array<String>] the entry ids successfully claimed if justid option is `true`
|
303
|
+
def xclaim(key, group, consumer, min_idle_time, *ids, **opts)
|
304
|
+
args = [:xclaim, key, group, consumer, min_idle_time].concat(ids.flatten)
|
305
|
+
args.concat(['IDLE', opts[:idle].to_i]) if opts[:idle]
|
306
|
+
args.concat(['TIME', opts[:time].to_i]) if opts[:time]
|
307
|
+
args.concat(['RETRYCOUNT', opts[:retrycount]]) if opts[:retrycount]
|
308
|
+
args << 'FORCE' if opts[:force]
|
309
|
+
args << 'JUSTID' if opts[:justid]
|
310
|
+
blk = opts[:justid] ? Noop : HashifyStreamEntries
|
311
|
+
send_command(args, &blk)
|
312
|
+
end
|
313
|
+
|
314
|
+
# Transfers ownership of pending stream entries that match the specified criteria.
|
315
|
+
#
|
316
|
+
# @example Claim next pending message stuck > 5 minutes and mark as retry
|
317
|
+
# redis.xautoclaim('mystream', 'mygroup', 'consumer1', 3600000, '0-0')
|
318
|
+
# @example Claim 50 next pending messages stuck > 5 minutes and mark as retry
|
319
|
+
# redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, '0-0', count: 50)
|
320
|
+
# @example Claim next pending message stuck > 5 minutes and don't mark as retry
|
321
|
+
# redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, '0-0', justid: true)
|
322
|
+
# @example Claim next pending message after this id stuck > 5 minutes and mark as retry
|
323
|
+
# redis.xautoclaim('mystream', 'mygroup', 'consumer1', 3600000, '1641321233-0')
|
324
|
+
#
|
325
|
+
# @param key [String] the stream key
|
326
|
+
# @param group [String] the consumer group name
|
327
|
+
# @param consumer [String] the consumer name
|
328
|
+
# @param min_idle_time [Integer] the number of milliseconds
|
329
|
+
# @param start [String] entry id to start scanning from or 0-0 for everything
|
330
|
+
# @param count [Integer] number of messages to claim (default 1)
|
331
|
+
# @param justid [Boolean] whether to fetch just an array of entry ids or not.
|
332
|
+
# Does not increment retry count when true
|
333
|
+
#
|
334
|
+
# @return [Hash{String => Hash}] the entries successfully claimed
|
335
|
+
# @return [Array<String>] the entry ids successfully claimed if justid option is `true`
|
336
|
+
def xautoclaim(key, group, consumer, min_idle_time, start, count: nil, justid: false)
|
337
|
+
args = [:xautoclaim, key, group, consumer, min_idle_time, start]
|
338
|
+
if count
|
339
|
+
args << 'COUNT' << count.to_s
|
340
|
+
end
|
341
|
+
args << 'JUSTID' if justid
|
342
|
+
blk = justid ? HashifyStreamAutoclaimJustId : HashifyStreamAutoclaim
|
343
|
+
send_command(args, &blk)
|
344
|
+
end
|
345
|
+
|
346
|
+
# Fetches not acknowledging pending entries
|
347
|
+
#
|
348
|
+
# @example With key and group
|
349
|
+
# redis.xpending('mystream', 'mygroup')
|
350
|
+
# @example With range options
|
351
|
+
# redis.xpending('mystream', 'mygroup', '-', '+', 10)
|
352
|
+
# @example With range and idle time options
|
353
|
+
# redis.xpending('mystream', 'mygroup', '-', '+', 10, idle: 9000)
|
354
|
+
# @example With range and consumer options
|
355
|
+
# redis.xpending('mystream', 'mygroup', '-', '+', 10, 'consumer1')
|
356
|
+
#
|
357
|
+
# @param key [String] the stream key
|
358
|
+
# @param group [String] the consumer group name
|
359
|
+
# @param start [String] start first entry id of range
|
360
|
+
# @param end [String] end last entry id of range
|
361
|
+
# @param count [Integer] count the number of entries as limit
|
362
|
+
# @param consumer [String] the consumer name
|
363
|
+
#
|
364
|
+
# @option opts [Integer] :idle pending message minimum idle time in milliseconds
|
365
|
+
#
|
366
|
+
# @return [Hash] the summary of pending entries
|
367
|
+
# @return [Array<Hash>] the pending entries details if options were specified
|
368
|
+
def xpending(key, group, *args, idle: nil)
|
369
|
+
command_args = [:xpending, key, group]
|
370
|
+
command_args << 'IDLE' << Integer(idle) if idle
|
371
|
+
case args.size
|
372
|
+
when 0, 3, 4
|
373
|
+
command_args.concat(args)
|
374
|
+
else
|
375
|
+
raise ArgumentError, "wrong number of arguments (given #{args.size + 2}, expected 2, 5 or 6)"
|
376
|
+
end
|
377
|
+
|
378
|
+
summary_needed = args.empty?
|
379
|
+
blk = summary_needed ? HashifyStreamPendings : HashifyStreamPendingDetails
|
380
|
+
send_command(command_args, &blk)
|
381
|
+
end
|
382
|
+
|
383
|
+
private
|
384
|
+
|
385
|
+
def _xread(args, keys, ids, blocking_timeout_msec)
|
386
|
+
keys = keys.is_a?(Array) ? keys : [keys]
|
387
|
+
ids = ids.is_a?(Array) ? ids : [ids]
|
388
|
+
args << 'STREAMS'
|
389
|
+
args.concat(keys)
|
390
|
+
args.concat(ids)
|
391
|
+
|
392
|
+
if blocking_timeout_msec.nil?
|
393
|
+
send_command(args, &HashifyStreams)
|
394
|
+
elsif blocking_timeout_msec.to_f.zero?
|
395
|
+
send_blocking_command(args, 0, &HashifyStreams)
|
396
|
+
else
|
397
|
+
send_blocking_command(args, blocking_timeout_msec.to_f / 1_000, &HashifyStreams)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|