consistent_random 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 980cb06e9d5c20085243ecb114932f744343830090a6148db527d5c685458c46
4
- data.tar.gz: 8872129783254ab5cd4ae70f4051ceb5901c4d28852168dfa0e4b229c8541d13
3
+ metadata.gz: 53c979ca8b32310fc3357e231ed29a029964396e19f1bafd0ac44220be535a1a
4
+ data.tar.gz: 35e7431d888b473db4063a8cec225314aae0e445740388a97ee9296d5a559c03
5
5
  SHA512:
6
- metadata.gz: 99ad2eb1aaf87bdee2aa1c1052d73c8e9db13e392c9d501c9d8d445644902414a0602ef4f8da3c63199cd55e2da0519bd15dd48b7070bbec59414506d181613c
7
- data.tar.gz: 76a775637c84fa12fb56bf6437943ffdc59cb7a454ec1fa9af44fda471d614237e61297c18251744fb45d5de2c0d18b8ec84ef1a3603b4e56b16ce954bb4a5e1
6
+ metadata.gz: cbc32f5cbbf0ad48742e9ede2e14a187530a32b2e832a0b9af5b293c9716f3e9893795601853ccc4b32ad9cbb24b70decb88f9b94f2c17b7ba687bfca2cd1810
7
+ data.tar.gz: 80ebaa9bfd1ba8519e755369cf76184e89c97c88302979a7b4fe0d176fbb107a3734a9fa2aa820ad80d0f5f3b370f7755b721080be7ec79219df48a0e6c5d3a9
data/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## 2.1.0
8
+
9
+ ### Added
10
+
11
+ - Added optional seed block to the Rack middleware to allow for custom seed values based on the request.
12
+ - Added helper method `ConsistentRandom::SidekiqMiddleware.install` to install both the client and server middlewares in one call.
13
+
7
14
  ## 2.0.0
8
15
 
9
16
  ### Changed
data/README.md CHANGED
@@ -8,11 +8,23 @@
8
8
 
9
9
  This Ruby gem allows you to generate consistent random values tied to a specific name within a defined scope. It ensures that random behavior remains consistent within a particular context.
10
10
 
11
+ Consistent Random is designed to simplify feature rollouts and other scenarios where you need to generate random values, but need those values to remain consistent within defined contexts.
12
+
11
13
  For example, consider rolling out a new feature to a subset of requests. You may want to do this to allow testing a new feature by only enabling it for 10% of requests. You want to randomize which requests get the new feature, but ensure that within each request, the feature is consistently enabled or disabled across all actions. This gem allows you to achieve that by tying random values to specific names and defining a scope. Within that scope, the same value will be consistently generated for each named variable.
12
14
 
