redis_batch 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d205bf5fdc9bfb375f6666e1017413f9bb2ecbdb8d696912cb9b658f3910ffed
4
+ data.tar.gz: 8b7521a379d318634fa2a6c8e5cf42398af416414b2fec89e1a0f9bd40e18087
5
+ SHA512:
6
+ metadata.gz: 357499ea517316f46c7b80dc43d14269656141f345afb8db1cc56a8dab790bcf6fbef8b95121b7480dbdd6fb6162c572182830550ba9637c191d13a99e5ec82d
7
+ data.tar.gz: 685246ee83f7a97946efebf7193477cd6aee5c75ace9b92e5f5bb75cf134a4d36968e11519bd3458b8da4b65c622701193e3b622c25615fd19bfb17c747646a4
@@ -0,0 +1,31 @@
1
+ require './lib/redis_batch/configurable'
2
+ require 'singleton'
3
+
4
+ module RedisBatch
5
+ class Client
6
+ include Singleton
7
+ extend RedisBatch::Configurable
8
+
9
+ def initialize(configuration)
10
+ if configuration.redis.respond_to?(:with)
11
+ @connection_pool = configuration.redis
12
+ else
13
+ @connection_pool = ConnectionPool.new(size: 1, timeout: 1) {
14
+ configuration.redis
15
+ }
16
+ end
17
+ end
18
+
19
+ def ping
20
+ @connection_pool.with(&:ping)
21
+ end
22
+
23
+ def with(...)
24
+ @connection_pool.with(...)
25
+ end
26
+
27
+ def pool
28
+ @connection_pool
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,38 @@
1
+ require 'ostruct'
2
+
3
+ module RedisBatch
4
+ # Add configuration to a Singleton
5
+ module Configurable
6
+ class Configuration
7
+ def initialize(redis:)
8
+ @redis = redis
9
+ end
10
+
11
+ attr_accessor :redis
12
+ end
13
+
14
+ def configure
15
+ yield configuration
16
+ end
17
+
18
+ def reset_configuration
19
+ @configuration = nil
20
+ end
21
+
22
+ def configuration
23
+ @configuration ||= Configuration.new(**default_configuration)
24
+ end
25
+
26
+ private
27
+
28
+ def new
29
+ super(configuration)
30
+ end
31
+
32
+ def default_configuration
33
+ {
34
+ redis: Redis.new
35
+ }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,60 @@
1
+ module RedisBatch
2
+ class Queue
3
+ def initialize(namespace = self.class.name)
4
+ @namespace = namespace
5
+ @client = Client.instance
6
+ end
7
+
8
+ def add(*items)
9
+ @client.with { |redis| redis.rpush(queue_key, items) }
10
+ end
11
+
12
+ def count
13
+ @client.with { |redis| redis.llen(queue_key) }
14
+ end
15
+
16
+ def self.processing?
17
+ @client.with { |redis| redis.keys("#{@namespace}_takeout_*").any? }
18
+ end
19
+
20
+ def abort_all
21
+ return unless processing?
22
+ keys = @client.with { |redis| redis.keys("#{@namespace}_takeout_*") }
23
+ client.with do |redis|
24
+ keys.each do |key|
25
+ abort_processing(key, redis)
26
+ end
27
+ end
28
+ end
29
+
30
+ def take(count: 1, client: @client)
31
+ values = client.with do |redis|
32
+ redis.multi do |transaction|
33
+ count.times.map { transaction.lmove(queue_key, take_key, :left, :right) }
34
+ end
35
+ end
36
+ yield values
37
+ client.with { |redis| redis.del(take_key) }
38
+ rescue => error
39
+ client.with { |redis| abort_processing(take_key, redis) }
40
+ raise error
41
+ end
42
+
43
+ private
44
+
45
+ def abort_processing(key, redis)
46
+ recover_count = redis.llen(key)
47
+ redis.multi do |transaction|
48
+ recover_count.times { transaction.lmove(take_key, queue_key, :right, :left) }
49
+ end
50
+ end
51
+
52
+ def queue_key
53
+ @queue_key ||= "RedisBatch/#{@namespace}_queue"
54
+ end
55
+
56
+ def take_key
57
+ @take_key ||= "RedisBatch/#{@namespace}_takeout_#{Thread.current.native_thread_id}"
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,16 @@
1
+ require 'redis'
2
+ require './lib/redis_batch/configurable'
3
+ require './lib/redis_batch/client'
4
+ require './lib/redis_batch/queue'
5
+
6
+ module RedisBatch
7
+ Error = Class.new(StandardError)
8
+
9
+ def self.configure(&block)
10
+ Client.configure { |config| block.call(config) }
11
+ end
12
+
13
+ def self.configuration
14
+ Client.configuration
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redis_batch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Christian Avemark
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-02-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: redis
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.8
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.0.8
27
+ description: A minimal gem for safely pushing data onto redis and taking it back out
28
+ in batches of any size. Designed to work well in a multi host/thread environment.
29
+ email:
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/redis_batch.rb
35
+ - lib/redis_batch/client.rb
36
+ - lib/redis_batch/configurable.rb
37
+ - lib/redis_batch/queue.rb
38
+ homepage: https://github.com/avemark/redis_batch_rb
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 3.3.0
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubygems_version: 3.5.5
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: Redis based work queue.
61
+ test_files: []