eventmachine 0.7.2 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/EPOLL +142 -0
- data/RELEASE_NOTES +14 -1
- data/ext/cmain.cpp +70 -1
- data/ext/ed.cpp +180 -65
- data/ext/ed.h +95 -17
- data/ext/em.cpp +400 -20
- data/ext/em.h +25 -2
- data/ext/emwin.cpp +2 -2
- data/ext/epoll.cpp +26 -0
- data/ext/epoll.h +25 -0
- data/ext/eventmachine.h +19 -1
- data/ext/extconf.rb +42 -1
- data/ext/files.cpp +2 -2
- data/ext/files.h +1 -1
- data/ext/pipe.cpp +307 -0
- data/ext/project.h +11 -1
- data/ext/rubymain.cpp +97 -5
- data/lib/em/messages.rb +66 -0
- data/lib/eventmachine.rb +522 -397
- data/lib/eventmachine_version.rb +2 -2
- data/lib/protocols/buftok.rb +6 -0
- data/lib/protocols/httpclient.rb +3 -2
- data/lib/protocols/line_and_text.rb +4 -2
- data/tests/test_epoll.rb +154 -0
- data/tests/test_eventables.rb +6 -3
- data/tests/test_httpclient.rb +3 -1
- data/tests/test_ltp.rb +3 -4
- data/tests/test_next_tick.rb +57 -0
- metadata +11 -3
data/ext/project.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: project.h
|
3
|
+
$Id: project.h 401 2007-07-11 12:54:06Z blackhedd $
|
4
4
|
|
5
5
|
File: project.h
|
6
6
|
Date: 06Apr06
|
@@ -28,6 +28,7 @@ See the file COPYING for complete licensing information.
|
|
28
28
|
|
29
29
|
#include <iostream>
|
30
30
|
#include <map>
|
31
|
+
#include <set>
|
31
32
|
#include <vector>
|
32
33
|
#include <deque>
|
33
34
|
#include <string>
|
@@ -41,6 +42,8 @@ See the file COPYING for complete licensing information.
|
|
41
42
|
#include <sys/types.h>
|
42
43
|
#include <sys/socket.h>
|
43
44
|
#include <sys/un.h>
|
45
|
+
#include <sys/resource.h>
|
46
|
+
#include <sys/wait.h>
|
44
47
|
#include <assert.h>
|
45
48
|
#include <unistd.h>
|
46
49
|
#include <fcntl.h>
|
@@ -73,6 +76,7 @@ typedef int SOCKET;
|
|
73
76
|
#include <fcntl.h>
|
74
77
|
#include <assert.h>
|
75
78
|
typedef int socklen_t;
|
79
|
+
typedef int pid_t;
|
76
80
|
#endif
|
77
81
|
|
78
82
|
|
@@ -83,13 +87,19 @@ using namespace std;
|
|
83
87
|
#include <openssl/err.h>
|
84
88
|
#endif
|
85
89
|
|
90
|
+
#ifdef HAVE_EPOLL
|
91
|
+
#include <sys/epoll.h>
|
92
|
+
#endif
|
93
|
+
|
86
94
|
#include "binder.h"
|
87
95
|
#include "em.h"
|
96
|
+
#include "epoll.h"
|
88
97
|
#include "sigs.h"
|
89
98
|
#include "ed.h"
|
90
99
|
#include "files.h"
|
91
100
|
#include "page.h"
|
92
101
|
#include "ssl.h"
|
102
|
+
#include "eventmachine.h"
|
93
103
|
|
94
104
|
|
95
105
|
|
data/ext/rubymain.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: rubymain.cpp
|
3
|
+
$Id: rubymain.cpp 377 2007-06-13 01:05:56Z blackhedd $
|
4
4
|
|
5
5
|
File: rubymain.cpp
|
6
6
|
Date: 06Apr06
|
@@ -28,6 +28,9 @@ Statics
|
|
28
28
|
*******/
|
29
29
|
|
30
30
|
static VALUE EmModule;
|
31
|
+
static VALUE EmConnection;
|
32
|
+
|
33
|
+
static VALUE Intern_at_signature;
|
31
34
|
|
32
35
|
|
33
36
|
/****************
|
@@ -139,6 +142,20 @@ static VALUE t_get_peername (VALUE self, VALUE signature)
|
|
139
142
|
return Qnil;
|
140
143
|
}
|
141
144
|
|
145
|
+
/********************
|
146
|
+
t_get_subprocess_pid
|
147
|
+
********************/
|
148
|
+
|
149
|
+
static VALUE t_get_subprocess_pid (VALUE self, VALUE signature)
|
150
|
+
{
|
151
|
+
pid_t pid;
|
152
|
+
if (evma_get_subprocess_pid (StringValuePtr (signature), &pid)) {
|
153
|
+
return INT2NUM (pid);
|
154
|
+
}
|
155
|
+
|
156
|
+
return Qnil;
|
157
|
+
}
|
158
|
+
|
142
159
|
/*****************************
|
143
160
|
t_get_comm_inactivity_timeout
|
144
161
|
*****************************/
|
@@ -305,6 +322,68 @@ static VALUE t__write_file (VALUE self, VALUE filename)
|
|
305
322
|
return rb_str_new2 (f);
|
306
323
|
}
|
307
324
|
|
325
|
+
/**************
|
326
|
+
t_invoke_popen
|
327
|
+
**************/
|
328
|
+
|
329
|
+
static VALUE t_invoke_popen (VALUE self, VALUE cmd)
|
330
|
+
{
|
331
|
+
int len = RARRAY (cmd)->len;
|
332
|
+
if (len > 98)
|
333
|
+
rb_raise (rb_eRuntimeError, "too many arguments to popen");
|
334
|
+
char *strings [100];
|
335
|
+
for (int i=0; i < len; i++) {
|
336
|
+
VALUE ix = INT2FIX (i);
|
337
|
+
VALUE s = rb_ary_aref (1, &ix, cmd);
|
338
|
+
strings[i] = StringValuePtr (s);
|
339
|
+
}
|
340
|
+
strings[len] = NULL;
|
341
|
+
|
342
|
+
const char *f = evma_popen (strings);
|
343
|
+
if (!f || !*f) {
|
344
|
+
char *err = strerror (errno);
|
345
|
+
char buf[100];
|
346
|
+
memset (buf, 0, sizeof(buf));
|
347
|
+
snprintf (buf, sizeof(buf)-1, "no popen: %s", (err?err:"???"));
|
348
|
+
rb_raise (rb_eRuntimeError, buf);
|
349
|
+
}
|
350
|
+
return rb_str_new2 (f);
|
351
|
+
}
|
352
|
+
|
353
|
+
|
354
|
+
/********
|
355
|
+
t__epoll
|
356
|
+
********/
|
357
|
+
|
358
|
+
static VALUE t__epoll (VALUE self)
|
359
|
+
{
|
360
|
+
// Temporary.
|
361
|
+
evma__epoll();
|
362
|
+
return Qnil;
|
363
|
+
}
|
364
|
+
|
365
|
+
|
366
|
+
/*******************
|
367
|
+
t_set_rlimit_nofile
|
368
|
+
*******************/
|
369
|
+
|
370
|
+
static VALUE t_set_rlimit_nofile (VALUE self, VALUE arg)
|
371
|
+
{
|
372
|
+
arg = (NIL_P(arg)) ? -1 : NUM2INT (arg);
|
373
|
+
return INT2NUM (evma_set_rlimit_nofile (arg));
|
374
|
+
}
|
375
|
+
|
376
|
+
/***************************
|
377
|
+
conn_get_outbound_data_size
|
378
|
+
***************************/
|
379
|
+
|
380
|
+
static VALUE conn_get_outbound_data_size (VALUE self)
|
381
|
+
{
|
382
|
+
VALUE sig = rb_ivar_get (self, Intern_at_signature);
|
383
|
+
return INT2NUM (evma_get_outbound_data_size (StringValuePtr(sig)));
|
384
|
+
}
|
385
|
+
|
386
|
+
|
308
387
|
|
309
388
|
/*********************
|
310
389
|
Init_rubyeventmachine
|
@@ -312,10 +391,19 @@ Init_rubyeventmachine
|
|
312
391
|
|
313
392
|
extern "C" void Init_rubyeventmachine()
|
314
393
|
{
|
394
|
+
// Tuck away some symbol values so we don't have to look 'em up every time we need 'em.
|
395
|
+
Intern_at_signature = rb_intern ("@signature");
|
396
|
+
|
315
397
|
// INCOMPLETE, we need to define class Connections inside module EventMachine
|
316
398
|
// run_machine and run_machine_without_threads are now identical.
|
317
399
|
// Must deprecate the without_threads variant.
|
318
400
|
EmModule = rb_define_module ("EventMachine");
|
401
|
+
EmConnection = rb_define_class_under (EmModule, "Connection", rb_cObject);
|
402
|
+
|
403
|
+
rb_define_class_under (EmModule, "ConnectionNotBound", rb_eException);
|
404
|
+
rb_define_class_under (EmModule, "NoHandlerForAcceptedConnection", rb_eException);
|
405
|
+
rb_define_class_under (EmModule, "UnknownTimerFired", rb_eException);
|
406
|
+
|
319
407
|
rb_define_module_function (EmModule, "initialize_event_machine", (VALUE(*)(...))t_initialize_event_machine, 0);
|
320
408
|
rb_define_module_function (EmModule, "run_machine", (VALUE(*)(...))t_run_machine_without_threads, 0);
|
321
409
|
rb_define_module_function (EmModule, "run_machine_without_threads", (VALUE(*)(...))t_run_machine_without_threads, 0);
|
@@ -335,17 +423,21 @@ extern "C" void Init_rubyeventmachine()
|
|
335
423
|
rb_define_module_function (EmModule, "library_type", (VALUE(*)(...))t_library_type, 0);
|
336
424
|
rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1);
|
337
425
|
rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1);
|
426
|
+
rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1);
|
338
427
|
|
339
|
-
|
428
|
+
// Provisional:
|
340
429
|
rb_define_module_function (EmModule, "_write_file", (VALUE(*)(...))t__write_file, 1);
|
341
430
|
|
342
431
|
rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
|
432
|
+
rb_define_module_function (EmModule, "get_subprocess_pid", (VALUE(*)(...))t_get_subprocess_pid, 1);
|
343
433
|
rb_define_module_function (EmModule, "get_comm_inactivity_timeout", (VALUE(*)(...))t_get_comm_inactivity_timeout, 1);
|
344
434
|
rb_define_module_function (EmModule, "set_comm_inactivity_timeout", (VALUE(*)(...))t_set_comm_inactivity_timeout, 2);
|
435
|
+
rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1);
|
345
436
|
|
346
|
-
|
347
|
-
|
348
|
-
|
437
|
+
// Temporary:
|
438
|
+
rb_define_module_function (EmModule, "epoll", (VALUE(*)(...))t__epoll, 0);
|
439
|
+
|
440
|
+
rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0);
|
349
441
|
|
350
442
|
rb_define_const (EmModule, "TimerFired", INT2NUM(100));
|
351
443
|
rb_define_const (EmModule, "ConnectionData", INT2NUM(101));
|
data/lib/em/messages.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# $Id: messages.rb 349 2007-06-04 17:10:17Z blackhedd $
|
2
|
+
#
|
3
|
+
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
|
+
# Homepage:: http://rubyeventmachine.com
|
5
|
+
# Date:: 16 Jul 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
|
+
=begin
|
27
|
+
|
28
|
+
Message Routing in EventMachine.
|
29
|
+
|
30
|
+
The goal here is to enable "routing points," objects that can send and receive
|
31
|
+
"messages," which are delimited streams of bytes. The boundaries of a message
|
32
|
+
are preserved as it passes through the reactor system.
|
33
|
+
|
34
|
+
There will be several module methods defined in EventMachine to create route-point
|
35
|
+
objects (which will probably have a base class of EventMachine::MessageRouter
|
36
|
+
until someone suggests a better name).
|
37
|
+
|
38
|
+
As with I/O objects, routing objects will receive events by having the router
|
39
|
+
core call methods on them. And of course user code can and will define handlers
|
40
|
+
to deal with events of interest.
|
41
|
+
|
42
|
+
The message router base class only really needs a receive_message method. There will
|
43
|
+
be an EM module-method to send messages, in addition to the module methods to create
|
44
|
+
the various kinds of message receivers.
|
45
|
+
|
46
|
+
The simplest kind of message receiver object can receive messages by being named
|
47
|
+
explicitly in a parameter to EM#send_message. More sophisticated receivers can define
|
48
|
+
pub-sub selectors and message-queue names. And they can also define channels for
|
49
|
+
route-points in other processes or even on other machines.
|
50
|
+
|
51
|
+
A message is NOT a marshallable entity. Rather, it's a chunk of flat content more like
|
52
|
+
an Erlang message. Initially, all content submitted for transmission as a message will
|
53
|
+
have the to_s method called on it. Eventually, we'll be able to transmit certain structured
|
54
|
+
data types (XML and YAML documents, Structs within limits) and have them reconstructed
|
55
|
+
on the other end.
|
56
|
+
|
57
|
+
A fundamental goal of the message-routing capability is to interoperate seamlessly with
|
58
|
+
external systems, including non-Ruby systems like ActiveMQ. We will define various protocol
|
59
|
+
handlers for things like Stomp and possibly AMQP, but these will be wrapped up and hidden
|
60
|
+
from the users of the basic routing capability.
|
61
|
+
|
62
|
+
As with Erlang, a critical goal is for programs that are built to use message-passing to work
|
63
|
+
WITHOUT CHANGE when the code is re-based on a multi-process system.
|
64
|
+
|
65
|
+
=end
|
66
|
+
|
data/lib/eventmachine.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: eventmachine.rb
|
1
|
+
# $Id: eventmachine.rb 393 2007-07-06 06:51:47Z blackhedd $
|
2
2
|
#
|
3
3
|
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
4
|
# Homepage:: http://rubyeventmachine.com
|
@@ -25,6 +25,15 @@
|
|
25
25
|
|
26
26
|
|
27
27
|
#-- Select in a library based on a global variable.
|
28
|
+
# PROVISIONALLY commented out this whole mechanism which selects
|
29
|
+
# a pure-Ruby EM implementation if the extension is not available.
|
30
|
+
# I expect this will cause a lot of people's code to break, as it
|
31
|
+
# exposes misconfigurations and path problems that were masked up
|
32
|
+
# till now. The reason I'm disabling it is because the pure-Ruby
|
33
|
+
# code will have problems of its own, and it's not nearly as fast
|
34
|
+
# anyway. Suggested by a problem report from Moshe Litvin. 05Jun07.
|
35
|
+
|
36
|
+
=begin
|
28
37
|
$eventmachine_library ||= nil
|
29
38
|
case $eventmachine_library
|
30
39
|
when :pure_ruby
|
@@ -40,12 +49,18 @@ else
|
|
40
49
|
require 'pr_eventmachine'
|
41
50
|
end
|
42
51
|
end
|
52
|
+
=end
|
53
|
+
require 'rubyeventmachine'
|
43
54
|
|
44
55
|
|
45
56
|
require "eventmachine_version"
|
46
57
|
require 'em/deferrable'
|
47
58
|
require 'em/future'
|
48
59
|
require 'em/eventable'
|
60
|
+
require 'em/messages'
|
61
|
+
|
62
|
+
require 'shellwords'
|
63
|
+
|
49
64
|
#-- Additional requires are at the BOTTOM of this file, because they
|
50
65
|
#-- depend on stuff defined in here. Refactor that someday.
|
51
66
|
|
@@ -633,220 +648,315 @@ module EventMachine
|
|
633
648
|
end
|
634
649
|
|
635
650
|
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
651
|
+
# EventMachine#open_datagram_socket is for support of UDP-based
|
652
|
+
# protocols. Its usage is similar to that of EventMachine#start_server.
|
653
|
+
# It takes three parameters: an IP address (which must be valid
|
654
|
+
# on the machine which executes the method), a port number,
|
655
|
+
# and an optional Module name which will handle the data.
|
656
|
+
# This method will create a new UDP (datagram) socket and
|
657
|
+
# bind it to the address and port that you specify.
|
658
|
+
# The normal callbacks (see EventMachine#start_server) will
|
659
|
+
# be called as events of interest occur on the newly-created
|
660
|
+
# socket, but there are some differences in how they behave.
|
661
|
+
#
|
662
|
+
# Connection#receive_data will be called when a datagram packet
|
663
|
+
# is received on the socket, but unlike TCP sockets, the message
|
664
|
+
# boundaries of the received data will be respected. In other words,
|
665
|
+
# if the remote peer sent you a datagram of a particular size,
|
666
|
+
# you may rely on Connection#receive_data to give you the
|
667
|
+
# exact data in the packet, with the original data length.
|
668
|
+
# Also observe that Connection#receive_data may be called with a
|
669
|
+
# <i>zero-length</i> data payload, since empty datagrams are permitted
|
670
|
+
# in UDP.
|
671
|
+
#
|
672
|
+
# Connection#send_data is available with UDP packets as with TCP,
|
673
|
+
# but there is an important difference. Because UDP communications
|
674
|
+
# are <i>connectionless,</i> there is no implicit recipient for the packets you
|
675
|
+
# send. Ordinarily you must specify the recipient for each packet you send.
|
676
|
+
# However, EventMachine
|
677
|
+
# provides for the typical pattern of receiving a UDP datagram
|
678
|
+
# from a remote peer, performing some operation, and then sending
|
679
|
+
# one or more packets in response to the same remote peer.
|
680
|
+
# To support this model easily, just use Connection#send_data
|
681
|
+
# in the code that you supply for Connection:receive_data.
|
682
|
+
# EventMachine will
|
683
|
+
# provide an implicit return address for any messages sent to
|
684
|
+
# Connection#send_data within the context of a Connection#receive_data callback,
|
685
|
+
# and your response will automatically go to the correct remote peer.
|
686
|
+
# (TODO: Example-code needed!)
|
687
|
+
#
|
688
|
+
# Observe that the port number that you supply to EventMachine#open_datagram_socket
|
689
|
+
# may be zero. In this case, EventMachine will create a UDP socket
|
690
|
+
# that is bound to an <i>ephemeral</i> (not well-known) port.
|
691
|
+
# This is not appropriate for servers that must publish a well-known
|
692
|
+
# port to which remote peers may send datagrams. But it can be useful
|
693
|
+
# for clients that send datagrams to other servers.
|
694
|
+
# If you do this, you will receive any responses from the remote
|
695
|
+
# servers through the normal Connection#receive_data callback.
|
696
|
+
# Observe that you will probably have issues with firewalls blocking
|
697
|
+
# the ephemeral port numbers, so this technique is most appropriate for LANs.
|
698
|
+
# (TODO: Need an example!)
|
699
|
+
#
|
700
|
+
# If you wish to send datagrams to arbitrary remote peers (not
|
701
|
+
# necessarily ones that have sent data to which you are responding),
|
702
|
+
# then see Connection#send_datagram.
|
703
|
+
#
|
704
|
+
# DO NOT call send_data from a datagram socket
|
705
|
+
# outside of a #receive_data method. Use #send_datagram. If you do use #send_data
|
706
|
+
# outside of a #receive_data method, you'll get a confusing error
|
707
|
+
# because there is no "peer," as #send_data requires. (Inside of #receive_data,
|
708
|
+
# #send_data "fakes" the peer as described above.)
|
709
|
+
#
|
710
|
+
#--
|
711
|
+
# Replaced the implementation on 01Oct06. Thanks to Tobias Gustafsson for pointing
|
712
|
+
# out that this originally did not take a class but only a module.
|
713
|
+
#
|
714
|
+
def self::open_datagram_socket address, port, handler=nil
|
715
|
+
klass = if (handler and handler.is_a?(Class))
|
716
|
+
handler
|
717
|
+
else
|
718
|
+
Class.new( Connection ) {handler and include handler}
|
719
|
+
end
|
699
720
|
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
721
|
+
s = open_udp_socket address, port
|
722
|
+
c = klass.new s
|
723
|
+
@conns[s] = c
|
724
|
+
block_given? and yield c
|
725
|
+
c
|
726
|
+
end
|
727
|
+
|
728
|
+
|
729
|
+
# For advanced users. This function sets the default timer granularity, which by default is
|
730
|
+
# slightly smaller than 100 milliseconds. Call this function to set a higher or lower granularity.
|
731
|
+
# The function affects the behavior of #add_timer and #add_periodic_timer. Most applications
|
732
|
+
# will not need to call this function.
|
733
|
+
#
|
734
|
+
# The argument is a number of milliseconds. Avoid setting the quantum to very low values because
|
735
|
+
# that may reduce performance under some extreme conditions. We recommend that you not set a quantum
|
736
|
+
# lower than 10.
|
737
|
+
#
|
738
|
+
# You may only call this function while an EventMachine loop is running (that is, after a call to
|
739
|
+
# EventMachine#run and before a subsequent call to EventMachine#stop).
|
740
|
+
#
|
741
|
+
def self::set_quantum mills
|
742
|
+
set_timer_quantum mills.to_i
|
743
|
+
end
|
744
|
+
|
745
|
+
|
746
|
+
#--
|
747
|
+
# The is the responder for the loopback-signalled event.
|
748
|
+
# It can be fired either by code running on a separate thread (EM#defer) or on
|
749
|
+
# the main thread (EM#next_tick).
|
750
|
+
# It will often happen that a next_tick handler will reschedule itself. We
|
751
|
+
# consume a duplicate of the tick queue so that tick events scheduled by tick events
|
752
|
+
# have to wait for the next pass through the reactor core.
|
753
|
+
#
|
754
|
+
def self::run_deferred_callbacks # :nodoc:
|
755
|
+
if @resultqueue
|
756
|
+
until @resultqueue.empty?
|
757
|
+
result,cback = @resultqueue.pop
|
758
|
+
cback.call result if cback
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
762
|
+
if (@next_tick_queue ||= []) and @next_tick_queue.length > 0
|
763
|
+
ary = @next_tick_queue.dup
|
764
|
+
@next_tick_queue.clear
|
765
|
+
until ary.empty?
|
766
|
+
cback=ary.pop and cback.call
|
767
|
+
end
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
|
772
|
+
# #defer is for integrating blocking operations into EventMachine's control flow.
|
773
|
+
# Call #defer with one or two blocks, as shown below (the second block is <i>optional</i>):
|
774
|
+
#
|
775
|
+
# operation = proc {
|
776
|
+
# # perform a long-running operation here, such as a database query.
|
777
|
+
# "result" # as usual, the last expression evaluated in the block will be the return value.
|
778
|
+
# }
|
779
|
+
# callback = proc {|result|
|
780
|
+
# # do something with result here, such as send it back to a network client.
|
781
|
+
# }
|
782
|
+
#
|
783
|
+
# EventMachine.defer( operation, callback )
|
784
|
+
#
|
785
|
+
# The action of #defer is to take the block specified in the first parameter (the "operation")
|
786
|
+
# and schedule it for asynchronous execution on an internal thread pool maintained by EventMachine.
|
787
|
+
# When the operation completes, it will pass the result computed by the block (if any)
|
788
|
+
# back to the EventMachine reactor. Then, EventMachine calls the block specified in the
|
789
|
+
# second parameter to #defer (the "callback"), as part of its normal, synchronous
|
790
|
+
# event handling loop. The result computed by the operation block is passed as a parameter
|
791
|
+
# to the callback. You may omit the callback parameter if you don't need to execute any code
|
792
|
+
# after the operation completes.
|
793
|
+
#
|
794
|
+
# <i>Caveats:</i>
|
795
|
+
# This is a <b>provisional</b> implementation and is subject to change.
|
796
|
+
# Note carefully that the code in your deferred operation will be executed on a separate
|
797
|
+
# thread from the main EventMachine processing and all other Ruby threads that may exist in
|
798
|
+
# your program. Also, multiple deferred operations may be running at once! Therefore, you
|
799
|
+
# are responsible for ensuring that your operation code is threadsafe. [Need more explanation
|
800
|
+
# and examples.]
|
801
|
+
# Don't write a deferred operation that will block forever. If so, the current implementation will
|
802
|
+
# not detect the problem, and the thread will never be returned to the pool. EventMachine limits
|
803
|
+
# the number of threads in its pool, so if you do this enough times, your subsequent deferred
|
804
|
+
# operations won't get a chance to run. [We might put in a timer to detect this problem.]
|
805
|
+
#
|
806
|
+
#--
|
807
|
+
# OBSERVE that #next_tick hacks into this mechanism, so don't make any changes here
|
808
|
+
# without syncing there.
|
809
|
+
#
|
810
|
+
# Running with $VERBOSE set to true gives a warning unless all ivars are defined when
|
811
|
+
# they appear in rvalues. But we DON'T ever want to initialize @threadqueue unless we
|
812
|
+
# need it, because the Ruby threads are so heavyweight. We end up with this bizarre
|
813
|
+
# way of initializing @threadqueue because EventMachine is a Module, not a Class, and
|
814
|
+
# has no constructor.
|
815
|
+
#
|
816
|
+
def self::defer op, callback = nil
|
817
|
+
@need_threadqueue ||= 0
|
818
|
+
if @need_threadqueue == 0
|
819
|
+
@need_threadqueue = 1
|
820
|
+
require 'thread'
|
821
|
+
@threadqueue = Queue.new
|
822
|
+
@resultqueue = Queue.new
|
823
|
+
20.times {|ix|
|
824
|
+
Thread.new {
|
825
|
+
my_ix = ix
|
826
|
+
loop {
|
827
|
+
op,cback = @threadqueue.pop
|
828
|
+
result = op.call
|
829
|
+
@resultqueue << [result, cback]
|
830
|
+
EventMachine.signal_loopbreak
|
831
|
+
}
|
832
|
+
}
|
833
|
+
}
|
834
|
+
end
|
835
|
+
|
836
|
+
@threadqueue << [op,callback]
|
837
|
+
end
|
838
|
+
|
839
|
+
# Schedules a proc for execution immediately after the next "turn" through the reactor
|
840
|
+
# core. An advanced technique, this can be useful for improving memory management and/or
|
841
|
+
# application responsiveness, especially when scheduling large amounts of data for
|
842
|
+
# writing to a network connection. TODO, we need a FAQ entry on this subject.
|
843
|
+
#
|
844
|
+
# #next_tick takes either a single argument (which must be a Proc) or a block.
|
845
|
+
# And I'm taking suggestions for a better name for this method.
|
846
|
+
#--
|
847
|
+
# This works by adding to the @resultqueue that's used for #defer.
|
848
|
+
# The general idea is that next_tick is used when we want to give the reactor a chance
|
849
|
+
# to let other operations run, either to balance the load out more evenly, or to let
|
850
|
+
# outbound network buffers drain, or both. So we probably do NOT want to block, and
|
851
|
+
# we probably do NOT want to be spinning any threads. A program that uses next_tick
|
852
|
+
# but not #defer shouldn't suffer the penalty of having Ruby threads running. They're
|
853
|
+
# extremely expensive even if they're just sleeping.
|
854
|
+
#
|
855
|
+
def self::next_tick pr=nil, &block
|
856
|
+
raise "no argument or block given" unless ((pr && pr.respond_to?(:call)) or block)
|
857
|
+
(@next_tick_queue ||= []) << (pr || block)
|
858
|
+
EventMachine.signal_loopbreak
|
706
859
|
=begin
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
@conns[s] = c
|
715
|
-
block_given? and yield c
|
716
|
-
c
|
717
|
-
end
|
860
|
+
(@next_tick_procs ||= []) << (pr || block)
|
861
|
+
if @next_tick_procs.length == 1
|
862
|
+
add_timer(0) {
|
863
|
+
@next_tick_procs.each {|t| t.call}
|
864
|
+
@next_tick_procs.clear
|
865
|
+
}
|
866
|
+
end
|
718
867
|
=end
|
868
|
+
end
|
719
869
|
|
870
|
+
# A wrapper over the setuid system call. Particularly useful when opening a network
|
871
|
+
# server on a privileged port because you can use this call to drop privileges
|
872
|
+
# after opening the port. Also very useful after a call to #set_descriptor_table_size,
|
873
|
+
# which generally requires that you start your process with root privileges.
|
874
|
+
#
|
875
|
+
# This method has no effective implementation on Windows or in the pure-Ruby
|
876
|
+
# implementation of EventMachine.
|
877
|
+
# Call #set_effective_user by passing it a string containing the effective name
|
878
|
+
# of the user whose privilege-level your process should attain.
|
879
|
+
# This method is intended for use in enforcing security requirements, consequently
|
880
|
+
# it will throw a fatal error and end your program if it fails.
|
881
|
+
#
|
882
|
+
def self::set_effective_user username
|
883
|
+
EventMachine::setuid_string username
|
884
|
+
end
|
720
885
|
|
721
|
-
# For advanced users. This function sets the default timer granularity, which by default is
|
722
|
-
# slightly smaller than 100 milliseconds. Call this function to set a higher or lower granularity.
|
723
|
-
# The function affects the behavior of #add_timer and #add_periodic_timer. Most applications
|
724
|
-
# will not need to call this function.
|
725
|
-
#
|
726
|
-
# The argument is a number of milliseconds. Avoid setting the quantum to very low values because
|
727
|
-
# that may reduce performance under some extreme conditions. We recommend that you not set a quantum
|
728
|
-
# lower than 10.
|
729
|
-
#
|
730
|
-
# You MUST call this function while an EventMachine loop is running (that is, after a call to
|
731
|
-
# EventMachine#run and before a subsequent call to EventMachine#stop).
|
732
|
-
#
|
733
|
-
def self::set_quantum mills
|
734
|
-
set_timer_quantum mills.to_i
|
735
|
-
end
|
736
886
|
|
887
|
+
# Sets the maximum number of file or socket descriptors that your process may open.
|
888
|
+
# You can pass this method an integer specifying the new size of the descriptor table.
|
889
|
+
# Returns the new descriptor-table size, which may be less than the number you
|
890
|
+
# requested. If you call this method with no arguments, it will simply return
|
891
|
+
# the current size of the descriptor table without attempting to change it.
|
892
|
+
#
|
893
|
+
# The new limit on open descriptors ONLY applies to sockets and other descriptors
|
894
|
+
# that belong to EventMachine. It has NO EFFECT on the number of descriptors
|
895
|
+
# you can create in ordinary Ruby code.
|
896
|
+
#
|
897
|
+
# Not available on all platforms. Increasing the number of descriptors beyond its
|
898
|
+
# default limit usually requires superuser privileges. (See #set_effective_user
|
899
|
+
# for a way to drop superuser privileges while your program is running.)
|
900
|
+
#
|
901
|
+
def self::set_descriptor_table_size n_descriptors=nil
|
902
|
+
EventMachine::set_rlimit_nofile n_descriptors
|
903
|
+
end
|
737
904
|
|
738
|
-
def self::run_deferred_callbacks # :nodoc:
|
739
|
-
until @resultqueue.empty?
|
740
|
-
result,cback = @resultqueue.pop
|
741
|
-
cback.call result if cback
|
742
|
-
end
|
743
|
-
end
|
744
905
|
|
745
|
-
# #defer is for integrating blocking operations into EventMachine's control flow.
|
746
|
-
# Call #defer with one or two blocks, as shown below (the second block is <i>optional</i>):
|
747
|
-
#
|
748
|
-
# operation = proc {
|
749
|
-
# # perform a long-running operation here, such as a database query.
|
750
|
-
# "result" # as usual, the last expression evaluated in the block will be the return value.
|
751
|
-
# }
|
752
|
-
# callback = proc {|result|
|
753
|
-
# # do something with result here, such as send it back to a network client.
|
754
|
-
# }
|
755
|
-
#
|
756
|
-
# EventMachine.defer( operation, callback )
|
757
|
-
#
|
758
|
-
# The action of #defer is to take the block specified in the first parameter (the "operation")
|
759
|
-
# and schedule it for asynchronous execution on an internal thread pool maintained by EventMachine.
|
760
|
-
# When the operation completes, it will pass the result computed by the block (if any)
|
761
|
-
# back to the EventMachine reactor. Then, EventMachine calls the block specified in the
|
762
|
-
# second parameter to #defer (the "callback"), as part of its normal, synchronous
|
763
|
-
# event handling loop. The result computed by the operation block is passed as a parameter
|
764
|
-
# to the callback. You may omit the callback parameter if you don't need to execute any code
|
765
|
-
# after the operation completes.
|
766
|
-
#
|
767
|
-
# <i>Caveats:</i>
|
768
|
-
# This is a <b>provisional</b> implementation and is subject to change.
|
769
|
-
# Note carefully that the code in your deferred operation will be executed on a separate
|
770
|
-
# thread from the main EventMachine processing and all other Ruby threads that may exist in
|
771
|
-
# your program. Also, multiple deferred operations may be running at once! Therefore, you
|
772
|
-
# are responsible for ensuring that your operation code is threadsafe. [Need more explanation
|
773
|
-
# and examples.]
|
774
|
-
# Don't write a deferred operation that will block forever. If so, the current implementation will
|
775
|
-
# not detect the problem, and the thread will never be returned to the pool. EventMachine limits
|
776
|
-
# the number of threads in its pool, so if you do this enough times, your subsequent deferred
|
777
|
-
# operations won't get a chance to run. [We might put in a timer to detect this problem.]
|
778
|
-
#
|
779
|
-
def self::defer op, callback = nil
|
780
|
-
unless @threadqueue
|
781
|
-
|
782
|
-
#start_server "127.0.0.1", 29999, DeferredTrigger
|
783
|
-
#@deferred_trigger = connect "127.0.0.1", 29999
|
784
|
-
|
785
|
-
require 'thread'
|
786
|
-
@threadqueue = Queue.new
|
787
|
-
@resultqueue = Queue.new
|
788
|
-
20.times {|ix|
|
789
|
-
Thread.new {
|
790
|
-
my_ix = ix
|
791
|
-
loop {
|
792
|
-
op,cback = @threadqueue.pop
|
793
|
-
result = op.call
|
794
|
-
@resultqueue << [result, cback]
|
795
|
-
EventMachine.signal_loopbreak
|
796
|
-
#@deferred_trigger.send_data "."
|
797
|
-
}
|
798
|
-
}
|
799
|
-
}
|
800
|
-
end
|
801
906
|
|
802
|
-
|
803
|
-
|
907
|
+
# TODO, must document popen. At this moment, it's only available on Unix.
|
908
|
+
# This limitation is expected to go away.
|
909
|
+
#--
|
910
|
+
# Perhaps misnamed since the underlying function uses socketpair and is full-duplex.
|
911
|
+
#
|
912
|
+
def self::popen cmd, handler=nil
|
913
|
+
klass = if (handler and handler.is_a?(Class))
|
914
|
+
handler
|
915
|
+
else
|
916
|
+
Class.new( Connection ) {handler and include handler}
|
917
|
+
end
|
804
918
|
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
# it will throw a fatal error and end your program if it fails.
|
814
|
-
def self::set_effective_user username
|
815
|
-
EventMachine::setuid_string username
|
816
|
-
end
|
919
|
+
w = Shellwords::shellwords( cmd )
|
920
|
+
w.unshift( w.first ) if w.first
|
921
|
+
s = invoke_popen( w )
|
922
|
+
c = klass.new s
|
923
|
+
@conns[s] = c
|
924
|
+
yield(c) if block_given?
|
925
|
+
c
|
926
|
+
end
|
817
927
|
|
818
928
|
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
929
|
+
|
930
|
+
private
|
931
|
+
def EventMachine::event_callback conn_binding, opcode, data
|
932
|
+
if opcode == ConnectionData
|
933
|
+
c = @conns[conn_binding] or raise ConnectionNotBound
|
934
|
+
c.receive_data data
|
935
|
+
elsif opcode == ConnectionUnbound
|
936
|
+
if c = @conns.delete( conn_binding )
|
937
|
+
c.unbind
|
938
|
+
elsif c = @acceptors.delete( conn_binding )
|
939
|
+
# no-op
|
940
|
+
else
|
941
|
+
raise ConnectionNotBound
|
942
|
+
end
|
943
|
+
elsif opcode == ConnectionAccepted
|
944
|
+
accep,blk = @acceptors[conn_binding]
|
945
|
+
raise NoHandlerForAcceptedConnection unless accep
|
946
|
+
c = accep.new data
|
947
|
+
@conns[data] = c
|
948
|
+
blk and blk.call(c)
|
949
|
+
c # (needed?)
|
950
|
+
elsif opcode == TimerFired
|
951
|
+
t = @timers.delete( data ) or raise UnknownTimerFired
|
952
|
+
t.call
|
953
|
+
elsif opcode == ConnectionCompleted
|
954
|
+
c = @conns[conn_binding] or raise ConnectionNotBound
|
955
|
+
c.connection_completed
|
956
|
+
elsif opcode == LoopbreakSignalled
|
957
|
+
run_deferred_callbacks
|
958
|
+
end
|
959
|
+
end
|
850
960
|
|
851
961
|
|
852
962
|
# Documentation stub
|
@@ -896,220 +1006,229 @@ module EventMachine
|
|
896
1006
|
#
|
897
1007
|
class Connection
|
898
1008
|
|
899
|
-
|
900
|
-
|
1009
|
+
# EXPERIMENTAL. Added the reconnect methods, which may go away.
|
1010
|
+
attr_accessor :signature
|
901
1011
|
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
1012
|
+
def initialize sig #:nodoc:
|
1013
|
+
@signature = sig
|
1014
|
+
post_init
|
1015
|
+
end
|
906
1016
|
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
1017
|
+
# EventMachine::Connection#post_init is called by the event loop
|
1018
|
+
# immediately after the network connection has been established,
|
1019
|
+
# and before resumption of the network loop.
|
1020
|
+
# This method is generally not called by user code, but is called automatically
|
1021
|
+
# by the event loop. The base-class implementation is a no-op.
|
1022
|
+
# This is a very good place to initialize instance variables that will
|
1023
|
+
# be used throughout the lifetime of the network connection.
|
1024
|
+
#
|
1025
|
+
def post_init
|
1026
|
+
end
|
917
1027
|
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
1028
|
+
# EventMachine::Connection#receive_data is called by the event loop
|
1029
|
+
# whenever data has been received by the network connection.
|
1030
|
+
# It is never called by user code.
|
1031
|
+
# receive_data is called with a single parameter, a String containing
|
1032
|
+
# the network protocol data, which may of course be binary. You will
|
1033
|
+
# generally redefine this method to perform your own processing of the incoming data.
|
1034
|
+
#
|
1035
|
+
# Here's a key point which is essential to understanding the event-driven
|
1036
|
+
# programming model: <i>EventMachine knows absolutely nothing about the protocol
|
1037
|
+
# which your code implements.</i> You must not make any assumptions about
|
1038
|
+
# the size of the incoming data packets, or about their alignment on any
|
1039
|
+
# particular intra-message or PDU boundaries (such as line breaks).
|
1040
|
+
# receive_data can and will send you arbitrary chunks of data, with the
|
1041
|
+
# only guarantee being that the data is presented to your code in the order
|
1042
|
+
# it was collected from the network. Don't even assume that the chunks of
|
1043
|
+
# data will correspond to network packets, as EventMachine can and will coalesce
|
1044
|
+
# several incoming packets into one, to improve performance. The implication for your
|
1045
|
+
# code is that you generally will need to implement some kind of a state machine
|
1046
|
+
# in your redefined implementation of receive_data. For a better understanding
|
1047
|
+
# of this, read through the examples of specific protocol handlers given
|
1048
|
+
# elsewhere in this package. (STUB, WE MUST ADD THESE!)
|
1049
|
+
#
|
1050
|
+
# The base-class implementation of receive_data (which will be invoked if
|
1051
|
+
# you don't redefine it) simply prints the size of each incoming data packet
|
1052
|
+
# to stdout.
|
1053
|
+
#
|
1054
|
+
def receive_data data
|
1055
|
+
puts "............>>>#{data.length}"
|
1056
|
+
end
|
947
1057
|
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
1058
|
+
# EventMachine::Connection#unbind is called by the framework whenever a connection
|
1059
|
+
# (either a server or client connection) is closed. The close can occur because
|
1060
|
+
# your code intentionally closes it (see close_connection and close_connection_after_writing),
|
1061
|
+
# because the remote peer closed the connection, or because of a network error.
|
1062
|
+
# You may not assume that the network connection is still open and able to send or
|
1063
|
+
# receive data when the callback to unbind is made. This is intended only to give
|
1064
|
+
# you a chance to clean up associations your code may have made to the connection
|
1065
|
+
# object while it was open.
|
1066
|
+
#
|
1067
|
+
def unbind
|
1068
|
+
end
|
959
1069
|
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
1070
|
+
# EventMachine::Connection#close_connection is called only by user code, and never
|
1071
|
+
# by the event loop. You may call this method against a connection object in any
|
1072
|
+
# callback handler, whether or not the callback was made against the connection
|
1073
|
+
# you want to close. close_connection <i>schedules</i> the connection to be closed
|
1074
|
+
# at the next available opportunity within the event loop. You may not assume that
|
1075
|
+
# the connection is closed when close_connection returns. In particular, the framework
|
1076
|
+
# will callback the unbind method for the particular connection at a point shortly
|
1077
|
+
# after you call close_connection. You may assume that the unbind callback will
|
1078
|
+
# take place sometime after your call to close_connection completes. In other words,
|
1079
|
+
# the unbind callback will not re-enter your code "inside" of your call to close_connection.
|
1080
|
+
# However, it's not guaranteed that a future version of EventMachine will not change
|
1081
|
+
# this behavior.
|
1082
|
+
#
|
1083
|
+
# close_connection will <i>silently discard</i> any outbound data which you have
|
1084
|
+
# sent to the connection using EventMachine::Connection#send_data but which has not
|
1085
|
+
# yet been sent across the network. If you want to avoid this behavior, use
|
1086
|
+
# EventMachine::Connection#close_connection_after_writing.
|
1087
|
+
#
|
1088
|
+
def close_connection after_writing = false
|
1089
|
+
EventMachine::close_connection @signature, after_writing
|
1090
|
+
end
|
981
1091
|
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1092
|
+
# EventMachine::Connection#close_connection_after_writing is a variant of close_connection.
|
1093
|
+
# All of the descriptive comments given for close_connection also apply to
|
1094
|
+
# close_connection_after_writing, <i>with one exception:</i> If the connection has
|
1095
|
+
# outbound data sent using send_dat but which has not yet been sent across the network,
|
1096
|
+
# close_connection_after_writing will schedule the connection to be closed <i>after</i>
|
1097
|
+
# all of the outbound data has been safely written to the remote peer.
|
1098
|
+
#
|
1099
|
+
# Depending on the amount of outgoing data and the speed of the network,
|
1100
|
+
# considerable time may elapse between your call to close_connection_after_writing
|
1101
|
+
# and the actual closing of the socket (at which time the unbind callback will be called
|
1102
|
+
# by the event loop). During this time, you <i>may not</i> call send_data to transmit
|
1103
|
+
# additional data (that is, the connection is closed for further writes). In very
|
1104
|
+
# rare cases, you may experience a receive_data callback after your call to close_connection_after_writing,
|
1105
|
+
# depending on whether incoming data was in the process of being received on the connection
|
1106
|
+
# at the moment when you called close_connection_after_writing. Your protocol handler must
|
1107
|
+
# be prepared to properly deal with such data (probably by ignoring it).
|
1108
|
+
#
|
1109
|
+
def close_connection_after_writing
|
1110
|
+
close_connection true
|
1111
|
+
end
|
1002
1112
|
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1113
|
+
# EventMachine::Connection#send_data is only called by user code, never by
|
1114
|
+
# the event loop. You call this method to send data to the remote end of the
|
1115
|
+
# network connection. send_data is called with a single String argument, which
|
1116
|
+
# may of course contain binary data. You can call send_data any number of times.
|
1117
|
+
# send_data is an instance method of an object derived from EventMachine::Connection
|
1118
|
+
# and containing your mixed-in handler code), so if you call it without qualification
|
1119
|
+
# within a callback function, the data will be sent to the same network connection
|
1120
|
+
# that generated the callback. Calling self.send_data is exactly equivalent.
|
1121
|
+
#
|
1122
|
+
# You can also call send_data to write to a connection <i>other than the one
|
1123
|
+
# whose callback you are calling send_data from.</i> This is done by recording
|
1124
|
+
# the value of the connection in any callback function (the value self), in any
|
1125
|
+
# variable visible to other callback invocations on the same or different
|
1126
|
+
# connection objects. (Need an example to make that clear.)
|
1127
|
+
#
|
1128
|
+
def send_data data
|
1129
|
+
EventMachine::send_data @signature, data, data.length
|
1130
|
+
end
|
1021
1131
|
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1132
|
+
# #connection_completed is called by the event loop when a remote TCP connection
|
1133
|
+
# attempt completes successfully. You can expect to get this notification after calls
|
1134
|
+
# to EventMachine#connect. Remember that EventMachine makes remote connections
|
1135
|
+
# asynchronously, just as with any other kind of network event. #connection_completed
|
1136
|
+
# is intended primarily to assist with network diagnostics. For normal protocol
|
1137
|
+
# handling, use #post_init to perform initial work on a new connection (such as
|
1138
|
+
# send an initial set of data).
|
1139
|
+
# #post_init will always be called. #connection_completed will only be called in case
|
1140
|
+
# of a successful completion. A connection-attempt which fails will receive a call
|
1141
|
+
# to #unbind after the failure.
|
1142
|
+
def connection_completed
|
1143
|
+
end
|
1034
1144
|
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1145
|
+
# Call #start_tls at any point to initiate TLS encryption on connected streams.
|
1146
|
+
# The method is smart enough to know whether it should perform a server-side
|
1147
|
+
# or a client-side handshake. An appropriate place to call #start_tls is in
|
1148
|
+
# your redefined #post_init method.
|
1149
|
+
#
|
1150
|
+
def start_tls
|
1151
|
+
EventMachine::start_tls @signature
|
1152
|
+
end
|
1043
1153
|
|
1044
1154
|
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1155
|
+
# send_datagram is for sending UDP messages.
|
1156
|
+
# This method may be called from any Connection object that refers
|
1157
|
+
# to an open datagram socket (see EventMachine#open_datagram_socket).
|
1158
|
+
# The method sends a UDP (datagram) packet containing the data you specify,
|
1159
|
+
# to a remote peer specified by the IP address and port that you give
|
1160
|
+
# as parameters to the method.
|
1161
|
+
# Observe that you may send a zero-length packet (empty string).
|
1162
|
+
# However, you may not send an arbitrarily-large data packet because
|
1163
|
+
# your operating system will enforce a platform-specific limit on
|
1164
|
+
# the size of the outbound packet. (Your kernel
|
1165
|
+
# will respond in a platform-specific way if you send an overlarge
|
1166
|
+
# packet: some will send a truncated packet, some will complain, and
|
1167
|
+
# some will silently drop your request).
|
1168
|
+
# On LANs, it's usually OK to send datagrams up to about 4000 bytes in length,
|
1169
|
+
# but to be really safe, send messages smaller than the Ethernet-packet
|
1170
|
+
# size (typically about 1400 bytes). Some very restrictive WANs
|
1171
|
+
# will either drop or truncate packets larger than about 500 bytes.
|
1172
|
+
#
|
1173
|
+
def send_datagram data, recipient_address, recipient_port
|
1174
|
+
data = data.to_s
|
1175
|
+
EventMachine::send_datagram @signature, data, data.length, recipient_address, recipient_port
|
1176
|
+
end
|
1067
1177
|
|
1068
1178
|
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1179
|
+
# #get_peername is used with stream-connections to obtain the identity
|
1180
|
+
# of the remotely-connected peer. If a peername is available, this method
|
1181
|
+
# returns a sockaddr structure. The method returns nil if no peername is available.
|
1182
|
+
# You can use Socket#unpack_sockaddr_in and its variants to obtain the
|
1183
|
+
# values contained in the peername structure returned from #get_peername.
|
1184
|
+
def get_peername
|
1185
|
+
EventMachine::get_peername @signature
|
1186
|
+
end
|
1077
1187
|
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1188
|
+
# Returns the PID (kernel process identifier) of a subprocess
|
1189
|
+
# associated with this Connection object. For use with EventMachine#popen
|
1190
|
+
# and similar methods. Returns nil when there is no meaningful subprocess.
|
1191
|
+
#--
|
1192
|
+
#
|
1193
|
+
def get_pid
|
1194
|
+
EventMachine::get_subprocess_pid @signature
|
1195
|
+
end
|
1086
1196
|
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1197
|
+
# comm_inactivity_timeout returns the current value (in seconds) of the inactivity-timeout
|
1198
|
+
# property of network-connection and datagram-socket objects. A nonzero value
|
1199
|
+
# indicates that the connection or socket will automatically be closed if no read or write
|
1200
|
+
# activity takes place for at least that number of seconds.
|
1201
|
+
# A zero value (the default) specifies that no automatic timeout will take place.
|
1202
|
+
def comm_inactivity_timeout
|
1203
|
+
EventMachine::get_comm_inactivity_timeout @signature
|
1204
|
+
end
|
1091
1205
|
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
# Specify a value of zero to indicate that no automatic timeout should take place.
|
1097
|
-
# Zero is the default value.
|
1098
|
-
def set_comm_inactivity_timeout value
|
1099
|
-
EventMachine::set_comm_inactivity_timeout @signature, value
|
1100
|
-
end
|
1206
|
+
# Alias for #set_comm_inactivity_timeout.
|
1207
|
+
def comm_inactivity_timeout= value
|
1208
|
+
self.send :set_comm_inactivity_timeout, value
|
1209
|
+
end
|
1101
1210
|
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1211
|
+
# comm_inactivity_timeout= allows you to set the inactivity-timeout property for
|
1212
|
+
# a network connection or datagram socket. Specify a non-negative numeric value in seconds.
|
1213
|
+
# If the value is greater than zero, the connection or socket will automatically be closed
|
1214
|
+
# if no read or write activity takes place for at least that number of seconds.
|
1215
|
+
# Specify a value of zero to indicate that no automatic timeout should take place.
|
1216
|
+
# Zero is the default value.
|
1217
|
+
def set_comm_inactivity_timeout value
|
1218
|
+
EventMachine::set_comm_inactivity_timeout @signature, value
|
1219
|
+
end
|
1220
|
+
|
1221
|
+
#--
|
1222
|
+
# EXPERIMENTAL. DO NOT RELY ON THIS METHOD TO REMAIN SUPPORTED.
|
1223
|
+
# (03Nov06)
|
1224
|
+
def reconnect server, port
|
1225
|
+
EventMachine::reconnect server, port, self
|
1226
|
+
end
|
1108
1227
|
|
1109
1228
|
|
1110
1229
|
|
1111
1230
|
|
1112
|
-
#
|
1231
|
+
# TODO, document this
|
1113
1232
|
#
|
1114
1233
|
#
|
1115
1234
|
class EventMachine::PeriodicTimer
|
@@ -1130,7 +1249,7 @@ class Connection
|
|
1130
1249
|
end
|
1131
1250
|
end
|
1132
1251
|
|
1133
|
-
#
|
1252
|
+
# TODO, document this
|
1134
1253
|
#
|
1135
1254
|
#
|
1136
1255
|
class EventMachine::Timer
|
@@ -1150,6 +1269,12 @@ end
|
|
1150
1269
|
|
1151
1270
|
end # module EventMachine
|
1152
1271
|
|
1272
|
+
|
1273
|
+
|
1274
|
+
# Save everyone some typing.
|
1275
|
+
EM = EventMachine
|
1276
|
+
|
1277
|
+
|
1153
1278
|
# At the bottom of this module, we load up protocol handlers that depend on some
|
1154
1279
|
# of the classes defined here. Eventually we should refactor this out so it's
|
1155
1280
|
# laid out in a more logical way.
|