redis 2.0.0 → 2.2.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.
Files changed (81) hide show
  1. data/.gitignore +8 -0
  2. data/CHANGELOG.md +49 -0
  3. data/README.md +208 -0
  4. data/Rakefile +183 -73
  5. data/TODO.md +4 -0
  6. data/benchmarking/logging.rb +62 -0
  7. data/benchmarking/pipeline.rb +51 -0
  8. data/benchmarking/speed.rb +21 -0
  9. data/benchmarking/suite.rb +24 -0
  10. data/benchmarking/thread_safety.rb +38 -0
  11. data/benchmarking/worker.rb +71 -0
  12. data/examples/basic.rb +15 -0
  13. data/examples/dist_redis.rb +43 -0
  14. data/examples/incr-decr.rb +17 -0
  15. data/examples/list.rb +26 -0
  16. data/examples/pubsub.rb +31 -0
  17. data/examples/sets.rb +36 -0
  18. data/examples/unicorn/config.ru +3 -0
  19. data/examples/unicorn/unicorn.rb +20 -0
  20. data/lib/redis/client.rb +149 -165
  21. data/lib/redis/connection/command_helper.rb +45 -0
  22. data/lib/redis/connection/hiredis.rb +49 -0
  23. data/lib/redis/connection/registry.rb +12 -0
  24. data/lib/redis/connection/ruby.rb +135 -0
  25. data/lib/redis/connection/synchrony.rb +129 -0
  26. data/lib/redis/connection.rb +9 -0
  27. data/lib/redis/distributed.rb +182 -7
  28. data/lib/redis/pipeline.rb +22 -1
  29. data/lib/redis/subscribe.rb +19 -4
  30. data/lib/redis/version.rb +3 -0
  31. data/lib/redis.rb +715 -155
  32. data/redis.gemspec +24 -0
  33. data/test/commands_on_hashes_test.rb +32 -0
  34. data/test/commands_on_lists_test.rb +60 -0
  35. data/test/commands_on_sets_test.rb +78 -0
  36. data/test/commands_on_sorted_sets_test.rb +109 -0
  37. data/test/commands_on_strings_test.rb +80 -0
  38. data/test/commands_on_value_types_test.rb +88 -0
  39. data/test/connection_handling_test.rb +88 -0
  40. data/test/db/.gitignore +1 -0
  41. data/test/distributed_blocking_commands_test.rb +53 -0
  42. data/test/distributed_commands_on_hashes_test.rb +12 -0
  43. data/test/distributed_commands_on_lists_test.rb +24 -0
  44. data/test/distributed_commands_on_sets_test.rb +85 -0
  45. data/test/distributed_commands_on_strings_test.rb +50 -0
  46. data/test/distributed_commands_on_value_types_test.rb +73 -0
  47. data/test/distributed_commands_requiring_clustering_test.rb +148 -0
  48. data/test/distributed_connection_handling_test.rb +25 -0
  49. data/test/distributed_internals_test.rb +27 -0
  50. data/test/distributed_key_tags_test.rb +53 -0
  51. data/test/distributed_persistence_control_commands_test.rb +24 -0
  52. data/test/distributed_publish_subscribe_test.rb +101 -0
  53. data/test/distributed_remote_server_control_commands_test.rb +43 -0
  54. data/test/distributed_sorting_test.rb +21 -0
  55. data/test/distributed_test.rb +59 -0
  56. data/test/distributed_transactions_test.rb +34 -0
  57. data/test/encoding_test.rb +16 -0
  58. data/test/error_replies_test.rb +53 -0
  59. data/test/helper.rb +145 -0
  60. data/test/internals_test.rb +160 -0
  61. data/test/lint/hashes.rb +114 -0
  62. data/test/lint/internals.rb +37 -0
  63. data/test/lint/lists.rb +93 -0
  64. data/test/lint/sets.rb +66 -0
  65. data/test/lint/sorted_sets.rb +167 -0
  66. data/test/lint/strings.rb +137 -0
  67. data/test/lint/value_types.rb +84 -0
  68. data/test/persistence_control_commands_test.rb +22 -0
  69. data/test/pipelining_commands_test.rb +123 -0
  70. data/test/publish_subscribe_test.rb +158 -0
  71. data/test/redis_mock.rb +80 -0
  72. data/test/remote_server_control_commands_test.rb +82 -0
  73. data/test/sorting_test.rb +44 -0
  74. data/test/synchrony_driver.rb +57 -0
  75. data/test/test.conf +8 -0
  76. data/test/thread_safety_test.rb +30 -0
  77. data/test/transactions_test.rb +100 -0
  78. data/test/unknown_commands_test.rb +14 -0
  79. data/test/url_param_test.rb +60 -0
  80. metadata +130 -22
  81. data/README.markdown +0 -120
