Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 4 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -779,22 +779,11 @@ split_config = YAML.load_file(Rails.root.join('config', 'split.yml'))
Split.redis = split_config[Rails.env]
```

### Redis Caching (v4.0+)
### Redis Caching

> [!WARNING]
> The caching mechanism has known issues in multi-process environments (e.g., Puma) and multi-server deployments with load balancers (typical production environments). Cache invalidation does not propagate across processes or servers, which can lead to inconsistent experiment data being served to users. See [#735](https://github.com/splitrb/split/issues/735) for details. Use with caution in production environments.

In some high-volume usage scenarios, Redis load can be incurred by repeated
fetches for fairly static data. Enabling caching will reduce this load.

```ruby
Split.configuration.cache = true
````

This currently caches:
- `Split::ExperimentCatalog.find`
- `Split::Experiment.start_time`
- `Split::Experiment.winner`
`Split.configuration.cache` no longer has any effect and can be removed. The cache
did not stay consistent across processes (see [#735](https://github.com/splitrb/split/issues/735)),
and Split now makes few enough Redis calls that it is no longer needed.

## Namespaces

Expand Down
5 changes: 0 additions & 5 deletions lib/split.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
require "split/algorithms/weighted_sample"
require "split/algorithms/whiplash"
require "split/alternative"
require "split/cache"
require "split/configuration"
require "split/encapsulated_helper"
require "split/exceptions"
Expand Down Expand Up @@ -69,10 +68,6 @@ def configure
self.configuration ||= Configuration.new
yield(configuration)
end

def cache(namespace, key, &block)
Split::Cache.fetch(namespace, key, &block)
end
end

# Check to see if being run in a Rails application. If so, wait until before_initialize to run configuration so Gems that create ENV variables have the chance to initialize first.
Expand Down
27 changes: 0 additions & 27 deletions lib/split/cache.rb

This file was deleted.

26 changes: 9 additions & 17 deletions lib/split/experiment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ class Experiment
}

def self.find(name)
Split.cache(:experiments, name) do
experiment = Experiment.new(name)
experiment.load_from_redis
experiment unless experiment.alternatives.empty?
end
experiment = Experiment.new(name)
experiment.load_from_redis
experiment unless experiment.alternatives.empty?
end

def self.find_many(names)
Expand Down Expand Up @@ -149,13 +147,11 @@ def alternatives=(alts)
end

def winner
Split.cache(:experiment_winner, name) do
experiment_winner = redis.hget(:experiment_winner, name)
if experiment_winner
Split::Alternative.new(experiment_winner, name)
else
nil
end
experiment_winner = redis.hget(:experiment_winner, name)
if experiment_winner
Split::Alternative.new(experiment_winner, name)
else
nil
end
end

Expand All @@ -181,7 +177,6 @@ def control
def reset_winner
redis.hdel(:experiment_winner, name)
@has_winner = false
Split::Cache.clear_key(@name)
end

def start
Expand All @@ -191,9 +186,7 @@ def start
def start_time
return @start_time if defined?(@start_time)

@start_time = Split.cache(:experiment_start_times, @name) do
parse_start_time(redis.hget(:experiment_start_times, @name))
end
@start_time = parse_start_time(redis.hget(:experiment_start_times, @name))
end

def prefetch_trial_state!
Expand Down Expand Up @@ -258,7 +251,6 @@ def resettable?

def reset
Split.configuration.on_before_experiment_reset.call(self)
Split::Cache.clear_key(@name)
alternatives.each(&:reset)
reset_winner
Split.configuration.on_experiment_reset.call(self)
Expand Down
84 changes: 0 additions & 84 deletions spec/cache_spec.rb

This file was deleted.

11 changes: 11 additions & 0 deletions spec/experiment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,17 @@ def alternative(color)
it "should have no winner initially" do
expect(experiment.winner).to be_nil
end

it "should see a winner changed by another process when the cache setting is on" do
Split.configuration.cache = true
experiment.save
experiment.winner = "red"
expect(experiment.winner.name).to eq("red")

Split.redis.hset(:experiment_winner, "link_color", "blue")

expect(experiment.winner.name).to eq("blue")
end
end

describe "winner=" do
Expand Down
1 change: 0 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ module GlobalSharedContext
Split.redis = Redis.new
Split.redis.select(10)
Split.redis.flushdb
Split::Cache.clear
@ab_user = mock_user
@params = nil
end
Expand Down
Loading