From 0317a57af1b21116a9ccd85c9ee42186d9ff2abd Mon Sep 17 00:00:00 2001 From: Vladimir Kochnev Date: Fri, 21 Aug 2015 15:54:39 +0300 Subject: [PATCH 1/8] Add redis-server to .travis.yml --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 337d72c..bd31d2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,3 +15,6 @@ matrix: notifications: irc: "irc.freenode.org#celluloid" + +services: + - redis-server From 46917ee8dad8cd110ca182cdd82d4a676208a181 Mon Sep 17 00:00:00 2001 From: Vladimir Kochnev Date: Fri, 21 Aug 2015 15:58:27 +0300 Subject: [PATCH 2/8] Run travis in containers. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index bd31d2e..f991ec5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +sudo: false + rvm: - 1.9.3 - 2.0.0 From 583ce5f16fc9696240c1030b5e4182d68ad66708 Mon Sep 17 00:00:00 2001 From: Vladimir Kochnev Date: Fri, 21 Aug 2015 14:14:24 +0300 Subject: [PATCH 3/8] Move version to CelluloidRedis::VERSION --- celluloid-redis.gemspec | 2 +- lib/celluloid/redis/version.rb | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/celluloid-redis.gemspec b/celluloid-redis.gemspec index a086127..8af80d5 100644 --- a/celluloid-redis.gemspec +++ b/celluloid-redis.gemspec @@ -5,7 +5,7 @@ require 'celluloid/redis/version' Gem::Specification.new do |spec| spec.name = "celluloid-redis" - spec.version = Celluloid::Redis::VERSION + spec.version = CelluloidRedis::VERSION spec.authors = ["Tony Arcieri"] spec.email = ["tony.arcieri@gmail.com"] spec.description = "Celluloid::IO support for the redis-rb library" diff --git a/lib/celluloid/redis/version.rb b/lib/celluloid/redis/version.rb index 19d8a7a..d302296 100644 --- a/lib/celluloid/redis/version.rb +++ b/lib/celluloid/redis/version.rb @@ -1,5 +1,3 @@ -module Celluloid - module Redis - VERSION = "0.0.2" - end +module CelluloidRedis + VERSION = "0.0.2" end From 05151d0ad28515d865007463e762eccac3a1875d Mon Sep 17 00:00:00 2001 From: Vladimir Kochnev Date: Fri, 21 Aug 2015 14:28:29 +0300 Subject: [PATCH 4/8] Load culture for celluloid and celluloid-io --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 4737819..7a622fe 100644 --- a/Gemfile +++ b/Gemfile @@ -2,5 +2,5 @@ source 'https://rubygems.org' gemspec gem 'coveralls', require: false -gem 'celluloid', github: 'celluloid/celluloid' -gem 'celluloid-io', github: 'celluloid/celluloid-io' +gem 'celluloid', github: 'celluloid/celluloid', submodules: true +gem 'celluloid-io', github: 'celluloid/celluloid-io', submodules: true From 8d549c805e73d54cfd1131f821c83614ded349f5 Mon Sep 17 00:00:00 2001 From: Vladimir Kochnev Date: Fri, 21 Aug 2015 14:28:48 +0300 Subject: [PATCH 5/8] Remove deprecated --default_path rspec parameter. --- .rspec | 1 - 1 file changed, 1 deletion(-) diff --git a/.rspec b/.rspec index 675313d..3d9d294 100644 --- a/.rspec +++ b/.rspec @@ -1,4 +1,3 @@ --color --format documentation --backtrace ---default_path spec From bf8790bf2e32515f7c15df0cc83a57871405c976 Mon Sep 17 00:00:00 2001 From: Vladimir Kochnev Date: Fri, 21 Aug 2015 14:29:38 +0300 Subject: [PATCH 6/8] Remove buggy redis_ext.rb --- lib/celluloid/redis.rb | 1 - lib/celluloid/redis/redis_ext.rb | 28 ---------------------------- 2 files changed, 29 deletions(-) delete mode 100644 lib/celluloid/redis/redis_ext.rb diff --git a/lib/celluloid/redis.rb b/lib/celluloid/redis.rb index e0ec131..4648b0e 100644 --- a/lib/celluloid/redis.rb +++ b/lib/celluloid/redis.rb @@ -1,4 +1,3 @@ require "redis" require "celluloid/redis/version" -require "celluloid/redis/redis_ext" \ No newline at end of file diff --git a/lib/celluloid/redis/redis_ext.rb b/lib/celluloid/redis/redis_ext.rb deleted file mode 100644 index 76a72f4..0000000 --- a/lib/celluloid/redis/redis_ext.rb +++ /dev/null @@ -1,28 +0,0 @@ -class Redis - class Client - # Well this is really sad. redis-rb does not provide extensible driver - # support. Instead they couple everything together though this method. - # This leaves us no choice but to monkeypatch - def _parse_driver(driver) - driver = driver.to_s if driver.is_a?(Symbol) - - if driver.kind_of?(String) - case driver - when "ruby" - require "redis/connection/ruby" - driver = Connection::Ruby - when "celluloid" - require "redis/connection/celluloid" - driver = Connection::Celluloid - when "hiredis" - require "redis/connection/hiredis" - driver = Connection::Hiredis - else - raise "Unknown driver: #{driver}" - end - end - - driver - end - end -end \ No newline at end of file From bd7451dc3bc0c059ca39a978a828d13193aa7570 Mon Sep 17 00:00:00 2001 From: Vladimir Kochnev Date: Fri, 21 Aug 2015 15:43:42 +0300 Subject: [PATCH 7/8] Add failing spec simulating race condition. --- spec/redis/connection/celluloid_spec.rb | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/redis/connection/celluloid_spec.rb b/spec/redis/connection/celluloid_spec.rb index 7aa3ada..bf9237b 100644 --- a/spec/redis/connection/celluloid_spec.rb +++ b/spec/redis/connection/celluloid_spec.rb @@ -21,4 +21,40 @@ expect { redis.shutdown }.not_to raise_error end end + + describe "using inside Celluloid::IO" do + before do + class Incrementor + include Celluloid::IO + + def initialize + @redis = Redis.new(:driver => :celluloid) + end + + def increment! + sleep(rand / 10) + @redis.incr 'rabbits' + rescue + STDERR.puts "I cannot increment rabbits because of #{$!.inspect}!" + raise RuntimeError + end + end + end + + let(:actor) { + Incrementor.new + } + let(:count) { 1000 } + + it "just survives" do + redis = Redis.new + redis.set 'rabbits', 0 + + count.times do + actor.async.increment! rescue nil + end + sleep 10 + expect(redis.get 'rabbits').to eq(count.to_s) + end + end end From c45f02a6d766858a340bdec1330a487159349359 Mon Sep 17 00:00:00 2001 From: Vladimir Kochnev Date: Fri, 21 Aug 2015 16:29:42 +0300 Subject: [PATCH 8/8] Synchronize redis operations with task-aware latch. --- lib/celluloid/redis.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/celluloid/redis.rb b/lib/celluloid/redis.rb index 4648b0e..9742289 100644 --- a/lib/celluloid/redis.rb +++ b/lib/celluloid/redis.rb @@ -1,3 +1,25 @@ require "redis" require "celluloid/redis/version" +require "celluloid/io" + +module Celluloid + class Redis < ::Redis + VERSION = CelluloidRedis::VERSION + + def initialize(*args) + super + if @options[:driver] == :celluloid + @latch = Celluloid::IO::Stream::Latch.new + end + end + + def synchronize + if @latch + @latch.synchronize { yield @client } + else + super(&proc) + end + end + end +end