forked from guitsaru/rack-idempotency
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Minor improvements: storage move, small behaviour tweaks & simplistic…
… specs (guitsaru#3)
- Loading branch information
1 parent
a058ee6
commit 2b883e4
Showing
18 changed files
with
355 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# frozen_string_literal: true | ||
|
||
module Rack | ||
class Idempotency | ||
class Store | ||
# Basic interface for a store | ||
class Base | ||
def read(_key) | ||
raise NotImplementedError | ||
end | ||
|
||
def write(_key, _value) | ||
raise NotImplementedError | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# frozen_string_literal: true | ||
|
||
module Rack | ||
class Idempotency | ||
class Store | ||
# Stores idempotency information in a Hash. | ||
class Memory < Base | ||
def initialize | ||
@store = {} | ||
super | ||
end | ||
|
||
def read(key) | ||
store[key] | ||
end | ||
|
||
def write(key, value) | ||
store[key] = value | ||
end | ||
|
||
private | ||
|
||
attr_reader :store | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# frozen_string_literal: true | ||
|
||
module Rack | ||
class Idempotency | ||
class Store | ||
# Most basic version of the store. This class doesn't read or write. | ||
class Null < Base | ||
def read(_key); end | ||
|
||
def write(_key, _value); end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'redis' | ||
|
||
module Rack | ||
class Idempotency | ||
# Stores idempotency information in a provided Redis instance. | ||
class Store | ||
class Redis < Base | ||
DEFAULT_TTL = 86400 | ||
|
||
# @param client [::Redis] A Redis client used to retrieve the requests. | ||
# @param ttl [#to_i, nil] Expiry duration in seconds. | ||
def initialize(client:, ttl: DEFAULT_TTL) | ||
@client = client | ||
@ttl = ttl.to_i | ||
end | ||
|
||
def read(key) | ||
client.get(key) | ||
end | ||
|
||
def write(key, value) | ||
if ttl.positive? | ||
client.setex(key, ttl, value) | ||
else | ||
client.set(key, value) | ||
end | ||
end | ||
|
||
private | ||
|
||
attr_reader :client, :ttl | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spec_helper' | ||
|
||
RSpec.describe Rack::Idempotency::Store::Base do | ||
describe '#write' do | ||
subject { described_class.new.write('key', 'd353c6836cc8c2a0bcf79626bb64bc48032e33ece8e8407c4cb65830965fa814') } | ||
|
||
it 'raises NotImplementedError' do | ||
expect { subject }.to raise_error(NotImplementedError) | ||
end | ||
end | ||
|
||
describe '#read' do | ||
subject { described_class.new.read('key') } | ||
|
||
it 'raises NotImplementedError' do | ||
expect { subject }.to raise_error(NotImplementedError) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spec_helper' | ||
|
||
RSpec.describe Rack::Idempotency::Store::Memory do | ||
let(:store) { described_class.new } | ||
let(:value) { 'd353c6836cc8c2a0bcf79626bb64bc48032e33ece8e8407c4cb65830965fa814' } | ||
|
||
describe '#write' do | ||
subject { store.write('key', value) } | ||
|
||
it 'stores value in memory' do | ||
expect(subject).to eq(value) | ||
expect(store.read('key')).to eq(value) | ||
end | ||
end | ||
|
||
describe '#read' do | ||
subject { store.read('key') } | ||
|
||
it 'reads value from memory' do | ||
store.write('key', value) | ||
expect(subject).to eq(value) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spec_helper' | ||
|
||
RSpec.describe Rack::Idempotency::Store::Null do | ||
let(:store) { described_class.new } | ||
let(:value) { 'd353c6836cc8c2a0bcf79626bb64bc48032e33ece8e8407c4cb65830965fa814' } | ||
|
||
describe '#write' do | ||
subject { store.write('key', value) } | ||
|
||
it 'stores nothing' do | ||
expect(subject).to be_nil | ||
expect(store.read('key')).to be_nil | ||
end | ||
end | ||
|
||
describe '#read' do | ||
subject { store.read('key') } | ||
|
||
it 'reads nothing' do | ||
store.write('key', value) | ||
expect(subject).to be_nil | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spec_helper' | ||
|
||
RSpec.describe Rack::Idempotency::Store::Redis do | ||
let(:redis) { instance_spy(::Redis) } | ||
let(:value) { 'd353c6836cc8c2a0bcf79626bb64bc48032e33ece8e8407c4cb65830965fa814' } | ||
|
||
describe '#write' do | ||
subject! { store.write('key', value) } | ||
|
||
context 'with positive TTL' do | ||
let(:store) { described_class.new(client: redis, ttl: 5) } | ||
|
||
it 'sets the key expiring in TTL seconds' do | ||
expect(redis).to have_received(:setex).with('key', 5, value).once | ||
end | ||
end | ||
|
||
context 'with negative or zero TTL' do | ||
let(:store) { described_class.new(client: redis, ttl: -5) } | ||
|
||
it 'sets the key without expiration' do | ||
expect(redis).to have_received(:set).with('key', value).once | ||
end | ||
end | ||
|
||
context 'without a provided TTL' do | ||
let(:store) { described_class.new(client: redis) } | ||
|
||
it 'sets the key for default TTL' do | ||
expect(redis).to have_received(:setex).with('key', described_class::DEFAULT_TTL, value).once | ||
end | ||
end | ||
end | ||
|
||
describe '#read' do | ||
subject! { store.read('key') } | ||
|
||
let(:store) { described_class.new(client: redis) } | ||
|
||
before { redis.set('key', value) } | ||
|
||
it 'reads value using Redis client' do | ||
expect(redis).to have_received(:get).with('key') | ||
end | ||
end | ||
end |
Oops, something went wrong.