kestrel-client 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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