Skip to content

Commit

Permalink
Add prune! on backends and release a new version
Browse files Browse the repository at this point in the history
  • Loading branch information
julik committed Feb 22, 2024
1 parent 75f734d commit a368bd7
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 4 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## [1.1.0] - 2024-02-22

- Use modern ActiveRecord migration options for better Rails 7.x compatibility
- Ensure Github actions CI can run and uses Postgres appropriately
- Add examples for more sophisticated use cases
- Implement `#prune!` on storage backends
- Reformat all code using [standard](https://github.com/standardrb/standard) instead of wetransfer_style as it is both more relaxed and more modern

## [1.0.0] - 2023-10-27

- Release 1.0 as the API can be considered stable and the gem has been in production for years

## [0.2.0] - 2022-04-08

- Allow setting the global default TTL for the cached responses
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ config.middleware.insert Idempo, backend: Idempo::ActiveRecordBackend.new
In your regular tasks (cron or Rake) you will want to add a call to delete old Idempo responses (there is an index on `expire_at`):

```ruby
Idempo::ActiveRecordBackend.new.model.where('expire_at < ?', Time.now).in_batches.delete_all
Idempo::ActiveRecordBackend.new.prune!
```

If you need to use Idempo with PGBouncer you will need to write your own locking implementation based on fencing tokens or similar.
Expand Down
5 changes: 5 additions & 0 deletions lib/idempo/active_record_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ def with_idempotency_key(request_key)
end
end

# Deletes expired cached Idempo responses from the database, in batches
def prune!
model.where("expire_at < ?", Time.now).in_batches.delete_all
end

private

def lock_implementation_for_connection(connection)
Expand Down
4 changes: 4 additions & 0 deletions lib/idempo/memory_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,8 @@ def with_idempotency_key(request_key)
@requests_in_flight_mutex.synchronize { @in_progress.delete(request_key) }
end
end

def prune!
@response_store.prune
end
end
4 changes: 4 additions & 0 deletions lib/idempo/redis_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ def with_idempotency_key(request_key)
end
end

def prune!
# Do nothing
end

def self.eval_or_evalsha(redis, script_code, keys:, argv:)
script_sha = Digest::SHA1.hexdigest(script_code)
redis.evalsha(script_sha, keys: keys, argv: argv)
Expand Down
4 changes: 2 additions & 2 deletions lib/idempo/response_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ def lookup(key)
nil
end

private

def prune
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
items_to_delete = remove_lower_than(@expiries, now, &:expire_at)
Expand All @@ -35,6 +33,8 @@ def prune
end
end

private

def binary_insert(array, item, &property_getter)
at_i = array.bsearch_index do |stored_item|
yield(stored_item) <= yield(item)
Expand Down
2 changes: 1 addition & 1 deletion lib/idempo/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class Idempo
VERSION = "1.0.0"
VERSION = "1.1.0"
end
11 changes: 11 additions & 0 deletions spec/idempo/shared_backend_specs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@
end
end

it "supports pruning" do
random_key = Random.new(RSpec.configuration.seed).bytes(11)
value = Random.new(RSpec.configuration.seed).bytes(1209)

subject.with_idempotency_key(random_key) do |store|
store.store(data: value, ttl: 1)
end
sleep 2
expect { subject.prune! }.not_to raise_error
end

it "provides locking" do
lock_key = Random.new(RSpec.configuration.seed).bytes(14)
a, b, c = (1..3).map do
Expand Down

0 comments on commit a368bd7

Please sign in to comment.