eventmachine 0.12.6-x86-mswin32-60 → 0.12.8-x86-mswin32-60
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/{docs/README → README} +21 -13
- data/Rakefile +14 -4
- data/docs/DEFERRABLES +0 -5
- data/docs/INSTALL +2 -4
- data/docs/LEGAL +1 -1
- data/docs/LIGHTWEIGHT_CONCURRENCY +0 -2
- data/docs/PURE_RUBY +0 -2
- data/docs/RELEASE_NOTES +0 -2
- data/docs/SMTP +0 -7
- data/docs/SPAWNED_PROCESSES +0 -4
- data/docs/TODO +0 -2
- data/eventmachine.gemspec +41 -32
- data/examples/ex_channel.rb +43 -0
- data/examples/ex_queue.rb +2 -0
- data/examples/helper.rb +2 -0
- data/ext/cmain.cpp +685 -586
- data/ext/cplusplus.cpp +15 -6
- data/ext/ed.cpp +1732 -1522
- data/ext/ed.h +407 -380
- data/ext/em.cpp +2263 -1937
- data/ext/em.h +223 -186
- data/ext/eventmachine.h +111 -98
- data/ext/eventmachine_cpp.h +1 -0
- data/ext/extconf.rb +4 -0
- data/ext/kb.cpp +81 -82
- data/ext/pipe.cpp +349 -351
- data/ext/project.h +21 -0
- data/ext/rubymain.cpp +1047 -847
- data/ext/ssl.cpp +38 -1
- data/ext/ssl.h +5 -1
- data/java/src/com/rubyeventmachine/Application.java +7 -3
- data/java/src/com/rubyeventmachine/EmReactor.java +16 -1
- data/java/src/com/rubyeventmachine/tests/ConnectTest.java +25 -3
- data/lib/{protocols → em}/buftok.rb +16 -5
- data/lib/em/callback.rb +26 -0
- data/lib/em/channel.rb +57 -0
- data/lib/em/connection.rb +505 -0
- data/lib/em/deferrable.rb +144 -165
- data/lib/em/file_watch.rb +54 -0
- data/lib/em/future.rb +24 -25
- data/lib/em/messages.rb +1 -1
- data/lib/em/process_watch.rb +44 -0
- data/lib/em/processes.rb +119 -113
- data/lib/em/protocols.rb +35 -0
- data/lib/em/protocols/header_and_content.rb +138 -0
- data/lib/em/protocols/httpclient.rb +263 -0
- data/lib/em/protocols/httpclient2.rb +582 -0
- data/lib/{protocols → em/protocols}/line_and_text.rb +2 -2
- data/lib/em/protocols/linetext2.rb +160 -0
- data/lib/{protocols → em/protocols}/memcache.rb +37 -7
- data/lib/em/protocols/object_protocol.rb +39 -0
- data/lib/em/protocols/postgres3.rb +247 -0
- data/lib/em/protocols/saslauth.rb +175 -0
- data/lib/em/protocols/smtpclient.rb +331 -0
- data/lib/em/protocols/smtpserver.rb +547 -0
- data/lib/em/protocols/stomp.rb +200 -0
- data/lib/{protocols → em/protocols}/tcptest.rb +21 -25
- data/lib/em/queue.rb +61 -0
- data/lib/em/spawnable.rb +53 -56
- data/lib/em/streamer.rb +92 -74
- data/lib/em/timers.rb +55 -0
- data/lib/em/version.rb +3 -0
- data/lib/eventmachine.rb +1636 -1926
- data/lib/evma.rb +1 -1
- data/lib/jeventmachine.rb +106 -101
- data/lib/pr_eventmachine.rb +47 -36
- data/tasks/project.rake +2 -1
- data/tests/client.crt +31 -0
- data/tests/client.key +51 -0
- data/tests/test_attach.rb +18 -0
- data/tests/test_basic.rb +285 -231
- data/tests/test_channel.rb +63 -0
- data/tests/test_connection_count.rb +2 -2
- data/tests/test_epoll.rb +162 -163
- data/tests/test_errors.rb +36 -36
- data/tests/test_exc.rb +22 -25
- data/tests/test_file_watch.rb +49 -0
- data/tests/test_futures.rb +77 -93
- data/tests/test_hc.rb +2 -2
- data/tests/test_httpclient.rb +55 -52
- data/tests/test_httpclient2.rb +153 -155
- data/tests/test_inactivity_timeout.rb +30 -0
- data/tests/test_kb.rb +8 -9
- data/tests/test_ltp2.rb +274 -277
- data/tests/test_next_tick.rb +135 -109
- data/tests/test_object_protocol.rb +37 -0
- data/tests/test_process_watch.rb +48 -0
- data/tests/test_processes.rb +128 -95
- data/tests/test_proxy_connection.rb +92 -0
- data/tests/test_pure.rb +1 -5
- data/tests/test_queue.rb +44 -0
- data/tests/test_running.rb +9 -14
- data/tests/test_sasl.rb +32 -34
- data/tests/test_send_file.rb +175 -176
- data/tests/test_servers.rb +37 -41
- data/tests/test_smtpserver.rb +47 -55
- data/tests/test_spawn.rb +284 -291
- data/tests/test_ssl_args.rb +1 -1
- data/tests/test_ssl_methods.rb +1 -1
- data/tests/test_ssl_verify.rb +82 -0
- data/tests/test_timers.rb +81 -88
- data/tests/test_ud.rb +0 -7
- data/tests/testem.rb +1 -1
- metadata +52 -36
- data/lib/em/eventable.rb +0 -39
- data/lib/eventmachine_version.rb +0 -31
- data/lib/protocols/header_and_content.rb +0 -129
- data/lib/protocols/httpcli2.rb +0 -803
- data/lib/protocols/httpclient.rb +0 -270
- data/lib/protocols/linetext2.rb +0 -161
- data/lib/protocols/postgres.rb +0 -261
- data/lib/protocols/saslauth.rb +0 -179
- data/lib/protocols/smtpclient.rb +0 -308
- data/lib/protocols/smtpserver.rb +0 -556
- data/lib/protocols/stomp.rb +0 -153
- data/tests/test_eventables.rb +0 -77
@@ -0,0 +1,200 @@
|
|
1
|
+
#--
|
2
|
+
#
|
3
|
+
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
|
+
# Homepage:: http://rubyeventmachine.com
|
5
|
+
# Date:: 15 November 2006
|
6
|
+
#
|
7
|
+
# See EventMachine and EventMachine::Connection for documentation and
|
8
|
+
# usage examples.
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
|
13
|
+
# Gmail: blackhedd
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#
|
26
|
+
|
27
|
+
module EventMachine
|
28
|
+
module Protocols
|
29
|
+
|
30
|
+
# Implements Stomp (http://docs.codehaus.org/display/STOMP/Protocol).
|
31
|
+
#
|
32
|
+
# == Usage example
|
33
|
+
#
|
34
|
+
# module StompClient
|
35
|
+
# include EM::Protocols::Stomp
|
36
|
+
#
|
37
|
+
# def connection_completed
|
38
|
+
# connect :login => 'guest', :passcode => 'guest'
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# def receive_msg msg
|
42
|
+
# if msg.command == "CONNECTED"
|
43
|
+
# subscribe '/some/topic'
|
44
|
+
# else
|
45
|
+
# p ['got a message', msg]
|
46
|
+
# puts msg.body
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# EM.run{
|
52
|
+
# EM.connect 'localhost', 61613, StompClient
|
53
|
+
# }
|
54
|
+
#
|
55
|
+
module Stomp
|
56
|
+
include LineText2
|
57
|
+
|
58
|
+
class Message
|
59
|
+
# The command associated with the message, usually 'CONNECTED' or 'MESSAGE'
|
60
|
+
attr_accessor :command
|
61
|
+
# Hash containing headers such as destination and message-id
|
62
|
+
attr_accessor :header
|
63
|
+
alias :headers :header
|
64
|
+
# Body of the message
|
65
|
+
attr_accessor :body
|
66
|
+
|
67
|
+
def initialize # :nodoc:
|
68
|
+
@header = {}
|
69
|
+
@state = :precommand
|
70
|
+
@content_length = nil
|
71
|
+
end
|
72
|
+
def consume_line line # :nodoc:
|
73
|
+
if @state == :precommand
|
74
|
+
unless line =~ /\A\s*\Z/
|
75
|
+
@command = line
|
76
|
+
@state = :headers
|
77
|
+
end
|
78
|
+
elsif @state == :headers
|
79
|
+
if line == ""
|
80
|
+
if @content_length
|
81
|
+
yield( [:sized_text, @content_length+1] )
|
82
|
+
else
|
83
|
+
@state = :body
|
84
|
+
yield( [:unsized_text] )
|
85
|
+
end
|
86
|
+
elsif line =~ /\A([^:]+):(.+)\Z/
|
87
|
+
k = $1.dup.strip
|
88
|
+
v = $2.dup.strip
|
89
|
+
@header[k] = v
|
90
|
+
if k == "content-length"
|
91
|
+
@content_length = v.to_i
|
92
|
+
end
|
93
|
+
else
|
94
|
+
# This is a protocol error. How to signal it?
|
95
|
+
end
|
96
|
+
elsif @state == :body
|
97
|
+
@body = line
|
98
|
+
yield( [:dispatch] )
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# :stopdoc:
|
104
|
+
|
105
|
+
def send_frame verb, headers={}, body=""
|
106
|
+
ary = [verb, "\n"]
|
107
|
+
headers.each {|k,v| ary << "#{k}:#{v}\n" }
|
108
|
+
ary << "content-length: #{body.to_s.length}\n"
|
109
|
+
ary << "content-type: text/plain; charset=UTF-8\n"
|
110
|
+
ary << "\n"
|
111
|
+
ary << body.to_s
|
112
|
+
ary << "\0"
|
113
|
+
send_data ary.join
|
114
|
+
end
|
115
|
+
|
116
|
+
def receive_line line
|
117
|
+
@stomp_initialized || init_message_reader
|
118
|
+
@stomp_message.consume_line(line) {|outcome|
|
119
|
+
if outcome.first == :sized_text
|
120
|
+
set_text_mode outcome[1]
|
121
|
+
elsif outcome.first == :unsized_text
|
122
|
+
set_delimiter "\0"
|
123
|
+
elsif outcome.first == :dispatch
|
124
|
+
receive_msg(@stomp_message) if respond_to?(:receive_msg)
|
125
|
+
init_message_reader
|
126
|
+
end
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
def receive_binary_data data
|
131
|
+
@stomp_message.body = data[0..-2]
|
132
|
+
receive_msg(@stomp_message) if respond_to?(:receive_msg)
|
133
|
+
init_message_reader
|
134
|
+
end
|
135
|
+
|
136
|
+
def init_message_reader
|
137
|
+
@stomp_initialized = true
|
138
|
+
set_delimiter "\n"
|
139
|
+
set_line_mode
|
140
|
+
@stomp_message = Message.new
|
141
|
+
end
|
142
|
+
|
143
|
+
# :startdoc:
|
144
|
+
|
145
|
+
# Invoked with an incoming Stomp::Message received from the STOMP server
|
146
|
+
def receive_msg msg
|
147
|
+
# stub, overwrite this in your handler
|
148
|
+
end
|
149
|
+
|
150
|
+
# CONNECT command, for authentication
|
151
|
+
#
|
152
|
+
# connect :login => 'guest', :passcode => 'guest'
|
153
|
+
#
|
154
|
+
def connect parms={}
|
155
|
+
send_frame "CONNECT", parms
|
156
|
+
end
|
157
|
+
|
158
|
+
# SEND command, for publishing messages to a topic
|
159
|
+
#
|
160
|
+
# send '/topic/name', 'some message here'
|
161
|
+
#
|
162
|
+
def send destination, body, parms={}
|
163
|
+
send_frame "SEND", parms.merge( :destination=>destination ), body.to_s
|
164
|
+
end
|
165
|
+
|
166
|
+
# SUBSCRIBE command, for subscribing to topics
|
167
|
+
#
|
168
|
+
# subscribe '/topic/name', false
|
169
|
+
#
|
170
|
+
def subscribe dest, ack=false
|
171
|
+
send_frame "SUBSCRIBE", {:destination=>dest, :ack=>(ack ? "client" : "auto")}
|
172
|
+
end
|
173
|
+
|
174
|
+
# ACK command, for acknowledging receipt of messages
|
175
|
+
#
|
176
|
+
# module StompClient
|
177
|
+
# include EM::P::Stomp
|
178
|
+
#
|
179
|
+
# def connection_completed
|
180
|
+
# connect :login => 'guest', :passcode => 'guest'
|
181
|
+
# # subscribe with ack mode
|
182
|
+
# subscribe '/some/topic', true
|
183
|
+
# end
|
184
|
+
#
|
185
|
+
# def receive_msg msg
|
186
|
+
# if msg.command == "MESSAGE"
|
187
|
+
# ack msg.headers['message-id']
|
188
|
+
# puts msg.body
|
189
|
+
# end
|
190
|
+
# end
|
191
|
+
# end
|
192
|
+
#
|
193
|
+
def ack msgid
|
194
|
+
send_frame "ACK", 'message-id'=> msgid
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
#--
|
2
2
|
#
|
3
3
|
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
4
|
# Homepage:: http://rubyeventmachine.com
|
@@ -24,34 +24,30 @@
|
|
24
24
|
#
|
25
25
|
#
|
26
26
|
|
27
|
-
|
28
|
-
|
29
27
|
module EventMachine
|
30
|
-
module Protocols
|
28
|
+
module Protocols
|
31
29
|
|
32
|
-
class TcpConnectTester < Connection
|
33
|
-
|
30
|
+
class TcpConnectTester < Connection # :nodoc:
|
31
|
+
include EventMachine::Deferrable
|
34
32
|
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
def self.test( host, port )
|
34
|
+
EventMachine.connect( host, port, self )
|
35
|
+
end
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
def post_init
|
38
|
+
@start_time = Time.now
|
39
|
+
end
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
def unbind
|
50
|
-
set_deferred_status :failed, (Time.now - @start_time) unless @completed
|
51
|
-
end
|
52
|
-
end
|
41
|
+
def connection_completed
|
42
|
+
@completed = true
|
43
|
+
set_deferred_status :succeeded, (Time.now - @start_time)
|
44
|
+
close_connection
|
45
|
+
end
|
53
46
|
|
47
|
+
def unbind
|
48
|
+
set_deferred_status :failed, (Time.now - @start_time) unless @completed
|
49
|
+
end
|
50
|
+
end
|
54
51
|
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
52
|
+
end
|
53
|
+
end
|
data/lib/em/queue.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
module EventMachine
|
2
|
+
# A cross thread, reactor scheduled, linear queue.
|
3
|
+
#
|
4
|
+
# This class provides a simple "Queue" like abstraction on top of the reactor
|
5
|
+
# scheduler. It services two primary purposes:
|
6
|
+
# * API sugar for stateful protocols
|
7
|
+
# * Pushing processing onto the same thread as the reactor
|
8
|
+
#
|
9
|
+
# See examples/ex_queue.rb for a detailed example.
|
10
|
+
#
|
11
|
+
# q = EM::Queue.new
|
12
|
+
# q.push('one', 'two', 'three')
|
13
|
+
# 3.times do
|
14
|
+
# q.pop{ |msg| puts(msg) }
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
class Queue
|
18
|
+
# Create a new queue
|
19
|
+
def initialize
|
20
|
+
@items = []
|
21
|
+
@popq = []
|
22
|
+
end
|
23
|
+
|
24
|
+
# Pop items off the queue, running the block on the reactor thread. The pop
|
25
|
+
# will not happen immediately, but at some point in the future, either in
|
26
|
+
# the next tick, if the queue has data, or when the queue is populated.
|
27
|
+
def pop(*a, &b)
|
28
|
+
cb = EM::Callback(*a, &b)
|
29
|
+
EM.schedule do
|
30
|
+
if @items.empty?
|
31
|
+
@popq << cb
|
32
|
+
else
|
33
|
+
cb.call @items.shift
|
34
|
+
end
|
35
|
+
end
|
36
|
+
nil # Always returns nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# Push items onto the queue in the reactor thread. The items will not appear
|
40
|
+
# in the queue immediately, but will be scheduled for addition during the
|
41
|
+
# next reactor tick.
|
42
|
+
def push(*items)
|
43
|
+
EM.schedule do
|
44
|
+
@items.concat items
|
45
|
+
@popq.shift.call @items.shift until @items.empty? || @popq.empty?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# N.B. This is a peek, it's not thread safe, and may only tend toward
|
50
|
+
# accuracy.
|
51
|
+
def empty?
|
52
|
+
@items.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
# N.B. This is a peek, it's not thread safe, and may only tend toward
|
56
|
+
# accuracy.
|
57
|
+
def size
|
58
|
+
@items.size
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/em/spawnable.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
#--
|
2
2
|
#
|
3
3
|
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
4
|
# Homepage:: http://rubyeventmachine.com
|
@@ -21,68 +21,65 @@
|
|
21
21
|
#
|
22
22
|
#---------------------------------------------------------------------------
|
23
23
|
#
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
# Support for Erlang-style processes.
|
28
24
|
#
|
29
25
|
|
30
|
-
|
31
26
|
module EventMachine
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
27
|
+
# Support for Erlang-style processes.
|
28
|
+
#
|
29
|
+
class SpawnedProcess
|
30
|
+
# Send a message to the spawned process
|
31
|
+
def notify *x
|
32
|
+
me = self
|
33
|
+
EM.next_tick {
|
34
|
+
# A notification executes in the context of this
|
35
|
+
# SpawnedProcess object. That makes self and notify
|
36
|
+
# work as one would expect.
|
37
|
+
#
|
38
|
+
y = me.call(*x)
|
39
|
+
if y and y.respond_to?(:pull_out_yield_block)
|
40
|
+
a,b = y.pull_out_yield_block
|
41
|
+
set_receiver a
|
42
|
+
self.notify if b
|
43
|
+
end
|
44
|
+
}
|
45
|
+
end
|
46
|
+
alias_method :resume, :notify
|
47
|
+
alias_method :run, :notify # for formulations like (EM.spawn {xxx}).run
|
48
|
+
#attr_accessor :receiver
|
51
49
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
50
|
+
#--
|
51
|
+
# I know I'm missing something stupid, but the inside of class << s
|
52
|
+
# can't see locally-bound values. It can see globals, though.
|
53
|
+
def set_receiver blk
|
54
|
+
$em______tmpglobal = blk
|
55
|
+
class << self
|
56
|
+
define_method :call, $em______tmpglobal.dup
|
57
|
+
end
|
58
|
+
end
|
60
59
|
|
61
|
-
|
60
|
+
end
|
62
61
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
62
|
+
class YieldBlockFromSpawnedProcess # :nodoc:
|
63
|
+
def initialize block, notify
|
64
|
+
@block = [block,notify]
|
65
|
+
end
|
66
|
+
def pull_out_yield_block
|
67
|
+
@block
|
68
|
+
end
|
69
|
+
end
|
71
70
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
# Spawn an erlang-style process
|
72
|
+
def self.spawn &block
|
73
|
+
s = SpawnedProcess.new
|
74
|
+
s.set_receiver block
|
75
|
+
s
|
76
|
+
end
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
def self.yield &block # :nodoc:
|
79
|
+
return YieldBlockFromSpawnedProcess.new( block, false )
|
80
|
+
end
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
def self.yield_and_notify &block # :nodoc:
|
83
|
+
return YieldBlockFromSpawnedProcess.new( block, true )
|
84
|
+
end
|
85
85
|
end
|
86
|
-
|
87
|
-
|
88
|
-
|