bigrails-redis 0.3.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff3e8766a94faf3c2465bd623e81753dfff98b37a309147561e891aa928d8007
4
- data.tar.gz: 667363a9f9648ff88c42b3f78306d84fc56e1cdeba0875de33c9d270a237de2f
3
+ metadata.gz: 8a2638608a5a80ec36cf93efccc3b761d9d1b976b0529dc407901f42c4269f7d
4
+ data.tar.gz: 677a8e2fbd028515253f3fac94a29b0cde604053cda39521fcc1efe6354e0020
5
5
  SHA512:
6
- metadata.gz: 1f2514a61324b4900b2dc412e44d816c6772b9b9ea747e69ee1cfae20c9cf20a6f6468683a21125fc93f178522573ec6fef1daeb94d83ee8a9773dee3ac6310a
7
- data.tar.gz: 684f353daaba4c3cff2d79d3bc9a2db97df582212b6b75949be6893c2e5220d4e3653036180a423454d803351b1280a20213cb7153c178ae7c85536c97e1f715
6
+ metadata.gz: 41ea96f64d5f57dcb9f058420e007dc2e84a106ea9d7232402483c16105f3b42a6f96c33f4a2514c20cf961ee44a1b8bbad8790124c9c93ffa94a042e5d6137e
7
+ data.tar.gz: 561b0610a79041b670f4b11036ea0ee0c1fbad843580726f1e694f3c9695b5b93df6b02cf59cd222060cdf152dad7e0ff9300e8372ec568211e4fc829c99f2e7
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # BigRails::Redis [![Ruby](https://github.com/BigRails/bigrails-redis/actions/workflows/main.yml/badge.svg)](https://github.com/BigRails/bigrails-redis/actions/workflows/main.yml)
2
2
 