@@ -0,0 +1,129 @@
1
+ require "redis/connection/command_helper"
2
+ require "redis/connection/registry"
3
+ require "em-synchrony"
4
+ require "hiredis/reader"
5
+
6
+ class Redis
7
+ module Connection
8
+ class RedisClient < EventMachine::Connection
9
+ include EventMachine::Deferrable
10
+
11
+ def post_init
12
+ @req = nil
13
+ @connected = false
14
+ @reader = ::Hiredis::Reader.new
15
+ end
16
+
17
+ def connection_completed
18
+ @connected = true
19
+ succeed
20
+ end
21
+
22
+ def connected?
23
+ @connected
24
+ end
25
+
26
+ def receive_data(data)
27
+ @reader.feed(data)
28
+
29
+ begin
30
+ until (reply = @reader.gets) == false
31
+ @req.succeed [:reply, reply]
32
+ end
33
+ rescue RuntimeError => err
34
+ @req.fail [:error, ::Redis::ProtocolError.new(err.message)]
35
+ end
36
+ end
37
+
38
+ def read
39
+ @req = EventMachine::DefaultDeferrable.new
40
+ EventMachine::Synchrony.sync @req
41
+ end
42
+
43
+ def send(data)
44
+ callback { send_data data }
45
+ end
46
+
47
+ def unbind
48
+ @connected = false
49
+ if @req
50
+ @req.fail [:error, Errno::ECONNRESET]
51
+ @req = nil
52
+ else
53
+ fail
54
+ end
55
+ end
56
+ end
57
+
58
+ class Synchrony
59
+ include Redis::Connection::CommandHelper
60
+
61
+ def initialize
62
+ @timeout = 5_000_000
63
+ @connection = nil
64
+ end
65
+
66
+ def connected?
67
+ @connection && @connection.connected?
68
+ end
69
+
70
+ def timeout=(usecs)
71
+ @timeout = usecs
72
+ end
73
+
74
+ def connect(host, port, timeout)
75
+ conn = EventMachine.connect(host, port, RedisClient) do |c|
76
+ c.pending_connect_timeout = [Float(timeout / 1_000_000), 0.1].max
77
+ end
78
+
79
+ setup_connect_callbacks(conn, Fiber.current)
80
+ end
81
+
82
+ def connect_unix(path, timeout)
83
+ conn = EventMachine.connect_unix_domain(path, RedisClient)
84
+ setup_connect_callbacks(conn, Fiber.current)
85
+ end
86
+
87
+ def disconnect
88
+ @connection.close_connection
89
+ @connection = nil
90
+ end
91
+
92
+ def write(command)
93
+ @connection.send(build_command(command))
94
+ end
95
+
96
+ def read
97
+ type, payload = @connection.read
98
+
99
+ if type == :reply
100
+ payload
101
+ elsif type == :error
102
+ raise payload
103
+ else
104
+ raise "Unknown type #{type.inspect}"
105
+ end
106
+ end
107
+
108
+ private
109
+
110
+ def setup_connect_callbacks(conn, f)
111
+ conn.callback do
112
+ @connection = conn
113
+ f.resume conn
114
+ end
115
+
116
+ conn.errback do
117
+ @connection = conn
118
+ f.resume :refused
119
+ end
120
+
121
+ r = Fiber.yield
122
+ raise Errno::ECONNREFUSED if r == :refused
123
+ r
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ Redis::Connection.drivers << Redis::Connection::Synchrony
@@ -0,0 +1,9 @@
1
+ require "redis/connection/registry"
2
+
3
+ # If a connection driver was required before this file, the array
4
+ # Redis::Connection.drivers will contain one or more classes. The last driver
5
+ # in this array will be used as default driver. If this array is empty, we load
6
+ # the plain Ruby driver as our default. Another driver can be required at a
7
+ # later point in time, causing it to be the last element of the #drivers array
8
+ # and therefore be chosen by default.
9
+ require "redis/connection/ruby" if Redis::Connection.drivers.empty?