bigrails-redis 0.1.0

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: 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 [![Ruby](https://github.com/BigRails/bigrails-redis/actions/workflows/main.yml/badge.svg)](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,9 @@
1
+ module BigRails
2
+ module Redis
3
+ module ApplicationExtension
4
+ def redis
5
+ @redis ||= Registry.new
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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,11 @@
1
+ require "rails"
2
+
3
+ module BigRails
4
+ module Redis
5
+ class Railtie < Rails::Railtie
6
+ config.before_configuration do |app|
7
+ app.include(ApplicationExtension)
8
+ end
9
+ end
10
+ end
11
+ 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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BigRails
4
+ module Redis
5
+ VERSION = "0.1.0"
6
+ end
7
+ 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: []