3
- A simple Redis connection manager for Rails applications with distributed and [ConnectionPool](https://github.com/mperham/connection_pool) support.
3
+ A simple Redis connection manager for Rails applications with the need to manage multiple redis connections. It supports distributed and [ConnectionPool](https://github.com/mperham/connection_pool) out of the box.
4
4
 
5
5
  ## Installation
6
6
 
@@ -18,9 +18,15 @@ Create a redis configuration file:
18
18
 
19
19
  The configuration file (`config/redis.rb`) is just a plain Ruby file that will be evaluated when a connection is requested. Use the `connection` DSL method to declare your connections. The method will yield a block and you're expected to return a configuration hash.
20
20
 
21
- A configuration hash, by default, is passed to `ActiveSupport::Cache::RedisCacheStore.build_redis(...)`. This is a Rails supplied helper which allows for more options than demostrated above. You'll want to [check out its source](https://github.com/rails/rails/blob/main/activesupport/lib/active_support/cache/redis_cache_store.rb#L77-L100) to get a better idea of what it supports.
21
+ The configuration hash is passed to the default `Builder`. You can customize the builder with your own object/proc that responds to `#call`.
22
22
 
23
23
  ```ruby
24
+ # Change the default builder.
25
+ Rails.application.redis.builder = ->(options) {
26
+ # options is the hash returned from the connection block.
27
+ Redis.new(...)
28
+ }
29
+
24
30
  # Simple hardcoded example.
25
31
  connection(:default) do
26
32
  {
@@ -89,14 +95,22 @@ If you request a wrapped connection for a non-pooled connection, it'll just retu
89
95
 
90
96
  ### Verifying Connections
91
97
 
92
- This library also allows you to verify connections on demand. If you want, perform the verification in a startup health check to make sure all your connections are valid. It will perform a simple [`PING` command](https://redis.io/commands/PING). An error will be raised if the connection bad.
98
+ This library also allows you to verify connections on demand. If you want, perform the verification in a startup health check to make sure all your connections are valid. It will perform a simple [`PING` command](https://redis.io/commands/PING) and clsoe the connection if it was originally closed. This is to help reduce the number of connections you actually need open. An error will be raised if the connection is bad.
93
99
 
94
100
  ```ruby
95
101
  # Verify all connections:
96
102
  Rails.application.redis.verify!
97
103
 
98
- # Verify a single connection:
99
- Rails.application.redis.verify!(:foobar)
104
+ # Verify specific connections:
105
+ Rails.application.redis.verify!(:foobar, :sidekiq)
106
+ ```
107
+
108
+ ### Disconnect Connections
109
+
110
+ You can disconnect all connections with a single call. This is useful for "before fork" hooks.
111
+
112
+ ```ruby
113
+ Rails.application.redis.disconnect
100
114
  ```
101
115
 
102
116
  ## Development
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "redis"
4
+
5
+ module BigRails
6
+ module Redis
7
+ class Builder
8
+ class << self
9
+ def call(options)
10
+ config = Configuration.new(options)
11
+
12
+ if config.pool_options.any?
13
+ ensure_connection_pool_added!
14
+
15
+ ::ConnectionPool.new(config.pool_options) { build(config) }
16
+ else
17
+ build(config)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def build(config)
24
+ if config.urls.size > 1
25
+ build_redis_distributed_client(urls: config.urls, **config.redis_options)
26
+ else
27
+ build_redis_client(url: config.urls.first, **config.redis_options)
28
+ end
29
+ end
30
+
31
+ def build_redis_distributed_client(urls:, **redis_options)
32
+ ::Redis::Distributed.new([], redis_options).tap do |dist|
33
+ urls.each { |u| dist.add_node(url: u) }
34
+ end
35
+ end
36
+
37
+ def build_redis_client(url:, **redis_options)
38
+ ::Redis.new(redis_options.merge(url: url))
39
+ end
40
+
41
+ def ensure_connection_pool_added!
42
+ require "connection_pool"
43
+ rescue LoadError => e
44
+ warn "You don't have connection_pool installed in your application. Please add it to your Gemfile and run bundle install"
45
+ raise
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -5,24 +5,15 @@ module BigRails
5
5
  class Configuration
6
6
  attr_reader :redis_options
7
7
  attr_reader :pool_options
8
+ attr_reader :urls
8
9
 
9
10
  def initialize(redis_options)
10
11
  @redis_options = redis_options
12
+ @urls = Array(redis_options.delete(:url))
11
13
  @pool_options ||= {}.tap do |pool_options|
12
14
  pool_options[:size] = redis_options.delete(:pool_size) if redis_options[:pool_size]
13
15
  pool_options[:timeout] = redis_options.delete(:pool_timeout) if redis_options[:pool_timeout]
14
16
  end
15
-
16
- ensure_connection_pool_added! if pool_options.any?
17
- end
18
-
19
- private
20
-
21
- def ensure_connection_pool_added!
22
- require "connection_pool"
23
- rescue LoadError => e
24
- warn "You don't have connection_pool installed in your application. Please add it to your Gemfile and run bundle install"
25
- raise e
26
17
  end
27
18
  end
28
19
  end
@@ -28,7 +28,7 @@ module BigRails
28
28
  raise ArgumentError, "connection named '#{name}' already registered"
29
29
  end
30
30
 
31
- @__configurations[name.to_s] = Configuration.new(yield)
31
+ @__configurations[name.to_s] = yield
32
32
  end
33
33
  end
34
34
  end
@@ -1,23 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "redis"
4
-
5
3
  module BigRails
6
4
  module Redis
7
5
  class Registry
8
6
  class UnknownConnection < StandardError
9
7
  end
8
+ class VerificationError < StandardError
9
+ end
10
10
 
11
11
  attr_accessor :builder
12
12
 
13
13
  def initialize
14
14
  @connections = {}
15
15
  @wrapped_connections = {}
16
-
17
- # Default redis builder.
18
- @builder = ->(config) {
19
- ActiveSupport::Cache::RedisCacheStore.build_redis(**config.redis_options)
20
- }
16
+ @builder = Builder
21
17
  end
22
18
 
23
19
  def for(name, wrapped: false)
@@ -38,11 +34,29 @@ module BigRails
38
34
  configurations.keys.map { |name| self.for(name) }.each(&block)
39
35
  end
40
36
 
41
- def verify!(name = nil)
42
- if name
43
- verify_connection(self.for(name))
44
- else
45
- each { |connection| verify_connection(connection) }
37
+ def disconnect
38
+ each do |connection|
39
+ if connection.is_a?(::ConnectionPool)
40
+ connection.reload { |conn| conn.close }
41
+ else
42
+ connection.close
43
+ end
44
+ end
45
+ end
46
+
47
+ def verify!(*names)
48
+ names.map! { |name| validate_name(name) }
49
+ names = configurations.keys if names.empty?
50
+ names.each do |name|
51
+ self.for(name).with do |connection|
52
+ next if connection.connected?
53
+
54
+ begin
55
+ connection.quit
56
+ rescue
57
+ raise VerificationError, "verification for '#{name}' failed"
58
+ end
59
+ end
46
60
  end
47
61
 
48
62
  true
@@ -52,27 +66,14 @@ module BigRails
52
66
 
53
67
  def build_connection(name)
54
68
  config = configurations.fetch(name)
55
-
56
- if config.pool_options.any?
57
- ::ConnectionPool.new(config.pool_options) { builder.call(config) }
58
- else
59
- builder.call(config)
60
- end
69
+ builder.call(config)
61
70
  end
62
71
 
63
72
  def build_wrapped_connection(connection)
64
- if connection.is_a?(::Redis)
65
- connection
66
- else
73
+ if connection.is_a?(::ConnectionPool)
67
74
  ::ConnectionPool.wrap(pool: connection)
68
- end
69
- end
70
-
71
- def verify_connection(connection)
72
- connection.with do |conn|
73
- connected = conn.connected?
74
- conn.ping
75
- conn.quit unless connected
75
+ else
76
+ connection
76
77
  end
77
78
  end
78
79
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module BigRails
4
4
  module Redis
5
- VERSION = "0.3.0"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
@@ -8,8 +8,9 @@ module BigRails
8
8
  extend ActiveSupport::Autoload
9
9
 
10
10
  autoload :ApplicationExtension
11
- autoload :ConfigurationDsl
11
+ autoload :Builder
12
12
  autoload :Configuration
13
+ autoload :ConfigurationDsl
13
14
  autoload :Registry
14
15
  end
15
16
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bigrails-redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ngan Pham
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-19 00:00:00.000000000 Z
11
+ date: 2022-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: redis
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '4.0'
33
+ version: '4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '4.0'
40
+ version: '4'
41
41
  description:
42
42
  email:
43
43
  - ngan@users.noreply.github.com
@@ -48,6 +48,7 @@ files:
48
48
  - README.md
49
49
  - lib/big_rails/redis.rb
50
50
  - lib/big_rails/redis/application_extension.rb
51
+ - lib/big_rails/redis/builder.rb
51
52
  - lib/big_rails/redis/configuration.rb
52
53
  - lib/big_rails/redis/configuration_dsl.rb
53
54
  - lib/big_rails/redis/railtie.rb