Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to Client/Server #165

Merged
merged 7 commits into from
Feb 24, 2020
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
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ rvm:
- 2.4
- 2.3
- 2.2
- jruby-9.2
- jruby-9.2.9.0
- rbx-3
services:
- mysql
Expand Down Expand Up @@ -128,7 +128,7 @@ matrix:
env: SCRIPT='rubocop lib'
- rvm: 2.2
env: SCRIPT='rubocop lib'
- rvm: jruby-9.2
- rvm: jruby-9.2.9.0
env: SCRIPT='rubocop lib'
- rvm: rbx-3
env: SCRIPT='rubocop lib'
Expand Down
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ end

# Rails integration testing
group :rails do
gem 'actionpack', '~> 5.0'
git 'https://github.com/rails/rails.git', branch: '5-2-stable' do
gem 'actionpack'
end
gem 'minitest', '~> 5.0'
end

Expand Down
3 changes: 2 additions & 1 deletion feature_matrix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,14 @@ backends:
- adapter: Client
platforms: [ MRI, JRuby ]
features: [multiprocess]
unknown: [ increment, create, expires, persist ]
unknown: [ increment, create, expires, persist, each_key ]
description: "Moneta client adapter"
notes:
increment: depends on server
create: depends on server
expires: depends on server
persist: depends on server
each_key: depends on server
- adapter: RestClient
platforms: [ MRI, JRuby ]
features: [ multiprocess ]
Expand Down
75 changes: 56 additions & 19 deletions lib/moneta/adapters/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,44 +23,44 @@ def initialize(options = {})
# (see Proxy#key?)
def key?(key, options = {})
write(:key?, key, options)
read
read_msg
end

# (see Proxy#load)
def load(key, options = {})
write(:load, key, options)
read
read_msg
end

# (see Proxy#store)
def store(key, value, options = {})
write(:store, key, value, options)
read
read_msg
value
end

# (see Proxy#delete)
def delete(key, options = {})
write(:delete, key, options)
read
read_msg
end

# (see Proxy#increment)
def increment(key, amount = 1, options = {})
write(:increment, key, amount, options)
read
read_msg
end

# (see Proxy#create)
def create(key, value, options = {})
write(:create, key, value, options)
read
read_msg
end

# (see Proxy#clear)
def clear(options = {})
write(:clear, options)
read
read_msg
self
end

Expand All @@ -70,12 +70,43 @@ def close
nil
end

# (see Proxy#each_key)
def each_key
raise NotImplementedError, 'each_key is not supported' unless supports?(:each_key)
return enum_for(:each_key) unless block_given?

begin
write(:each_key)
yield_break = false

loop do
write('NEXT')

# A StopIteration error will be raised by this call if the server
# reached the end of the enumeration. This will stop the loop
# automatically.
result = read_msg

# yield_break will be true in the ensure block (below) if anything
# happened during the yield to stop further enumeration.
yield_break = true
yield result
yield_break = false
end
ensure
write('BREAK') if yield_break
read_msg # nil return from each_key
end

self
end

# (see Default#features)
def features
@features ||=
begin
write(:features)
read.freeze
read_msg.freeze
end
end

Expand All @@ -86,18 +117,24 @@ def write(*args)
@socket.write([s.bytesize].pack('N') << s)
end

def read
size = @socket
.recv(4).tap do |bytes|
raise EOFError, 'failed to read size' unless bytes.bytesize == 4
end
.unpack('N')
.first

result = Marshal.load(@socket.recv(size).tap do |bytes|
raise EOFError, 'Not enough bytes read' unless bytes.bytesize == size
end)
# JRuby doesn't support socket#recv with flags
if defined?(JRUBY_VERSION)
def read(bytes)
received = @socket.read(bytes)
raise EOFError, "Server closed socket" unless received && received.bytesize == bytes
received
end
else
def read(bytes)
received = @socket.recv(bytes, Socket::MSG_WAITALL)
raise EOFError, "Server closed socket" unless received && received.bytesize == bytes
received
end
end

def read_msg
size = read(4).unpack('N').first
result = Marshal.load(read(size))
raise result if Exception === result
result
end
Expand Down
7 changes: 6 additions & 1 deletion lib/moneta/lock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@ def initialize(adapter, options = {})
protected

def wrap(name, *args, &block)
self.locks ||= Set.new
if locked?
yield
else
lock!(&block)
end
end

def locks=(locks)
Thread.current.thread_variable_set('Moneta::Lock', locks)
end

def locks
Thread.current['Moneta::Lock'] ||= Set.new
Thread.current.thread_variable_get('Moneta::Lock')
end

def lock!(&block)
Expand Down
Loading