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 CHANGED
@@ -1 +1 @@
1
- 0.1.11
1
+ 0.1.12
@@ -1,10 +1,161 @@
1
+ require 'timeout'
2
+
1
3
  module Dalli
2
4
  class Server
3
- class KAsyncSocket < EventMachine::Synchrony::TCPSocket
4
- def readfull(count)
5
- value = ''
6
- read count, value
7
- value
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
- KAsyncSocket.new *args
166
+ Dalli::Server::EventMachineConnection.connect *args
16
167
  else
17
168
  open_without_async *args
18
169
  end
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "with_connection"
8
- s.version = "0.1.11"
8
+ s.version = "0.1.12"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Doug Youch"]
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.11
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: -1499532644223541582
117
+ hash: 4460793055233630791
118
118
  required_rubygems_version: !ruby/object:Gem::Requirement
119
119
  none: false
120
120
  requirements: