kestrel-client 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{kestrel-client}
8
- s.version = "0.3.1"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Matt Freels", "Rael Dornfest"]
12
- s.date = %q{2010-05-18}
12
+ s.date = %q{2010-07-22}
13
13
  s.description = %q{Ruby client for the Kestrel queue server}
14
14
  s.email = %q{rael@twitter.com}
15
15
  s.extra_rdoc_files = [
@@ -30,6 +30,8 @@ Gem::Specification.new do |s|
30
30
  "lib/kestrel/client/namespace.rb",
31
31
  "lib/kestrel/client/partitioning.rb",
32
32
  "lib/kestrel/client/proxy.rb",
33
+ "lib/kestrel/client/reliable.rb",
34
+ "lib/kestrel/client/retrying.rb",
33
35
  "lib/kestrel/client/unmarshal.rb",
34
36
  "lib/kestrel/config.rb",
35
37
  "spec/kestrel/client/blocking_spec.rb",
@@ -37,6 +39,8 @@ Gem::Specification.new do |s|
37
39
  "spec/kestrel/client/json_spec.rb",
38
40
  "spec/kestrel/client/namespace_spec.rb",
39
41
  "spec/kestrel/client/partitioning_spec.rb",
42
+ "spec/kestrel/client/reliable_spec.rb",
43
+ "spec/kestrel/client/retrying_spec.rb",
40
44
  "spec/kestrel/client/unmarshal_spec.rb",
41
45
  "spec/kestrel/client_spec.rb",
42
46
  "spec/kestrel/config/kestrel.yml",
@@ -47,7 +51,7 @@ Gem::Specification.new do |s|
47
51
  s.homepage = %q{http://github.com/freels/kestrel-client}
48
52
  s.rdoc_options = ["--charset=UTF-8"]
49
53
  s.require_paths = ["lib"]
50
- s.rubygems_version = %q{1.3.6}
54
+ s.rubygems_version = %q{1.3.7}
51
55
  s.summary = %q{Ruby Kestrel client}
52
56
  s.test_files = [
53
57
  "spec/kestrel/client/blocking_spec.rb",
@@ -55,6 +59,8 @@ Gem::Specification.new do |s|
55
59
  "spec/kestrel/client/json_spec.rb",
56
60
  "spec/kestrel/client/namespace_spec.rb",
57
61
  "spec/kestrel/client/partitioning_spec.rb",
62
+ "spec/kestrel/client/reliable_spec.rb",
63
+ "spec/kestrel/client/retrying_spec.rb",
58
64
  "spec/kestrel/client/unmarshal_spec.rb",
59
65
  "spec/kestrel/client_spec.rb",
60
66
  "spec/kestrel/config_spec.rb",
@@ -65,7 +71,7 @@ Gem::Specification.new do |s|
65
71
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
72
  s.specification_version = 3
67
73
 
68
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
74
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
69
75
  s.add_runtime_dependency(%q<memcached>, [">= 0"])
70
76
  else
71
77
  s.add_dependency(%q<memcached>, [">= 0"])
@@ -7,14 +7,37 @@ module Kestrel
7
7
  autoload :Unmarshal, 'kestrel/client/unmarshal'
8
8
  autoload :Namespace, 'kestrel/client/namespace'
9
9
  autoload :Json, 'kestrel/client/json'
10
-
10
+ autoload :Reliable, "kestrel/client/reliable"
11
+ autoload :Retrying, "kestrel/client/retrying"
11
12
 
12
13
  QUEUE_STAT_NAMES = %w{items bytes total_items logsize expired_items mem_items mem_bytes age discarded}
13
14
 
15
+ # ==== Parameters
16
+ # key<String>:: Queue name
17
+ # opts<Boolean,Hash>:: True/false toggles Marshalling. A Hash
18
+ # allows collision-avoiding options support.
19
+ #
20
+ # ==== Options (opts)
21
+ # :open<Boolean>:: Begins a reliable read.
22
+ # :close<Boolean>:: Ends a reliable read.
23
+ # :abort<Boolean>:: Cancels an existing reliable read
24
+ # :peek<Boolean>:: Return the head of the queue, without removal
25
+ # :timeout<Integer>:: Milliseconds to block for a new item
26
+ # :raw<Boolean>:: Toggles Marshalling. Equivalent to the "old
27
+ # style" second argument.
28
+ #
29
+ def get(key, opts = false)
30
+ opts = extract_options(opts)
31
+ raw = opts.delete(:raw)
32
+ commands = extract_queue_commands(opts)
33
+
34
+ super key + commands, raw
35
+ end
36
+
14
37
  def flush(queue)
15
38
  count = 0
16
39
  while sizeof(queue) > 0
17
- while get(queue, true)
40
+ while get queue, :raw => true
18
41
  count += 1
19
42
  end
20
43
  end
@@ -22,9 +45,7 @@ module Kestrel
22
45
  end
23
46
 
24
47
  def peek(queue)
25
- val = get(queue)
26
- set(queue, val)
27
- val
48
+ get queue, :peek => true
28
49
  end
29
50
 
30
51
  def sizeof(queue)
@@ -46,6 +67,20 @@ module Kestrel
46
67
 
47
68
  private
48
69
 
70
+ def extract_options(opts)
71
+ opts.is_a?(Hash) ? opts : { :raw => !!opts }
72
+ end
73
+
74
+ def extract_queue_commands(opts)
75
+ commands = [:open, :close, :abort, :peek].select do |key|
76
+ opts[key]
77
+ end
78
+
79
+ commands << "t=#{opts[:timeout]}" if opts[:timeout]
80
+
81
+ commands.map { |c| "/#{c}" }.join('')
82
+ end
83
+
49
84
  def stats_for_server(server)
50
85
  server_name, port = server.split(/:/)
51
86
  socket = TCPSocket.new(server_name, port)
@@ -1,31 +1,22 @@
1
1
  module Kestrel
2
2
  class Client
3
3
  class Blocking < Proxy
4
- DEFAULT_EXPIRY = 0
5
- WAIT_TIME_BEFORE_RETRY = 0.25
4
+ DEFAULT_TIMEOUT = 1000
6
5
 
7
- def get(*args)
8
- while !(response = client.get(*args))
9
- sleep WAIT_TIME_BEFORE_RETRY
6
+ def get(key, opts = false)
7
+ opts = extract_options(opts)
8
+ opts[:timeout] = DEFAULT_TIMEOUT
9
+
10
+ loop do
11
+ response = client.get(key, opts)
12
+ return response if response
10
13
  end
11
- response
12
14
  end
13
15
 
14
16
  def get_without_blocking(*args)
15
17
  client.get(*args)
16
18
  end
17
19
 
18
- def set(key, value, expiry = DEFAULT_EXPIRY, raw = false)
19
- @retried = false
20
- begin
21
- client.set(key, value, expiry, raw)
22
- rescue Memcached::Error => e
23
- raise if @retried
24
- sleep(WAIT_TIME_BEFORE_RETRY)
25
- @retried = true
26
- retry
27
- end
28
- end
29
20
  end
30
21
  end
31
22
  end
@@ -0,0 +1,65 @@
1
+ module Kestrel
2
+ class Client
3
+ class Reliable < Proxy
4
+
5
+ # Number of times to retry a job before giving up
6
+ DEFAULT_RETRIES = 100
7
+
8
+ # Pct. of the time during 'normal' processing we check the error queue first
9
+ ERROR_PROCESSING_RATE = 0.1
10
+
11
+ # Returns job from the +key+ queue 1 - ERROR_PROCESSING_RATE
12
+ # pct. of the time. Every so often, checks the error queue for
13
+ # jobs and returns a retryable job. If either the error queue or
14
+ # +key+ queue are empty, attempts to pull a job from the
15
+ # alternate queue before giving up.
16
+ #
17
+ # ==== Returns
18
+ # Job, possibly retryable, or nil
19
+ #
20
+ def get(key, opts = false)
21
+ opts = extract_options(opts)
22
+ opts.merge! :close => true, :open => true
23
+
24
+ job =
25
+ if rand < ERROR_PROCESSING_RATE
26
+ client.get(key + "_errors", opts) || client.get(key, opts)
27
+ else
28
+ client.get(key, opts) || client.get(key + "_errors", opts)
29
+ end
30
+
31
+ if job
32
+ @key = key
33
+ @job = job.is_a?(RetryableJob) ? job : RetryableJob.new(0, job)
34
+ @job.job
35
+ else
36
+ @key = @job = nil
37
+ end
38
+ end
39
+
40
+ def current_try
41
+ @job ? @job.retries + 1 : 1
42
+ end
43
+
44
+ # Enqueues the current job on the error queue for later
45
+ # retry. If the job has been retried DEFAULT_RETRIES times,
46
+ # gives up entirely.
47
+ #
48
+ # ==== Returns
49
+ # Boolean:: true if the job is retryable, false otherwise
50
+ #
51
+ def retry
52
+ @job.retries += 1
53
+ if @job.retries < DEFAULT_RETRIES
54
+ client.set(@key + "_errors", @job)
55
+ true
56
+ else
57
+ false
58
+ end
59
+ end
60
+
61
+ class RetryableJob < Struct.new(:retries, :job)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,51 @@
1
+ module Kestrel
2
+ class Client
3
+ class Retrying < Proxy
4
+
5
+ # Number of times to retry after connection failures
6
+ DEFAULT_RETRY_COUNT = 5
7
+
8
+ # Exceptions which are connection failures we retry after
9
+ RECOVERABLE_ERRORS = [
10
+ Memcached::ServerIsMarkedDead,
11
+ Memcached::ATimeoutOccurred,
12
+ Memcached::ConnectionBindFailure,
13
+ Memcached::ConnectionFailure,
14
+ Memcached::ConnectionSocketCreateFailure,
15
+ Memcached::Failure,
16
+ Memcached::MemoryAllocationFailure,
17
+ Memcached::ReadFailure,
18
+ Memcached::ServerError,
19
+ Memcached::SystemError,
20
+ Memcached::UnknownReadFailure,
21
+ Memcached::WriteFailure
22
+ ]
23
+
24
+ def initialize(client, retry_count = nil)
25
+ @retry_count = retry_count || DEFAULT_RETRY_COUNT
26
+ super(client)
27
+ end
28
+
29
+ %w(set get delete).each do |method|
30
+ class_eval "def #{method}(*args); retry_call(#{method.inspect}, *args) end", __FILE__, __LINE__
31
+ end
32
+
33
+ private
34
+
35
+ def retry_call(method, *args) #:nodoc:
36
+ begin
37
+ tries ||= 0
38
+ client.send(method, *args)
39
+ rescue *RECOVERABLE_ERRORS
40
+ if tries < @retry_count
41
+ tries += 1
42
+ retry
43
+ else
44
+ raise
45
+ end
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec/spec_helper'
2
2
 
3
3
  describe "Kestrel::Client::Blocking" do
4
4
  describe "Instance Methods" do
@@ -7,62 +7,21 @@ describe "Kestrel::Client::Blocking" do
7
7
  @kestrel = Kestrel::Client::Blocking.new(@raw_kestrel_client)
8
8
  end
9
9
 
10
- describe "#set" do
11
- before do
12
- @queue = "some_queue"
13
- @value = "some_value"
14
- end
15
-
16
- it "blocks on a set until the set works" do
17
- @queue = "some_queue"
18
- @value = "some_value"
19
- mock(@raw_kestrel_client)\
20
- .set(@queue, @value, anything, anything) { raise Memcached::Error }.then\
21
- .set(@queue, @value, anything, anything) { :mcguffin }
22
- mock(@kestrel).sleep(Kestrel::Client::Blocking::WAIT_TIME_BEFORE_RETRY).once
23
- @kestrel.set(@queue, @value).should == :mcguffin
24
- end
25
-
26
- it "raises if two sets in a row fail" do
27
- mock(@raw_kestrel_client)\
28
- .set(@queue, @value, anything, anything) { raise Memcached::Error }.then\
29
- .set(@queue, @value, anything, anything) { raise Memcached::Error }
30
- mock(@kestrel).sleep(Kestrel::Client::Blocking::WAIT_TIME_BEFORE_RETRY).once
31
- lambda { @kestrel.set(@queue, @value) }.should raise_error(Memcached::Error)
32
- end
33
-
34
- it "passes along the default expiry time if none is given" do
35
- @queue = "some_queue"
36
- @value = "some_value"
37
- mock(@raw_kestrel_client).set(@queue, @value, Kestrel::Client::Blocking::DEFAULT_EXPIRY, anything)
38
- @kestrel.set(@queue, @value)
39
- end
40
-
41
- it "passes along the given expiry time if one is passed in" do
42
- @queue = "some_queue"
43
- @value = "some_value"
44
- mock(@raw_kestrel_client).set(@queue, @value, 60, anything)
45
- @kestrel.set(@queue, @value, 60)
46
- end
47
- end
48
-
49
10
  describe "#get" do
50
11
  before do
51
12
  @queue = "some_queue"
52
13
  end
53
14
 
54
15
  it "blocks on a get until the get works" do
55
- mock(@raw_kestrel_client)\
56
- .get(@queue) { nil }.then\
57
- .get(@queue) { :mcguffin }
58
- mock(@kestrel).sleep(Kestrel::Client::Blocking::WAIT_TIME_BEFORE_RETRY).once
16
+ mock(@raw_kestrel_client).
17
+ get(@queue, :raw => false, :timeout => Kestrel::Client::Blocking::DEFAULT_TIMEOUT) { nil }.then.
18
+ get(@queue, :raw => false, :timeout => Kestrel::Client::Blocking::DEFAULT_TIMEOUT) { :mcguffin }
59
19
  @kestrel.get(@queue).should == :mcguffin
60
20
  end
61
21
 
62
22
  describe "#get_without_blocking" do
63
23
  it "does not block" do
64
24
  mock(@raw_kestrel_client).get(@queue) { nil }
65
- mock(@kestrel).sleep(Kestrel::Client::Blocking::WAIT_TIME_BEFORE_RETRY).never
66
25
  @kestrel.get_without_blocking(@queue).should be_nil
67
26
  end
68
27
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec/spec_helper'
2
2
 
3
3
  class Envelope; end
4
4
 
@@ -1,6 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- require 'kestrel/client/json'
1
+ require 'spec/spec_helper'
4
2
 
5
3
  describe Kestrel::Client::Json do
6
4
  describe "Instance Methods" do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec/spec_helper'
2
2
 
3
3
  describe Kestrel::Client::Namespace do
4
4
  describe "Instance Methods" do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec/spec_helper'
2
2
 
3
3
  describe Kestrel::Client::Partitioning do
4
4
  before do
@@ -0,0 +1,130 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe "Kestrel::Client::Reliable" do
4
+ describe "Instance Methods" do
5
+ before do
6
+ @raw_kestrel_client = Kestrel::Client.new(*Kestrel::Config.default)
7
+ @kestrel = Kestrel::Client::Reliable.new(@raw_kestrel_client)
8
+ stub(@kestrel).rand { 1 }
9
+ @queue = "some_queue"
10
+ end
11
+
12
+ describe "#get" do
13
+
14
+ it "asks for a transaction" do
15
+ mock(@raw_kestrel_client).get(@queue, :raw => false, :open => true, :close => true) { :mcguffin }
16
+ @kestrel.get(@queue).should == :mcguffin
17
+ end
18
+
19
+ it "gets from the error queue ERROR_PROCESSING_RATE pct. of the time" do
20
+ mock(@kestrel).rand { Kestrel::Client::Reliable::ERROR_PROCESSING_RATE - 0.05 }
21
+ mock(@raw_kestrel_client).get(@queue + "_errors", anything) { :mcguffin }
22
+ mock(@raw_kestrel_client).get(@queue, anything).never
23
+ @kestrel.get(@queue).should == :mcguffin
24
+ end
25
+
26
+ it "falls through to the normal queue when error queue is empty" do
27
+ mock(@kestrel).rand { Kestrel::Client::Reliable::ERROR_PROCESSING_RATE - 0.05 }
28
+ mock(@raw_kestrel_client).get(@queue + "_errors", anything) { nil }
29
+ mock(@raw_kestrel_client).get(@queue, anything) { :mcguffin }
30
+ @kestrel.get(@queue).should == :mcguffin
31
+ end
32
+
33
+ it "gets from the normal queue most of the time" do
34
+ mock(@kestrel).rand { Kestrel::Client::Reliable::ERROR_PROCESSING_RATE + 0.05 }
35
+ mock(@raw_kestrel_client).get(@queue, anything) { :mcguffin }
36
+ mock(@raw_kestrel_client).get(@queue + "_errors", anything).never
37
+ @kestrel.get(@queue).should == :mcguffin
38
+ end
39
+
40
+ it "falls through to the error queue when normal queue is empty" do
41
+ mock(@kestrel).rand { Kestrel::Client::Reliable::ERROR_PROCESSING_RATE + 0.05 }
42
+ mock(@raw_kestrel_client).get(@queue, anything) { nil }
43
+ mock(@raw_kestrel_client).get(@queue + "_errors", anything) { :mcguffin }
44
+ @kestrel.get(@queue).should == :mcguffin
45
+ end
46
+
47
+ it "is nil when both queues are empty" do
48
+ mock(@kestrel).rand { Kestrel::Client::Reliable::ERROR_PROCESSING_RATE + 0.05 }
49
+ mock(@raw_kestrel_client).get(@queue, anything) { nil }
50
+ mock(@raw_kestrel_client).get(@queue + "_errors", anything) { nil }
51
+ @kestrel.get(@queue).should be_nil
52
+ end
53
+
54
+ it "returns the payload of a RetryableJob" do
55
+ stub(@kestrel).rand { 0 }
56
+ mock(@raw_kestrel_client).get(@queue + "_errors", anything) do
57
+ Kestrel::Client::Reliable::RetryableJob.new(1, :mcmuffin)
58
+ end
59
+
60
+ @kestrel.get(@queue).should == :mcmuffin
61
+ @kestrel.current_try.should == 2
62
+ end
63
+
64
+ end
65
+
66
+ describe "#current_try" do
67
+
68
+ it "returns 1 if nothing has been gotten" do
69
+ @kestrel.current_try.should == 1
70
+ end
71
+
72
+ it "returns 1 for jobs that have not been retried" do
73
+ mock(@raw_kestrel_client).get(@queue, anything) { :mcguffin }
74
+ @kestrel.get(@queue)
75
+ @kestrel.current_try.should == 1
76
+ end
77
+
78
+ it "returns 1 plus the number of tries for a RetryableJob" do
79
+ stub(@kestrel).rand { 0 }
80
+ mock(@raw_kestrel_client).get(@queue + "_errors", anything) do
81
+ Kestrel::Client::Reliable::RetryableJob.new(1, :mcmuffin)
82
+ end
83
+ @kestrel.get(@queue)
84
+ @kestrel.current_try.should == 2
85
+ end
86
+
87
+ end
88
+
89
+ describe "#retry" do
90
+ before do
91
+ stub(@raw_kestrel_client).get(@queue, anything) { :mcmuffin }
92
+ @kestrel.get(@queue)
93
+ end
94
+
95
+ it "enqueues a fresh failed job to the errors queue with a retry count" do
96
+ mock(@raw_kestrel_client).set(@queue + "_errors", anything) do |queue, job|
97
+ job.retries.should == 1
98
+ job.job.should == :mcmuffin
99
+ end
100
+ @kestrel.retry.should be_true
101
+ end
102
+
103
+ it "increments the retry count and re-enqueues the retried job" do
104
+ stub(@kestrel).rand { 0 }
105
+ stub(@raw_kestrel_client).get(@queue + "_errors", anything) do
106
+ Kestrel::Client::Reliable::RetryableJob.new(1, :mcmuffin)
107
+ end
108
+
109
+ mock(@raw_kestrel_client).set(@queue + "_errors", anything) do |queue, job|
110
+ job.retries.should == 2
111
+ job.job.should == :mcmuffin
112
+ end
113
+
114
+ @kestrel.get(@queue)
115
+ @kestrel.retry.should be_true
116
+ end
117
+
118
+ it "does not enqueue the retried job after too many tries" do
119
+ stub(@kestrel).rand { 0 }
120
+ stub(@raw_kestrel_client).get(@queue + "_errors", anything) do
121
+ Kestrel::Client::Reliable::RetryableJob.new(Kestrel::Client::Reliable::DEFAULT_RETRIES - 1, :mcmuffin)
122
+ end
123
+ mock(@raw_kestrel_client).set(@queue + "_errors", anything).never
124
+ @kestrel.get(@queue)
125
+ @kestrel.retry.should be_false
126
+ end
127
+
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Kestrel::Client::Retrying do
4
+ before do
5
+ @raw_kestrel_client = Kestrel::Client.new(*Kestrel::Config.default)
6
+ @kestrel = Kestrel::Client::Retrying.new(@raw_kestrel_client)
7
+ @queue = "some_queue"
8
+ end
9
+
10
+ it "does not retry if no exception is raised" do
11
+ mock(@raw_kestrel_client).get(@queue) { :mcguffin }
12
+ lambda do
13
+ @kestrel.get(@queue).should == :mcguffin
14
+ end.should_not raise_error
15
+ end
16
+
17
+ ['get', 'set', 'delete'].each do |operation|
18
+ it "retries DEFAULT_RETRY_COUNT times then fails" do
19
+ mock(@raw_kestrel_client).send(operation, @queue) { raise Memcached::ServerIsMarkedDead }.
20
+ times(Kestrel::Client::Retrying::DEFAULT_RETRY_COUNT + 1)
21
+
22
+ lambda do
23
+ @kestrel.send(operation, @queue)
24
+ end.should raise_error(Memcached::ServerIsMarkedDead)
25
+ end
26
+
27
+ it "does not retry on non-connection related exceptions" do
28
+ [Memcached::ABadKeyWasProvidedOrCharactersOutOfRange,
29
+ Memcached::ActionQueued,
30
+ Memcached::NoServersDefined].each do |ex|
31
+
32
+ mock(@raw_kestrel_client).send(operation, @queue) { raise ex }
33
+ lambda { @kestrel.send(operation, @queue) }.should raise_error(ex)
34
+
35
+ end
36
+ end
37
+
38
+ it "does not retry when retry count is 0" do
39
+ kestrel = Kestrel::Client::Retrying.new(@raw_kestrel_client, 0)
40
+ mock(@raw_kestrel_client).send(operation, @queue) { raise Memcached::ServerIsMarkedDead }
41
+ lambda { kestrel.send(operation, @queue) }.should raise_error(Memcached::ServerIsMarkedDead)
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec/spec_helper'
2
2
 
3
3
  describe Kestrel::Client::Unmarshal do
4
4
  describe "Instance Methods" do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec/spec_helper'
2
2
 
3
3
  describe Kestrel::Client do
4
4
  describe "Instance Methods" do
@@ -1,7 +1,7 @@
1
1
  defaults: &defaults
2
2
  distribution: :random
3
- timeout: 10
4
- connect_timeout: 2
3
+ timeout: 0.1
4
+ connect_timeout: 0.5
5
5
  server_failure_limit: 10
6
6
  auto_eject_hosts: false
7
7
 
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec/spec_helper'
2
2
 
3
3
  describe Kestrel::Config do
4
4
  before do
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kestrel-client
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 15
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 3
8
- - 1
9
- version: 0.3.1
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Matt Freels
@@ -15,16 +16,18 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-05-18 00:00:00 -07:00
19
+ date: 2010-07-22 00:00:00 -07:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
22
23
  name: memcached
23
24
  prerelease: false
24
25
  requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
25
27
  requirements:
26
28
  - - ">="
27
29
  - !ruby/object:Gem::Version
30
+ hash: 3
28
31
  segments:
29
32
  - 0
30
33
  version: "0"
@@ -53,6 +56,8 @@ files:
53
56
  - lib/kestrel/client/namespace.rb
54
57
  - lib/kestrel/client/partitioning.rb
55
58
  - lib/kestrel/client/proxy.rb
59
+ - lib/kestrel/client/reliable.rb
60
+ - lib/kestrel/client/retrying.rb
56
61
  - lib/kestrel/client/unmarshal.rb
57
62
  - lib/kestrel/config.rb
58
63
  - spec/kestrel/client/blocking_spec.rb
@@ -60,6 +65,8 @@ files:
60
65
  - spec/kestrel/client/json_spec.rb
61
66
  - spec/kestrel/client/namespace_spec.rb
62
67
  - spec/kestrel/client/partitioning_spec.rb
68
+ - spec/kestrel/client/reliable_spec.rb
69
+ - spec/kestrel/client/retrying_spec.rb
63
70
  - spec/kestrel/client/unmarshal_spec.rb
64
71
  - spec/kestrel/client_spec.rb
65
72
  - spec/kestrel/config/kestrel.yml
@@ -76,23 +83,27 @@ rdoc_options:
76
83
  require_paths:
77
84
  - lib
78
85
  required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
79
87
  requirements:
80
88
  - - ">="
81
89
  - !ruby/object:Gem::Version
90
+ hash: 3
82
91
  segments:
83
92
  - 0
84
93
  version: "0"
85
94
  required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
86
96
  requirements:
87
97
  - - ">="
88
98
  - !ruby/object:Gem::Version
99
+ hash: 3
89
100
  segments:
90
101
  - 0
91
102
  version: "0"
92
103
  requirements: []
93
104
 
94
105
  rubyforge_project:
95
- rubygems_version: 1.3.6
106
+ rubygems_version: 1.3.7
96
107
  signing_key:
97
108
  specification_version: 3
98
109
  summary: Ruby Kestrel client
@@ -102,6 +113,8 @@ test_files:
102
113
  - spec/kestrel/client/json_spec.rb
103
114
  - spec/kestrel/client/namespace_spec.rb
104
115
  - spec/kestrel/client/partitioning_spec.rb
116
+ - spec/kestrel/client/reliable_spec.rb
117
+ - spec/kestrel/client/retrying_spec.rb
105
118
  - spec/kestrel/client/unmarshal_spec.rb
106
119
  - spec/kestrel/client_spec.rb
107
120
  - spec/kestrel/config_spec.rb