chimera 0.0.1
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/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
|