eventmachine-eventmachine 0.12.7 → 0.12.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/{docs/README → README} +21 -13
  2. data/Rakefile +14 -4
  3. data/docs/DEFERRABLES +0 -5
  4. data/docs/INSTALL +2 -4
  5. data/docs/LEGAL +1 -1
  6. data/docs/LIGHTWEIGHT_CONCURRENCY +0 -2
  7. data/docs/PURE_RUBY +0 -2
  8. data/docs/RELEASE_NOTES +0 -2
  9. data/docs/SMTP +0 -7
  10. data/docs/SPAWNED_PROCESSES +0 -4
  11. data/docs/TODO +0 -2
  12. data/eventmachine.gemspec +17 -8
  13. data/examples/ex_channel.rb +43 -0
  14. data/examples/ex_queue.rb +2 -0
  15. data/examples/helper.rb +2 -0
  16. data/ext/cmain.cpp +119 -20
  17. data/ext/cplusplus.cpp +15 -6
  18. data/ext/ed.cpp +303 -93
  19. data/ext/ed.h +49 -22
  20. data/ext/em.cpp +368 -42
  21. data/ext/em.h +43 -6
  22. data/ext/eventmachine.h +21 -8
  23. data/ext/eventmachine_cpp.h +1 -0
  24. data/ext/extconf.rb +4 -0
  25. data/ext/kb.cpp +1 -2
  26. data/ext/pipe.cpp +1 -3
  27. data/ext/project.h +21 -0
  28. data/ext/rubymain.cpp +232 -32
  29. data/ext/ssl.cpp +38 -1
  30. data/ext/ssl.h +5 -1
  31. data/java/src/com/rubyeventmachine/Application.java +7 -3
  32. data/java/src/com/rubyeventmachine/EmReactor.java +16 -1
  33. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +25 -3
  34. data/lib/{protocols → em}/buftok.rb +16 -5
  35. data/lib/em/callback.rb +26 -0
  36. data/lib/em/channel.rb +57 -0
  37. data/lib/em/connection.rb +505 -0
  38. data/lib/em/deferrable.rb +144 -165
  39. data/lib/em/file_watch.rb +54 -0
  40. data/lib/em/future.rb +24 -25
  41. data/lib/em/messages.rb +1 -1
  42. data/lib/em/process_watch.rb +44 -0
  43. data/lib/em/processes.rb +58 -52
  44. data/lib/em/protocols/header_and_content.rb +138 -0
  45. data/lib/em/protocols/httpclient.rb +263 -0
  46. data/lib/em/protocols/httpclient2.rb +582 -0
  47. data/lib/{protocols → em/protocols}/line_and_text.rb +2 -2
  48. data/lib/em/protocols/linetext2.rb +160 -0
  49. data/lib/{protocols → em/protocols}/memcache.rb +37 -7
  50. data/lib/em/protocols/object_protocol.rb +39 -0
  51. data/lib/em/protocols/postgres3.rb +247 -0
  52. data/lib/em/protocols/saslauth.rb +175 -0
  53. data/lib/em/protocols/smtpclient.rb +331 -0
  54. data/lib/em/protocols/smtpserver.rb +547 -0
  55. data/lib/em/protocols/stomp.rb +200 -0
  56. data/lib/{protocols → em/protocols}/tcptest.rb +21 -25
  57. data/lib/em/protocols.rb +35 -0
  58. data/lib/em/queue.rb +61 -0
  59. data/lib/em/spawnable.rb +53 -56
  60. data/lib/em/streamer.rb +92 -74
  61. data/lib/em/timers.rb +55 -0
  62. data/lib/em/version.rb +3 -0
  63. data/lib/eventmachine.rb +1008 -1298
  64. data/lib/evma.rb +1 -1
  65. data/lib/jeventmachine.rb +106 -101
  66. data/lib/pr_eventmachine.rb +47 -36
  67. data/tasks/project.rake +2 -1
  68. data/tests/client.crt +31 -0
  69. data/tests/client.key +51 -0
  70. data/tests/test_attach.rb +18 -0
  71. data/tests/test_basic.rb +108 -54
  72. data/tests/test_channel.rb +63 -0
  73. data/tests/test_connection_count.rb +2 -2
  74. data/tests/test_epoll.rb +109 -110
  75. data/tests/test_errors.rb +36 -36
  76. data/tests/test_exc.rb +22 -25
  77. data/tests/test_file_watch.rb +49 -0
  78. data/tests/test_futures.rb +77 -93
  79. data/tests/test_hc.rb +2 -2
  80. data/tests/test_httpclient.rb +55 -52
  81. data/tests/test_httpclient2.rb +110 -112
  82. data/tests/test_inactivity_timeout.rb +30 -0
  83. data/tests/test_kb.rb +8 -9
  84. data/tests/test_ltp2.rb +274 -277
  85. data/tests/test_next_tick.rb +91 -65
  86. data/tests/test_object_protocol.rb +37 -0
  87. data/tests/test_process_watch.rb +48 -0
  88. data/tests/test_processes.rb +56 -23
  89. data/tests/test_proxy_connection.rb +92 -0
  90. data/tests/test_pure.rb +1 -5
  91. data/tests/test_queue.rb +44 -0
  92. data/tests/test_running.rb +9 -14
  93. data/tests/test_sasl.rb +32 -34
  94. data/tests/test_send_file.rb +175 -176
  95. data/tests/test_servers.rb +37 -41
  96. data/tests/test_smtpserver.rb +47 -55
  97. data/tests/test_spawn.rb +284 -291
  98. data/tests/test_ssl_args.rb +1 -1
  99. data/tests/test_ssl_methods.rb +1 -1
  100. data/tests/test_ssl_verify.rb +82 -0
  101. data/tests/test_timers.rb +81 -88
  102. data/tests/test_ud.rb +0 -7
  103. data/tests/testem.rb +1 -1
  104. metadata +53 -37
  105. data/lib/em/eventable.rb +0 -39
  106. data/lib/eventmachine_version.rb +0 -31
  107. data/lib/protocols/header_and_content.rb +0 -129
  108. data/lib/protocols/httpcli2.rb +0 -803
  109. data/lib/protocols/httpclient.rb +0 -270
  110. data/lib/protocols/linetext2.rb +0 -161
  111. data/lib/protocols/postgres.rb +0 -261
  112. data/lib/protocols/saslauth.rb +0 -179
  113. data/lib/protocols/smtpclient.rb +0 -308
  114. data/lib/protocols/smtpserver.rb +0 -556
  115. data/lib/protocols/stomp.rb +0 -153
  116. 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
- # Note added by FC, 10Jul07. This paragraph contains a regression. It breaks
80
- # empty tokens. Think of the empty line that delimits an HTTP header. It will have
81
- # two "\n" delimiters in a row, and this code mishandles the resulting empty token.
82
- # It someone figures out how to fix the problem, we can re-enable this code branch.
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
@@ -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