eventmachine-eventmachine 0.12.7 → 0.12.8
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 +17 -8
- data/examples/ex_channel.rb +43 -0
- data/examples/ex_queue.rb +2 -0
- data/examples/helper.rb +2 -0
- data/ext/cmain.cpp +119 -20
- data/ext/cplusplus.cpp +15 -6
- data/ext/ed.cpp +303 -93
- data/ext/ed.h +49 -22
- data/ext/em.cpp +368 -42
- data/ext/em.h +43 -6
- data/ext/eventmachine.h +21 -8
- data/ext/eventmachine_cpp.h +1 -0
- data/ext/extconf.rb +4 -0
- data/ext/kb.cpp +1 -2
- data/ext/pipe.cpp +1 -3
- data/ext/project.h +21 -0
- data/ext/rubymain.cpp +232 -32
- 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 +58 -52
- 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/protocols.rb +35 -0
- 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 +1008 -1298
- 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 +108 -54
- data/tests/test_channel.rb +63 -0
- data/tests/test_connection_count.rb +2 -2
- data/tests/test_epoll.rb +109 -110
- 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 +110 -112
- 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 +91 -65
- data/tests/test_object_protocol.rb +37 -0
- data/tests/test_process_watch.rb +48 -0
- data/tests/test_processes.rb +56 -23
- 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 +53 -37
- 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
|
@@ -340,7 +340,6 @@ public class EmReactor {
|
|
|
340
340
|
(Connections.get(sig)).scheduleOutboundDatagram( bb, recipAddress, recipPort);
|
|
341
341
|
}
|
|
342
342
|
|
|
343
|
-
|
|
344
343
|
/**
|
|
345
344
|
*
|
|
346
345
|
* @param address
|
|
@@ -349,11 +348,27 @@ public class EmReactor {
|
|
|
349
348
|
* @throws ClosedChannelException
|
|
350
349
|
*/
|
|
351
350
|
public String connectTcpServer (String address, int port) throws ClosedChannelException {
|
|
351
|
+
return connectTcpServer(null, 0, address, port);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
*
|
|
356
|
+
* @param bindAddr
|
|
357
|
+
* @param bindPort
|
|
358
|
+
* @param address
|
|
359
|
+
* @param port
|
|
360
|
+
* @return
|
|
361
|
+
* @throws ClosedChannelException
|
|
362
|
+
*/
|
|
363
|
+
public String connectTcpServer (String bindAddr, int bindPort, String address, int port) throws ClosedChannelException {
|
|
352
364
|
String b = createBinding();
|
|
353
365
|
|
|
354
366
|
try {
|
|
355
367
|
SocketChannel sc = SocketChannel.open();
|
|
356
368
|
sc.configureBlocking(false);
|
|
369
|
+
if (bindAddr != null)
|
|
370
|
+
sc.socket().bind(new InetSocketAddress (bindAddr, bindPort));
|
|
371
|
+
|
|
357
372
|
EventableSocketChannel ec = new EventableSocketChannel (sc, b, mySelector);
|
|
358
373
|
|
|
359
374
|
if (sc.connect (new InetSocketAddress (address, port))) {
|
|
@@ -97,9 +97,31 @@ public class ConnectTest {
|
|
|
97
97
|
});
|
|
98
98
|
a.run();
|
|
99
99
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
|
|
101
|
+
public final void testBindConnect() throws IOException {
|
|
102
|
+
class Server extends Connection {
|
|
103
|
+
public void postInit() {
|
|
104
|
+
// TODO: get peername here and check if the port is 33333
|
|
105
|
+
// doesnt seem like peername is impl yet?
|
|
106
|
+
System.out.println("post init!");
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
Application a = new Application();
|
|
111
|
+
a.addTimer(0, new Timer() {
|
|
112
|
+
public void fire() {
|
|
113
|
+
application.startServer(new InetSocketAddress("localhost", 20000), new Server());
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
a.addTimer(500, new Timer() {
|
|
117
|
+
public void fire() {
|
|
118
|
+
application.bindConnect("localhost", 33333, "localhost", 20000);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
a.run();
|
|
123
|
+
}
|
|
124
|
+
|
|
103
125
|
class C1 extends Connection {
|
|
104
126
|
Application application;
|
|
105
127
|
public C1 (Application a) {
|
|
@@ -18,6 +18,16 @@
|
|
|
18
18
|
# by default. It allows input to be spoon-fed from some outside source which
|
|
19
19
|
# receives arbitrary length datagrams which may-or-may-not contain the token
|
|
20
20
|
# by which entities are delimited.
|
|
21
|
+
#
|
|
22
|
+
# Commonly used to parse lines out of incoming data:
|
|
23
|
+
#
|
|
24
|
+
# module LineBufferedConnection
|
|
25
|
+
# def receive_data(data)
|
|
26
|
+
# (@buffer ||= BufferedTokenizer.new).extract(data).each do |line|
|
|
27
|
+
# receive_line(line)
|
|
28
|
+
# end
|
|
29
|
+
# end
|
|
30
|
+
# end
|
|
21
31
|
|
|
22
32
|
class BufferedTokenizer
|
|
23
33
|
# New BufferedTokenizers will operate on lines delimited by "\n" by default
|
|
@@ -76,10 +86,10 @@ class BufferedTokenizer
|
|
|
76
86
|
entities.unshift @input.join
|
|
77
87
|
|
|
78
88
|
=begin
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
# Note added by FC, 10Jul07. This paragraph contains a regression. It breaks
|
|
90
|
+
# empty tokens. Think of the empty line that delimits an HTTP header. It will have
|
|
91
|
+
# two "\n" delimiters in a row, and this code mishandles the resulting empty token.
|
|
92
|
+
# It someone figures out how to fix the problem, we can re-enable this code branch.
|
|
83
93
|
# Multi-character token support.
|
|
84
94
|
# Split any tokens that were incomplete on the last iteration buf complete now.
|
|
85
95
|
entities.map! do |e|
|
|
@@ -121,7 +131,8 @@ class BufferedTokenizer
|
|
|
121
131
|
buffer
|
|
122
132
|
end
|
|
123
133
|
|
|
134
|
+
# Is the buffer empty?
|
|
124
135
|
def empty?
|
|
125
136
|
@input.empty?
|
|
126
137
|
end
|
|
127
|
-
end
|
|
138
|
+
end
|
data/lib/em/callback.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module EventMachine
|
|
2
|
+
# Utility method for coercing arguments to an object that responds to #call
|
|
3
|
+
# Accepts an object and a method name to send to, or a block, or an object
|
|
4
|
+
# that responds to call.
|
|
5
|
+
#
|
|
6
|
+
# cb = EM.Callback{ |msg| puts(msg) }
|
|
7
|
+
# cb.call('hello world')
|
|
8
|
+
#
|
|
9
|
+
# cb = EM.Callback(Object, :puts)
|
|
10
|
+
# cb.call('hello world')
|
|
11
|
+
#
|
|
12
|
+
# cb = EM.Callback(proc{ |msg| puts(msg) })
|
|
13
|
+
# cb.call('hello world')
|
|
14
|
+
#
|
|
15
|
+
def self.Callback(object = nil, method = nil, &blk)
|
|
16
|
+
if object && method
|
|
17
|
+
lambda { |*args| object.send method, *args }
|
|
18
|
+
else
|
|
19
|
+
if object.respond_to? :call
|
|
20
|
+
object
|
|
21
|
+
else
|
|
22
|
+
blk || raise(ArgumentError)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/em/channel.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module EventMachine
|
|
2
|
+
# Provides a simple interface to push items to a number of subscribers. The
|
|
3
|
+
# channel will schedule all operations on the main reactor thread for thread
|
|
4
|
+
# safe reactor operations.
|
|
5
|
+
#
|
|
6
|
+
# This provides a convenient way for connections to consume messages from
|
|
7
|
+
# long running code in defer, without threading issues.
|
|
8
|
+
#
|
|
9
|
+
# channel = EM::Channel.new
|
|
10
|
+
# sid = channel.subscribe{ |msg| p [:got, msg] }
|
|
11
|
+
# channel.push('hello world')
|
|
12
|
+
# channel.unsubscribe(sid)
|
|
13
|
+
#
|
|
14
|
+
# See examples/ex_channel.rb for a detailed example.
|
|
15
|
+
class Channel
|
|
16
|
+
# Create a new channel
|
|
17
|
+
def initialize
|
|
18
|
+
@subs = {}
|
|
19
|
+
@uid = 0
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Takes any arguments suitable for EM::Callback() and returns a subscriber
|
|
23
|
+
# id for use when unsubscribing.
|
|
24
|
+
def subscribe(*a, &b)
|
|
25
|
+
name = gen_id
|
|
26
|
+
EM.schedule { @subs[name] = EM::Callback(*a, &b) }
|
|
27
|
+
name
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Removes this subscriber from the list.
|
|
31
|
+
def unsubscribe(name)
|
|
32
|
+
EM.schedule { @subs.delete name }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Add items to the channel, which are pushed out to all subscribers.
|
|
36
|
+
def push(*items)
|
|
37
|
+
items = items.dup
|
|
38
|
+
EM.schedule { @subs.values.each { |s| items.each { |i| s.call i } } }
|
|
39
|
+
end
|
|
40
|
+
alias << push
|
|
41
|
+
|
|
42
|
+
# Receive exactly one message from the channel.
|
|
43
|
+
def pop(*a, &b)
|
|
44
|
+
EM.schedule {
|
|
45
|
+
name = subscribe do |*args|
|
|
46
|
+
unsubscribe(name)
|
|
47
|
+
EM::Callback(*a, &b).call(*args)
|
|
48
|
+
end
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
def gen_id # :nodoc:
|
|
54
|
+
@uid += 1
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|