with_connection 0.1.11 → 0.1.12
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 +1 -1
- data/lib/dalli/async_socket.rb +157 -6
- data/with_connection.gemspec +1 -1
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.12
|
data/lib/dalli/async_socket.rb
CHANGED
@@ -1,10 +1,161 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
1
3
|
module Dalli
|
2
4
|
class Server
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# from thrift_cliet-0.8.2/lib/thrift_client/event_machine.rb
|
6
|
+
module EventMachineConnection
|
7
|
+
GARBAGE_BUFFER_SIZE = 4096 # 4kB
|
8
|
+
|
9
|
+
include EM::Deferrable
|
10
|
+
|
11
|
+
def self.connect(host='localhost', port=11211, options={}, &block)
|
12
|
+
fiber = Fiber.current
|
13
|
+
EM.connect(host, port, self, host, port) do |conn|
|
14
|
+
conn.pending_connect_timeout = options[:timeout] || 5
|
15
|
+
conn.read_timeout = options[:read_timeout] || 5
|
16
|
+
conn.write_timeout = options[:write_timeout] || 5
|
17
|
+
end.tap do |connection|
|
18
|
+
connection.callback do
|
19
|
+
fiber.resume
|
20
|
+
end
|
21
|
+
|
22
|
+
connection.errback do
|
23
|
+
fiber.resume
|
24
|
+
end
|
25
|
+
|
26
|
+
Fiber.yield
|
27
|
+
|
28
|
+
raise Exception, "Unable to connect to #{host}:#{port}" unless connection.connected?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def trap
|
33
|
+
begin
|
34
|
+
yield
|
35
|
+
rescue Exception => ex
|
36
|
+
puts ex.message
|
37
|
+
puts ex.backtrace.join("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_accessor :read_timeout, :write_timeout
|
42
|
+
|
43
|
+
def initialize(host, port=9090)
|
44
|
+
@host, @port = host, port
|
45
|
+
@index = 0
|
46
|
+
@disconnected = 'not connected'
|
47
|
+
@buf = ''
|
48
|
+
end
|
49
|
+
|
50
|
+
def close
|
51
|
+
trap do
|
52
|
+
@disconnected = 'closed'
|
53
|
+
close_connection(true)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def blocking_read(size)
|
58
|
+
raise IOError, "lost connection to #{@host}:#{@port}: #{@disconnected}" if @disconnected
|
59
|
+
if can_read?(size)
|
60
|
+
yank(size)
|
61
|
+
else
|
62
|
+
raise ArgumentError, "Unexpected state" if @size or @callback
|
63
|
+
|
64
|
+
timed(self.read_timeout) do
|
65
|
+
read_with_callback size
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
alias readfull blocking_read
|
70
|
+
|
71
|
+
# when enough data has been received the callback will return the data to the requesting fiber
|
72
|
+
def read_with_callback(size)
|
73
|
+
fiber = Fiber.current
|
74
|
+
|
75
|
+
@size = size
|
76
|
+
@callback = proc { |data|
|
77
|
+
fiber.resume(data)
|
78
|
+
}
|
79
|
+
|
80
|
+
Fiber.yield
|
81
|
+
end
|
82
|
+
|
83
|
+
def write(buf)
|
84
|
+
timed(self.write_timeout) do
|
85
|
+
send_data buf
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def receive_data(data)
|
90
|
+
trap do
|
91
|
+
(@buf) << data
|
92
|
+
|
93
|
+
if @callback and can_read?(@size)
|
94
|
+
callback = @callback
|
95
|
+
data = yank(@size)
|
96
|
+
@callback = @size = nil
|
97
|
+
callback.call(data)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def connected?
|
103
|
+
!@disconnected
|
104
|
+
end
|
105
|
+
|
106
|
+
def connection_completed
|
107
|
+
@disconnected = nil
|
108
|
+
succeed
|
109
|
+
end
|
110
|
+
|
111
|
+
def unbind
|
112
|
+
if !@disconnected
|
113
|
+
@disconnected = 'unbound'
|
114
|
+
else
|
115
|
+
fail
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def can_read?(size)
|
120
|
+
@buf.size >= @index + size
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def create_timer(timeout)
|
126
|
+
fiber = Fiber.current
|
127
|
+
|
128
|
+
EM::Timer.new(timeout) do
|
129
|
+
self.close
|
130
|
+
@size = nil
|
131
|
+
@callback = nil
|
132
|
+
@buf = ''
|
133
|
+
@index = 0
|
134
|
+
@timed_out = true
|
135
|
+
fiber.resume false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def timed(timeout)
|
140
|
+
timer = create_timer(timeout)
|
141
|
+
yield.tap do
|
142
|
+
timer.cancel
|
143
|
+
if @timed_out
|
144
|
+
@timed_out = nil
|
145
|
+
raise Timeout::Error, "connection to #{@host}:#{@port}: timed out while writing"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def yank(len)
|
151
|
+
data = @buf.slice(@index, len)
|
152
|
+
@index += len
|
153
|
+
@index = @buf.size if @index > @buf.size
|
154
|
+
if @index >= GARBAGE_BUFFER_SIZE
|
155
|
+
@buf = @buf.slice(@index..-1)
|
156
|
+
@index = 0
|
157
|
+
end
|
158
|
+
data
|
8
159
|
end
|
9
160
|
end
|
10
161
|
|
@@ -12,7 +163,7 @@ module Dalli
|
|
12
163
|
class << self
|
13
164
|
def open_with_async(*args)
|
14
165
|
if EM.reactor_running?
|
15
|
-
|
166
|
+
Dalli::Server::EventMachineConnection.connect *args
|
16
167
|
else
|
17
168
|
open_without_async *args
|
18
169
|
end
|
data/with_connection.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: with_connection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -114,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
114
|
version: '0'
|
115
115
|
segments:
|
116
116
|
- 0
|
117
|
-
hash:
|
117
|
+
hash: 4460793055233630791
|
118
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
119
|
none: false
|
120
120
|
requirements:
|