bigrails-redis 0.1.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 +7 -0
- data/README.md +118 -0
- data/lib/big_rails/redis/application_extension.rb +9 -0
- data/lib/big_rails/redis/configuration.rb +29 -0
- data/lib/big_rails/redis/configuration_dsl.rb +35 -0
- data/lib/big_rails/redis/railtie.rb +11 -0
- data/lib/big_rails/redis/registry.rb +88 -0
- data/lib/big_rails/redis/version.rb +7 -0
- data/lib/big_rails/redis.rb +17 -0
- data/lib/bigrails-redis.rb +1 -0
- metadata +69 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a759e01aab33407d58cedf4e5920130bc302fb72bdf1f31d9946a6315bade497
|
4
|
+
data.tar.gz: bce916691075cb892b279bc14aa152ffd4dd436470d4204199f19f0b9d0c18ba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5f9d4a1d5c7d237ecd5ef4dfafc4dcb60a000a417992fc133097b96858b0c092e8707584757c5f6d42b7d204431b2dace0857013e9e19299d7e56da8b72d5916
|
7
|
+
data.tar.gz: 67b9273fbbcc1f4ccbcd1883499c6acf841ef02aa477b742cbc03e4ac19e358f9859c61e5cfcf7bf4a0cb356ce20b4209bf26799759dea11eef44829d8fd5d1f
|
data/README.md
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# BigRails::Redis [](https://github.com/BigRails/bigrails-redis/actions/workflows/main.yml)
|
2
|
+
|
3
|
+
A simple Redis connection manager for Rails applications with distributed and [ConnectionPool](https://github.com/mperham/connection_pool) support.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add to your Gemfile:
|
8
|
+
|
9
|
+
$ bundle add bigrails-redis
|
10
|
+
|
11
|
+
Create a redis configuration file:
|
12
|
+
|
13
|
+
$ touch config/redis.rb
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
### Configuring Connections
|
18
|
+
|
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
|
+
|
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.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
# Simple hardcoded example.
|
25
|
+
connection(:default) do
|
26
|
+
{
|
27
|
+
url: "redis://localhost"
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
# Do something more dynamic.
|
32
|
+
%w(
|
33
|
+
cache
|
34
|
+
foobar
|
35
|
+
).each do |name|
|
36
|
+
connection(name) do
|
37
|
+
{
|
38
|
+
url: Rails.application.credentials.fetch("#{name}_redis")
|
39
|
+
}.tap do |options|
|
40
|
+
# Maybe in CI, you need to change the host.
|
41
|
+
if ENV['CI']
|
42
|
+
options[:host] = "redishost"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Connection pool support.
|
49
|
+
connection(:sidekiq) do
|
50
|
+
{
|
51
|
+
url: "redis://localhost/2"
|
52
|
+
pool_timeout: 5,
|
53
|
+
pool_size: 5
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
# Distributed Redis support.
|
58
|
+
connection(:baz) do
|
59
|
+
{
|
60
|
+
url: [
|
61
|
+
"redis://host1",
|
62
|
+
"redis://host2",
|
63
|
+
"redis://host3"
|
64
|
+
]
|
65
|
+
}
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
### Accessing Connections
|
70
|
+
|
71
|
+
To access connections inside the application, you can do the following:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
Rails.application.redis #=> Redis Registry
|
75
|
+
|
76
|
+
Rails.application.redis.for(:default) #=> Redis
|
77
|
+
Rails.application.redis.for(:cache) #=> Redis
|
78
|
+
Rails.application.redis.for(:foobar) #=> Redis
|
79
|
+
Rails.application.redis.for(:sidekiq) #=> ConnectionPool
|
80
|
+
```
|
81
|
+
|
82
|
+
If needed, you can request a [wrapped connection pool](https://github.com/mperham/connection_pool#migrating-to-a-connection-pool):
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
Rails.application.redis.for(:pooled_connection, wrapped: true)
|
86
|
+
```
|
87
|
+
|
88
|
+
If you request a wrapped connection for a non-pooled connection, it'll just return the original, plain `Redis` connection object. Rails already modifies `Redis` to add `ConnectionPool`-like behavior by adding a `with` method that yields the connection itself.
|
89
|
+
|
90
|
+
### Verifying Connections
|
91
|
+
|
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.
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
# Verify all connections:
|
96
|
+
Rails.application.redis.verify!
|
97
|
+
|
98
|
+
# Verify a single connection:
|
99
|
+
Rails.application.redis.verify!(:foobar)
|
100
|
+
```
|
101
|
+
|
102
|
+
## Development
|
103
|
+
|
104
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
105
|
+
|
106
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
107
|
+
|
108
|
+
## Contributing
|
109
|
+
|
110
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ngan/bigrails-redis. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/ngan/bigrails-redis/blob/master/CODE_OF_CONDUCT.md).
|
111
|
+
|
112
|
+
## License
|
113
|
+
|
114
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
115
|
+
|
116
|
+
## Code of Conduct
|
117
|
+
|
118
|
+
Everyone interacting in the BigRails::Redis project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ngan/bigrails-redis/blob/master/CODE_OF_CONDUCT.md).
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "active_support/cache/redis_cache_store"
|
2
|
+
|
3
|
+
module BigRails
|
4
|
+
module Redis
|
5
|
+
class Configuration
|
6
|
+
attr_reader :redis_options
|
7
|
+
attr_reader :pool_options
|
8
|
+
|
9
|
+
def initialize(redis_options)
|
10
|
+
@redis_options = redis_options
|
11
|
+
@pool_options ||= {}.tap do |pool_options|
|
12
|
+
pool_options[:size] = redis_options.delete(:pool_size) if redis_options[:pool_size]
|
13
|
+
pool_options[:timeout] = redis_options.delete(:pool_timeout) if redis_options[:pool_timeout]
|
14
|
+
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
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BigRails
|
4
|
+
module Redis
|
5
|
+
class ConfigurationDsl
|
6
|
+
FILENAME = "redis.rb"
|
7
|
+
|
8
|
+
attr_reader :__configurations
|
9
|
+
|
10
|
+
def self.resolve
|
11
|
+
new.__configurations
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@__configurations = {}
|
16
|
+
|
17
|
+
file = File.join(Rails.application.paths["config"].first, FILENAME)
|
18
|
+
instance_eval(File.read(file), file, 1)
|
19
|
+
|
20
|
+
@__configurations.freeze
|
21
|
+
end
|
22
|
+
|
23
|
+
# DSL Methods
|
24
|
+
|
25
|
+
def connection(name)
|
26
|
+
name = name.to_s
|
27
|
+
if @__configurations.key?(name)
|
28
|
+
raise ArgumentError, "connection named '#{name}' already registered"
|
29
|
+
end
|
30
|
+
|
31
|
+
@__configurations[name.to_s] = Configuration.new(yield)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BigRails
|
4
|
+
module Redis
|
5
|
+
class Registry
|
6
|
+
class UnknownConnection < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :builder
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@connections = {}
|
13
|
+
@wrapped_connections = {}
|
14
|
+
|
15
|
+
# Default redis builder.
|
16
|
+
@builder = ->(config) {
|
17
|
+
ActiveSupport::Cache::RedisCacheStore.build_redis(**config.redis_options)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def for(name, wrapped: false)
|
22
|
+
name = validate_name(name)
|
23
|
+
|
24
|
+
if wrapped
|
25
|
+
@wrapped_connections[name] ||= build_wrapped_connection(self.for(name))
|
26
|
+
else
|
27
|
+
@connections[name] ||= build_connection(name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def config_for(name)
|
32
|
+
configurations[validate_name(name)]
|
33
|
+
end
|
34
|
+
|
35
|
+
def each(&block)
|
36
|
+
configurations.keys.map { self.for(name) }.each(&block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def verify!(name = nil)
|
40
|
+
if name
|
41
|
+
verify_connection(self.for(name))
|
42
|
+
else
|
43
|
+
each { |connection| verify_connection(connection) }
|
44
|
+
end
|
45
|
+
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def build_connection(name)
|
52
|
+
config = configurations.fetch(name)
|
53
|
+
|
54
|
+
if config.pool_options.any?
|
55
|
+
::ConnectionPool.new(config.pool_options) { builder.call(config) }
|
56
|
+
else
|
57
|
+
builder.call(config)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def build_wrapped_connection(connection)
|
62
|
+
if connection.is_a?(::Redis)
|
63
|
+
connection
|
64
|
+
else
|
65
|
+
::ConnectionPool.wrap(pool: connection)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def verify_connection(connection)
|
70
|
+
connection.with do |redis|
|
71
|
+
redis.ping == "PONG"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def validate_name(name)
|
76
|
+
name = name.to_s
|
77
|
+
unless configurations.key?(name)
|
78
|
+
raise UnknownConnection, "connection for '#{name}' is not registered"
|
79
|
+
end
|
80
|
+
name
|
81
|
+
end
|
82
|
+
|
83
|
+
def configurations
|
84
|
+
@configurations ||= ConfigurationDsl.resolve
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "redis/version"
|
4
|
+
require "active_support"
|
5
|
+
|
6
|
+
module BigRails
|
7
|
+
module Redis
|
8
|
+
extend ActiveSupport::Autoload
|
9
|
+
|
10
|
+
autoload :ApplicationExtension
|
11
|
+
autoload :ConfigurationDsl
|
12
|
+
autoload :Configuration
|
13
|
+
autoload :Registry
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require "big_rails/redis/railtie"
|
@@ -0,0 +1 @@
|
|
1
|
+
require "big_rails/redis"
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bigrails-redis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ngan Pham
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-03-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '6'
|
27
|
+
description:
|
28
|
+
email:
|
29
|
+
- ngan@users.noreply.github.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- lib/big_rails/redis.rb
|
36
|
+
- lib/big_rails/redis/application_extension.rb
|
37
|
+
- lib/big_rails/redis/configuration.rb
|
38
|
+
- lib/big_rails/redis/configuration_dsl.rb
|
39
|
+
- lib/big_rails/redis/railtie.rb
|
40
|
+
- lib/big_rails/redis/registry.rb
|
41
|
+
- lib/big_rails/redis/version.rb
|
42
|
+
- lib/bigrails-redis.rb
|
43
|
+
homepage: https://github.com/bigrails/bigrails-redis
|
44
|
+
licenses:
|
45
|
+
- MIT
|
46
|
+
metadata:
|
47
|
+
homepage_uri: https://github.com/bigrails/bigrails-redis
|
48
|
+
source_code_uri: https://github.com/BigRails/bigrails-redis
|
49
|
+
changelog_uri: https://github.com/bigrails/bigrails-redis/releases
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 2.6.0
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubygems_version: 3.2.32
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: Redis connection manager for Rails applications.
|
69
|
+
test_files: []
|