chimera 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +57 -0
- data/PostInstall.txt +7 -0
- data/README.rdoc +114 -0
- data/Rakefile +30 -0
- data/doc/NOTES +11 -0
- data/doc/examples/config.yml +16 -0
- data/doc/redis6379.conf +132 -0
- data/lib/chimera.rb +33 -0
- data/lib/chimera/associations.rb +146 -0
- data/lib/chimera/attributes.rb +52 -0
- data/lib/chimera/base.rb +95 -0
- data/lib/chimera/config.rb +9 -0
- data/lib/chimera/error.rb +12 -0
- data/lib/chimera/finders.rb +49 -0
- data/lib/chimera/geo_indexes.rb +76 -0
- data/lib/chimera/indexes.rb +177 -0
- data/lib/chimera/persistence.rb +70 -0
- data/lib/chimera/redis_objects.rb +345 -0
- data/lib/redis.rb +373 -0
- data/lib/redis/counter.rb +94 -0
- data/lib/redis/dist_redis.rb +149 -0
- data/lib/redis/hash_ring.rb +135 -0
- data/lib/redis/helpers/core_commands.rb +46 -0
- data/lib/redis/helpers/serialize.rb +25 -0
- data/lib/redis/list.rb +122 -0
- data/lib/redis/lock.rb +83 -0
- data/lib/redis/objects.rb +100 -0
- data/lib/redis/objects/counters.rb +132 -0
- data/lib/redis/objects/lists.rb +45 -0
- data/lib/redis/objects/locks.rb +71 -0
- data/lib/redis/objects/sets.rb +46 -0
- data/lib/redis/objects/values.rb +56 -0
- data/lib/redis/pipeline.rb +21 -0
- data/lib/redis/set.rb +156 -0
- data/lib/redis/value.rb +35 -0
- data/lib/riak_raw.rb +100 -0
- data/lib/typhoeus.rb +55 -0
- data/lib/typhoeus/.gitignore +1 -0
- data/lib/typhoeus/easy.rb +253 -0
- data/lib/typhoeus/filter.rb +28 -0
- data/lib/typhoeus/hydra.rb +210 -0
- data/lib/typhoeus/multi.rb +34 -0
- data/lib/typhoeus/remote.rb +306 -0
- data/lib/typhoeus/remote_method.rb +108 -0
- data/lib/typhoeus/remote_proxy_object.rb +48 -0
- data/lib/typhoeus/request.rb +124 -0
- data/lib/typhoeus/response.rb +39 -0
- data/lib/typhoeus/service.rb +20 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/test/models.rb +49 -0
- data/test/test_chimera.rb +238 -0
- data/test/test_helper.rb +7 -0
- metadata +243 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
# This is the class loader, for use as "include Redis::Objects::Locks"
|
2
|
+
# For the object itself, see "Redis::Lock"
|
3
|
+
require 'redis/lock'
|
4
|
+
class Redis
|
5
|
+
module Objects
|
6
|
+
class UndefinedLock < StandardError; end #:nodoc:
|
7
|
+
module Locks
|
8
|
+
def self.included(klass)
|
9
|
+
klass.send :include, InstanceMethods
|
10
|
+
klass.extend ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
# Class methods that appear in your class when you include Redis::Objects.
|
14
|
+
module ClassMethods
|
15
|
+
# Define a new lock. It will function like a model attribute,
|
16
|
+
# so it can be used alongside ActiveRecord/DataMapper, etc.
|
17
|
+
def lock(name, options={})
|
18
|
+
options[:timeout] ||= 5 # seconds
|
19
|
+
options[:init] = false if options[:init].nil? # default :init to false
|
20
|
+
@redis_objects[name] = options.merge(:type => :lock)
|
21
|
+
if options[:global]
|
22
|
+
instance_eval <<-EndMethods
|
23
|
+
def #{name}_lock(&block)
|
24
|
+
@#{name} ||= Redis::Lock.new(field_key(:#{name}_lock, ''), redis, @redis_objects[:#{name}])
|
25
|
+
end
|
26
|
+
EndMethods
|
27
|
+
class_eval <<-EndMethods
|
28
|
+
def #{name}_lock(&block)
|
29
|
+
self.class.#{name}(block)
|
30
|
+
end
|
31
|
+
EndMethods
|
32
|
+
else
|
33
|
+
class_eval <<-EndMethods
|
34
|
+
def #{name}_lock(&block)
|
35
|
+
raise(ActiveRedis::Errors::NotSavedError) if self.new?
|
36
|
+
@#{name} ||= Redis::Lock.new(field_key(:#{name}_lock), redis, self.class.redis_objects[:#{name}])
|
37
|
+
end
|
38
|
+
EndMethods
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
# Obtain a lock, and execute the block synchronously. Any other code
|
46
|
+
# (on any server) will spin waiting for the lock up to the :timeout
|
47
|
+
# that was specified when the lock was defined.
|
48
|
+
def obtain_lock(name, id, &block)
|
49
|
+
verify_lock_defined!(name)
|
50
|
+
raise ArgumentError, "Missing block to #{self.name}.obtain_lock" unless block_given?
|
51
|
+
lock_name = field_key("#{name}_lock", id)
|
52
|
+
Redis::Lock.new(lock_name, redis, self.redis_objects[name]).lock(&block)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Clear the lock. Use with care - usually only in an Admin page to clear
|
56
|
+
# stale locks (a stale lock should only happen if a server crashes.)
|
57
|
+
def clear_lock(name, id)
|
58
|
+
verify_lock_defined!(name)
|
59
|
+
lock_name = field_key("#{name}_lock", id)
|
60
|
+
redis.del(lock_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def verify_lock_defined!(name)
|
66
|
+
raise Redis::Objects::UndefinedLock, "Undefined lock :#{name} for class #{self.name}" unless @redis_objects.has_key?(name)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# This is the class loader, for use as "include Redis::Objects::Sets"
|
2
|
+
# For the object itself, see "Redis::Set"
|
3
|
+
require 'redis/set'
|
4
|
+
class Redis
|
5
|
+
module Objects
|
6
|
+
module Sets
|
7
|
+
def self.included(klass)
|
8
|
+
klass.send :include, InstanceMethods
|
9
|
+
klass.extend ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
# Class methods that appear in your class when you include Redis::Objects.
|
13
|
+
module ClassMethods
|
14
|
+
# Define a new list. It will function like a regular instance
|
15
|
+
# method, so it can be used alongside ActiveRecord, DataMapper, etc.
|
16
|
+
def set(name, options={})
|
17
|
+
@redis_objects[name] = options.merge(:type => :set)
|
18
|
+
if options[:global]
|
19
|
+
instance_eval <<-EndMethods
|
20
|
+
def #{name}
|
21
|
+
@#{name} ||= Redis::Set.new(field_key(:#{name}, ''), redis, @redis_objects[:#{name}])
|
22
|
+
end
|
23
|
+
EndMethods
|
24
|
+
class_eval <<-EndMethods
|
25
|
+
def #{name}
|
26
|
+
self.class.#{name}
|
27
|
+
end
|
28
|
+
EndMethods
|
29
|
+
else
|
30
|
+
class_eval <<-EndMethods
|
31
|
+
def #{name}
|
32
|
+
raise(ActiveRedis::Errors::NotSavedError) if self.new?
|
33
|
+
@#{name} ||= Redis::Set.new(field_key(:#{name}), redis, self.class.redis_objects[:#{name}])
|
34
|
+
end
|
35
|
+
EndMethods
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Instance methods that appear in your class when you include Redis::Objects.
|
42
|
+
module InstanceMethods
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# This is the class loader, for use as "include Redis::Objects::Values"
|
2
|
+
# For the object itself, see "Redis::Value"
|
3
|
+
require 'redis/value'
|
4
|
+
class Redis
|
5
|
+
module Objects
|
6
|
+
module Values
|
7
|
+
def self.included(klass)
|
8
|
+
klass.send :include, InstanceMethods
|
9
|
+
klass.extend ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
# Class methods that appear in your class when you include Redis::Objects.
|
13
|
+
module ClassMethods
|
14
|
+
# Define a new simple value. It will function like a regular instance
|
15
|
+
# method, so it can be used alongside ActiveRecord, DataMapper, etc.
|
16
|
+
def value(name, options={})
|
17
|
+
@redis_objects[name] = options.merge(:type => :value)
|
18
|
+
if options[:global]
|
19
|
+
instance_eval <<-EndMethods
|
20
|
+
def #{name}
|
21
|
+
@#{name} ||= Redis::Value.new(field_key(:#{name}, ''), redis, @redis_objects[:#{name}])
|
22
|
+
end
|
23
|
+
def #{name}=(value)
|
24
|
+
#{name}.value = value
|
25
|
+
end
|
26
|
+
EndMethods
|
27
|
+
class_eval <<-EndMethods
|
28
|
+
def #{name}
|
29
|
+
self.class.#{name}
|
30
|
+
end
|
31
|
+
def #{name}=(value)
|
32
|
+
self.class.#{name} = value
|
33
|
+
end
|
34
|
+
EndMethods
|
35
|
+
else
|
36
|
+
class_eval <<-EndMethods
|
37
|
+
def #{name}
|
38
|
+
raise(ActiveRedis::Errors::NotSavedError) if self.new?
|
39
|
+
@#{name} ||= Redis::Value.new(field_key(:#{name}), redis, self.class.redis_objects[:#{name}])
|
40
|
+
end
|
41
|
+
def #{name}=(value)
|
42
|
+
raise(ActiveRedis::Errors::NotSavedError) if self.new?
|
43
|
+
#{name}.value = value
|
44
|
+
end
|
45
|
+
EndMethods
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Instance methods that appear in your class when you include Redis::Objects.
|
52
|
+
module InstanceMethods
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Redis
|
2
|
+
class Pipeline < Redis
|
3
|
+
BUFFER_SIZE = 50_000
|
4
|
+
|
5
|
+
def initialize(redis)
|
6
|
+
@redis = redis
|
7
|
+
@commands = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def call_command(command)
|
11
|
+
@commands << command
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
return if @commands.empty?
|
16
|
+
@redis.call_command(@commands)
|
17
|
+
@commands.clear
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/redis/set.rb
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
class Redis
|
2
|
+
#
|
3
|
+
# Class representing a set.
|
4
|
+
#
|
5
|
+
class Set
|
6
|
+
require 'enumerator'
|
7
|
+
include Enumerable
|
8
|
+
require 'redis/helpers/core_commands'
|
9
|
+
include Redis::Helpers::CoreCommands
|
10
|
+
require 'redis/helpers/serialize'
|
11
|
+
include Redis::Helpers::Serialize
|
12
|
+
|
13
|
+
attr_reader :key, :options, :redis
|
14
|
+
|
15
|
+
# Create a new Set.
|
16
|
+
def initialize(key, redis=$redis, options={})
|
17
|
+
@key = key
|
18
|
+
@redis = redis
|
19
|
+
@options = options
|
20
|
+
end
|
21
|
+
|
22
|
+
# Works like add. Can chain together: list << 'a' << 'b'
|
23
|
+
def <<(value)
|
24
|
+
add(value)
|
25
|
+
self # for << 'a' << 'b'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add the specified value to the set only if it does not exist already.
|
29
|
+
# Redis: SADD
|
30
|
+
def add(value)
|
31
|
+
redis.sadd(key, to_redis(value))
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return all members in the set. Redis: SMEMBERS
|
35
|
+
def members
|
36
|
+
from_redis redis.smembers(key)
|
37
|
+
end
|
38
|
+
alias_method :get, :members
|
39
|
+
|
40
|
+
# Returns true if the specified value is in the set. Redis: SISMEMBER
|
41
|
+
def member?(value)
|
42
|
+
redis.sismember(key, to_redis(value))
|
43
|
+
end
|
44
|
+
alias_method :include?, :member?
|
45
|
+
|
46
|
+
# Delete the value from the set. Redis: SREM
|
47
|
+
def delete(value)
|
48
|
+
redis.srem(key, value)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Iterate through each member of the set. Redis::Objects mixes in Enumerable,
|
52
|
+
# so you can also use familiar methods like +collect+, +detect+, and so forth.
|
53
|
+
def each(&block)
|
54
|
+
members.each(&block)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return the intersection with another set. Can pass it either another set
|
58
|
+
# object or set name. Also available as & which is a bit cleaner:
|
59
|
+
#
|
60
|
+
# members_in_both = set1 & set2
|
61
|
+
#
|
62
|
+
# If you want to specify multiple sets, you must use +intersection+:
|
63
|
+
#
|
64
|
+
# members_in_all = set1.intersection(set2, set3, set4)
|
65
|
+
# members_in_all = set1.inter(set2, set3, set4) # alias
|
66
|
+
#
|
67
|
+
# Redis: SINTER
|
68
|
+
def intersection(*sets)
|
69
|
+
from_redis redis.sinter(key, *keys_from_objects(sets))
|
70
|
+
end
|
71
|
+
alias_method :intersect, :intersection
|
72
|
+
alias_method :inter, :intersection
|
73
|
+
alias_method :&, :intersection
|
74
|
+
|
75
|
+
# Calculate the intersection and store it in Redis as +name+. Returns the number
|
76
|
+
# of elements in the stored intersection. Redis: SUNIONSTORE
|
77
|
+
def interstore(name, *sets)
|
78
|
+
redis.sinterstore(name, key, *keys_from_objects(sets))
|
79
|
+
end
|
80
|
+
|
81
|
+
# Return the union with another set. Can pass it either another set
|
82
|
+
# object or set name. Also available as | and + which are a bit cleaner:
|
83
|
+
#
|
84
|
+
# members_in_either = set1 | set2
|
85
|
+
# members_in_either = set1 + set2
|
86
|
+
#
|
87
|
+
# If you want to specify multiple sets, you must use +union+:
|
88
|
+
#
|
89
|
+
# members_in_all = set1.union(set2, set3, set4)
|
90
|
+
#
|
91
|
+
# Redis: SUNION
|
92
|
+
def union(*sets)
|
93
|
+
from_redis redis.sunion(key, *keys_from_objects(sets))
|
94
|
+
end
|
95
|
+
alias_method :|, :union
|
96
|
+
alias_method :+, :union
|
97
|
+
|
98
|
+
# Calculate the union and store it in Redis as +name+. Returns the number
|
99
|
+
# of elements in the stored union. Redis: SUNIONSTORE
|
100
|
+
def unionstore(name, *sets)
|
101
|
+
redis.sunionstore(name, key, *keys_from_objects(sets))
|
102
|
+
end
|
103
|
+
|
104
|
+
# Return the difference vs another set. Can pass it either another set
|
105
|
+
# object or set name. Also available as ^ or - which is a bit cleaner:
|
106
|
+
#
|
107
|
+
# members_difference = set1 ^ set2
|
108
|
+
# members_difference = set1 - set2
|
109
|
+
#
|
110
|
+
# If you want to specify multiple sets, you must use +difference+:
|
111
|
+
#
|
112
|
+
# members_difference = set1.difference(set2, set3, set4)
|
113
|
+
# members_difference = set1.diff(set2, set3, set4)
|
114
|
+
#
|
115
|
+
# Redis: SDIFF
|
116
|
+
def difference(*sets)
|
117
|
+
from_redis redis.sdiff(key, *keys_from_objects(sets))
|
118
|
+
end
|
119
|
+
alias_method :diff, :difference
|
120
|
+
alias_method :^, :difference
|
121
|
+
alias_method :-, :difference
|
122
|
+
|
123
|
+
# Calculate the diff and store it in Redis as +name+. Returns the number
|
124
|
+
# of elements in the stored union. Redis: SDIFFSTORE
|
125
|
+
def diffstore(name, *sets)
|
126
|
+
redis.sdiffstore(name, key, *keys_from_objects(sets))
|
127
|
+
end
|
128
|
+
|
129
|
+
# The number of members in the set. Aliased as size. Redis: SCARD
|
130
|
+
def length
|
131
|
+
redis.scard(key)
|
132
|
+
end
|
133
|
+
alias_method :size, :length
|
134
|
+
|
135
|
+
# Returns true if the set has no members. Redis: SCARD == 0
|
136
|
+
def empty?
|
137
|
+
length == 0
|
138
|
+
end
|
139
|
+
|
140
|
+
def ==(x)
|
141
|
+
members == x
|
142
|
+
end
|
143
|
+
|
144
|
+
def to_s
|
145
|
+
members.join(', ')
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def keys_from_objects(sets)
|
151
|
+
raise ArgumentError, "Must pass in one or more set names" if sets.empty?
|
152
|
+
sets.collect{|set| set.is_a?(Redis::Set) ? set.key : set}
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
data/lib/redis/value.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
class Redis
|
2
|
+
#
|
3
|
+
# Class representing a simple value. You can use standard Ruby operations on it.
|
4
|
+
#
|
5
|
+
class Value
|
6
|
+
require 'redis/helpers/core_commands'
|
7
|
+
include Redis::Helpers::CoreCommands
|
8
|
+
require 'redis/helpers/serialize'
|
9
|
+
include Redis::Helpers::Serialize
|
10
|
+
|
11
|
+
attr_reader :key, :options, :redis
|
12
|
+
def initialize(key, redis=$redis, options={})
|
13
|
+
@key = key
|
14
|
+
@redis = redis
|
15
|
+
@options = options
|
16
|
+
@redis.setnx(key, @options[:default]) if @options[:default]
|
17
|
+
end
|
18
|
+
|
19
|
+
def value=(val)
|
20
|
+
redis.set key, to_redis(val)
|
21
|
+
end
|
22
|
+
alias_method :set, :value=
|
23
|
+
|
24
|
+
def value
|
25
|
+
from_redis redis.get(key)
|
26
|
+
end
|
27
|
+
alias_method :get, :value
|
28
|
+
|
29
|
+
def to_s; value.to_s; end
|
30
|
+
alias_method :to_str, :to_s
|
31
|
+
|
32
|
+
def ==(x); value == x; end
|
33
|
+
def nil?; value.nil?; end
|
34
|
+
end
|
35
|
+
end
|
data/lib/riak_raw.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# gem "typhoeus", "= 0.1.18"
|
2
|
+
# gem "uuidtools", "= 2.1.1"
|
3
|
+
# gem "brianmario-yajl-ruby", "= 0.6.3"
|
4
|
+
# require "typhoeus"
|
5
|
+
# require "uuidtools"
|
6
|
+
# require "uri"
|
7
|
+
# require "yajl"
|
8
|
+
|
9
|
+
# A Ruby interface for the Riak (http://riak.basho.com/) key-value store.
|
10
|
+
#
|
11
|
+
# Example Usage:
|
12
|
+
#
|
13
|
+
# > client = RiakRaw::Client.new('127.0.0.1', 8098, 'raw')
|
14
|
+
# > client.delete('raw_example', 'doctestkey')
|
15
|
+
# > obj = client.store('raw_example', 'doctestkey', {'foo':2})
|
16
|
+
# > client.fetch('raw_example', 'doctestkey')
|
17
|
+
module RiakRaw
|
18
|
+
VERSION = '0.0.1'
|
19
|
+
|
20
|
+
class Client
|
21
|
+
attr_accessor :host, :port, :prefix, :client_id
|
22
|
+
|
23
|
+
def initialize(host="127.0.0.1", port=8098, prefix='riak', client_id=SecureRandom.base64)
|
24
|
+
@host = host
|
25
|
+
@port = port
|
26
|
+
@prefix = prefix
|
27
|
+
@client_id = client_id
|
28
|
+
end
|
29
|
+
|
30
|
+
def bucket(bucket_name,keys=false)
|
31
|
+
#request(:get, build_path(bucket_name))
|
32
|
+
response = request(:get,
|
33
|
+
build_path(bucket_name),
|
34
|
+
nil, nil,
|
35
|
+
{"returnbody" => "true", "keys" => keys})
|
36
|
+
if response.code == 200
|
37
|
+
if json = response.body
|
38
|
+
return Yajl::Parser.parse(json)
|
39
|
+
end
|
40
|
+
end; nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def store(bucket_name, key, content, vclock=nil, links=[], content_type='application/json', w=2, dw=2, r=2)
|
44
|
+
headers = { 'Content-Type' => content_type,
|
45
|
+
'X-Riak-ClientId' => self.client_id }
|
46
|
+
if vclock
|
47
|
+
headers['X-Riak-Vclock'] = vclock
|
48
|
+
end
|
49
|
+
|
50
|
+
response = request(:put,
|
51
|
+
build_path(bucket_name,key),
|
52
|
+
content, headers,
|
53
|
+
{"returnbody" => "false", "w" => w, "dw" => dw})
|
54
|
+
|
55
|
+
# returnbody=true could cause issues. instead we'll do a
|
56
|
+
# separate fetch. see: https://issues.basho.com/show_bug.cgi?id=52
|
57
|
+
if response.code == 204
|
58
|
+
response = fetch(bucket_name, key, r)
|
59
|
+
end
|
60
|
+
|
61
|
+
response
|
62
|
+
end
|
63
|
+
|
64
|
+
def fetch(bucket_name, key, r=2)
|
65
|
+
response = request(:get,
|
66
|
+
build_path(bucket_name, key),
|
67
|
+
nil, {}, {"r" => r})
|
68
|
+
end
|
69
|
+
|
70
|
+
# there could be concurrency issues if we don't force a short sleep
|
71
|
+
# after delete. see: https://issues.basho.com/show_bug.cgi?id=52
|
72
|
+
def delete(bucket_name, key, dw=2)
|
73
|
+
response = request(:delete,
|
74
|
+
build_path(bucket_name, key),
|
75
|
+
nil, {}, {"dw" => dw})
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def build_path(bucket_name, key='')
|
81
|
+
"http://#{self.host}:#{self.port}/#{self.prefix}/#{URI.escape(bucket_name)}/#{URI.escape(key)}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def request(method, uri, body="", headers={}, params={})
|
85
|
+
hydra = Typhoeus::Hydra.new
|
86
|
+
case method
|
87
|
+
when :get then
|
88
|
+
req = Typhoeus::Request.new(uri, :method => :get, :body => body, :headers => headers, :params => params)
|
89
|
+
when :post then
|
90
|
+
req = Typhoeus::Request.new(uri, :method => :post, :body => body, :headers => headers, :params => params)
|
91
|
+
when :put then
|
92
|
+
req = Typhoeus::Request.new(uri, :method => :put, :body => body, :headers => headers, :params => params)
|
93
|
+
when :delete then
|
94
|
+
req = Typhoeus::Request.new(uri, :method => :delete, :body => body, :headers => headers, :params => params)
|
95
|
+
end
|
96
|
+
hydra.queue(req); hydra.run
|
97
|
+
req.handled_response
|
98
|
+
end
|
99
|
+
end # Client
|
100
|
+
end
|