15
+ ## Table of Contents
16
+ - [Usage](#usage)
17
+ - [Middlewares](#middlewares)
18
+ - [Rack Middleware](#rack-middleware)
19
+ - [Sidekiq Middleware](#sidekiq-middleware)
20
+ - [ActiveJob](#activejob)
21
+ - [Installation](#installation)
22
+ - [Contributing](#contributing)
23
+ - [License](#license)
24
+
13
25
  ## Usage
14
26
 
15
- To generate consistent random values, you need to define a scope. You do this with the `ConsistentRandom.scope` method. Within the scope block, calls to `ConsistentRandom` will return the same random values for the same name.
27
+ To generate consistent random values, you need to define a scope. Scopes are defined with the `ConsistentRandom.scope` method. Within the scope block, calls to `ConsistentRandom` will return the same random values for the same name. Scopes are isolated to the block in which they're defined, meaning random values are consistent within each scoped block but independent across threads or separate invocations.
16
28
 
17
29
  ```ruby
18
30
  ConsistentRandom.scope do
@@ -65,11 +77,11 @@ random = ConsistentRandom.new("foobar")
65
77
  random.rand != random.rand # => true
66
78
  ```
67
79
 
68
- ### Middlewares
80
+ ## Middlewares
69
81
 
70
- The gem provides built-in middlewares for Rack and Sidekiq, automatically scoping requests and jobs. This ensures that consistent random values are generated within the request/job context.
82
+ The gem provides built-in middlewares for Rack, Sidekiq, and ActiveJob. These middlewares allow you to automatically scope web requests and propagate consistent random values from the original request to asynchronous jobs.
71
83
 
72
- #### Rack Middleware
84
+ ### Rack Middleware
73
85
 
74
86
  In a Rack application:
75
87
 
@@ -87,14 +99,35 @@ Or in a Rails application:
87
99
  config.middleware.use ConsistentRandom::RackMiddleware
88
100
  ```
89
101
 
90
- #### Sidekiq Middleware
102
+ You can also specify a seed value based on the request. This can be useful if you want to generate random values based on a specific request attribute, such as the current user.
103
+
104
+ ```ruby
105
+ Rack::Builder.app do
106
+ use ConsistentRandom::RackMiddleware, ->(env) { env["warden"].user.id }
107
+ run MyApp
108
+ end
109
+ ```
110
+
111
+ If the seed block returns `nil`, then a random seed will be generated for the request.
91
112
 
92
- Add the middlewares to your Sidekiq configuration:
113
+ ### Sidekiq Middleware
114
+
115
+ Add the middlewares to your Sidekiq in an initializer:
116
+
117
+ ```ruby
118
+ ConsistentRandom::SidekiqMiddleware.install
119
+ ```
120
+
121
+ This will install both the client and server middleware. You can also install them manually if you need more control on the order of the middlewares. You should install the client middleware on both the server and client configurations.
93
122
 
94
123
  ```ruby
95
124
  Sidekiq.configure_server do |config|
96
125
  config.server_middleware do |chain|
97
- chain.add ConsistentRandom::SidekiqMiddleware
126
+ chain.prepend ConsistentRandom::SidekiqMiddleware
127
+ end
128
+
129
+ config.client_middleware do |chain|
130
+ chain.add ConsistentRandom::SidekiqClientMiddleware
98
131
  end
99
132
  end
100
133
 
@@ -119,6 +152,20 @@ class MyWorker
119
152
  end
120
153
  ```
121
154
 
155
+ You can still specify a custom seed value in your worker if, for example, you want to ensure that values are consistent based on a user when the job is not enqueued from a Rack request.
156
+
157
+ ```ruby
158
+ class MyWorker
159
+ include Sidekiq::Job
160
+
161
+ def perform(user_id)
162
+ ConsistentRandom.scope(user_id) do
163
+ ...
164
+ end
165
+ end
166
+ end
167
+ ```
168
+
122
169
  ### ActiveJob
123
170
 
124
171
  You can use consistent random values in your ActiveJob jobs by including the `ConsistentRandom::ActiveJob` module.
@@ -147,6 +194,18 @@ class MyJob < ApplicationJob
147
194
  end
148
195
  ```
149
196
 
197
+ You can still specify a custom seed value in your worker if, for example, you want to ensure that values are consistent based on a user when the job is not enqueued from a Rack request.
198
+
199
+ ```ruby
200
+ class MyJob < ApplicationJob
201
+ def perform(user_id)
202
+ ConsistentRandom.scope(user_id) do
203
+ ...
204
+ end
205
+ end
206
+ end
207
+ ```
208
+
150
209
  ## Installation
151
210
 
152
211
  Add this line to your application's Gemfile:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0
1
+ 2.1.0
@@ -4,12 +4,19 @@ class ConsistentRandom
4
4
  # Rack middleware that wraps a request with consistent random scope
5
5
  # so that you can generate consistent random values within a request.
6
6
  class RackMiddleware
7
- def initialize(app)
7
+ # @param app [Object] Rack application to wrap
8
+ # @param seed_block [Proc, #call, nil] block to generate seed for the request
9
+ # If provided, the block will be called with the request env and
10
+ # the return value will be used as the seed for the request. You can
11
+ # use this to generate a seed based on the request state..
12
+ def initialize(app, seed_block = nil)
8
13
  @app = app
14
+ @seed_block = seed_block
9
15
  end
10
16
 
11
17
  def call(env)
12
- ConsistentRandom.scope do
18
+ seed = @seed_block.call(env) if @seed_block
19
+ ConsistentRandom.scope(seed) do
13
20
  @app.call(env)
14
21
  end
15
22
  end
@@ -8,6 +8,26 @@ class ConsistentRandom
8
8
  include Sidekiq::ServerMiddleware
9
9
  end
10
10
 
11
+ class << self
12
+ def install
13
+ Sidekiq.configure_server do |config|
14
+ config.server_middleware do |chain|
15
+ chain.prepend ConsistentRandom::SidekiqMiddleware
16
+ end
17
+
18
+ config.client_middleware do |chain|
19
+ chain.add ConsistentRandom::SidekiqClientMiddleware
20
+ end
21
+ end
22
+
23
+ Sidekiq.configure_client do |config|
24
+ config.client_middleware do |chain|
25
+ chain.add ConsistentRandom::SidekiqClientMiddleware
26
+ end
27
+ end
28
+ end
29
+ end
30
+
11
31
  def call(job_instance, job_payload, queue)
12
32
  ConsistentRandom.scope(job_payload["consistent_random_seed"]) do
13
33
  yield
@@ -3,15 +3,15 @@
3
3
  require "digest/sha1"
4
4
  require "securerandom"
5
5
 
6
- require_relative "consistent_random/rack_middleware"
7
- require_relative "consistent_random/sidekiq_middleware"
8
- require_relative "consistent_random/sidekiq_client_middleware"
9
- require_relative "consistent_random/active_job"
10
-
11
6
  class ConsistentRandom
12
7
  SEED_DIVISOR = (2**64 - 1).to_f
13
8
  private_constant :SEED_DIVISOR
14
9
 
10
+ autoload :RackMiddleware, "consistent_random/rack_middleware"
11
+ autoload :SidekiqMiddleware, "consistent_random/sidekiq_middleware"
12
+ autoload :SidekiqClientMiddleware, "consistent_random/sidekiq_client_middleware"
13
+ autoload :ActiveJob, "consistent_random/active_job"
14
+
15
15
  class << self
16
16
  # Define a scope where consistent random values will be generated.
17
17
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: consistent_random
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Durand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-24 00:00:00.000000000 Z
11
+ date: 2024-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler