eventmachine 1.0.0.beta.4-java → 1.0.0-java
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/Rakefile +11 -10
- data/eventmachine.gemspec +1 -1
- data/ext/cmain.cpp +38 -0
- data/ext/ed.cpp +18 -1
- data/ext/ed.h +5 -0
- data/ext/em.cpp +40 -19
- data/ext/em.h +3 -2
- data/ext/eventmachine.h +4 -0
- data/ext/extconf.rb +23 -4
- data/ext/fastfilereader/extconf.rb +20 -2
- data/ext/project.h +2 -1
- data/ext/rubymain.cpp +69 -19
- data/ext/ssl.cpp +4 -1
- data/java/src/com/rubyeventmachine/EmReactor.java +4 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +1 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +6 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +6 -0
- data/lib/em/connection.rb +11 -0
- data/lib/em/pool.rb +7 -2
- data/lib/em/protocols/smtpclient.rb +28 -28
- data/lib/em/threaded_resource.rb +1 -1
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +57 -11
- data/lib/jeventmachine.rb +5 -0
- data/{tasks → rakelib}/cpp.rake_example +0 -0
- data/{tasks → rakelib}/package.rake +1 -1
- data/{tasks → rakelib}/test.rake +0 -0
- data/tests/test_basic.rb +67 -0
- data/tests/test_idle_connection.rb +23 -0
- data/tests/test_pool.rb +67 -1
- data/tests/test_proxy_connection.rb +13 -1
- data/tests/test_unbind_reason.rb +19 -2
- metadata +12 -13
@@ -17,7 +17,7 @@ add_define 'BUILD_FOR_RUBY'
|
|
17
17
|
# Minor platform details between *nix and Windows:
|
18
18
|
|
19
19
|
if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
|
20
|
-
GNU_CHAIN = $1 == 'mingw'
|
20
|
+
GNU_CHAIN = ENV['CROSS_COMPILING'] or $1 == 'mingw'
|
21
21
|
OS_WIN32 = true
|
22
22
|
add_define "OS_WIN32"
|
23
23
|
else
|
@@ -26,6 +26,15 @@ else
|
|
26
26
|
add_define 'OS_UNIX'
|
27
27
|
end
|
28
28
|
|
29
|
+
# Adjust number of file descriptors (FD) on Windows
|
30
|
+
|
31
|
+
if RbConfig::CONFIG["host_os"] =~ /mingw/
|
32
|
+
found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS").
|
33
|
+
any? { |v| v.include?("FD_SETSIZE") }
|
34
|
+
|
35
|
+
add_define "FD_SETSIZE=32767" unless found
|
36
|
+
end
|
37
|
+
|
29
38
|
# Main platform invariances:
|
30
39
|
|
31
40
|
case RUBY_PLATFORM
|
@@ -77,9 +86,18 @@ when /aix/
|
|
77
86
|
# on Unix we need a g++ link, not gcc.
|
78
87
|
CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G"
|
79
88
|
|
89
|
+
when /cygwin/
|
90
|
+
# For rubies built with Cygwin, CXX may be set to CC, which is just
|
91
|
+
# a wrapper for gcc.
|
92
|
+
# This will compile, but it will not link to the C++ std library.
|
93
|
+
# Explicitly set CXX to use g++.
|
94
|
+
CONFIG['CXX'] = "g++"
|
95
|
+
# on Unix we need a g++ link, not gcc.
|
96
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
97
|
+
|
80
98
|
else
|
81
99
|
# on Unix we need a g++ link, not gcc.
|
82
100
|
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
83
101
|
end
|
84
102
|
|
85
|
-
create_makefile "fastfilereaderext"
|
103
|
+
create_makefile "fastfilereaderext"
|
data/ext/project.h
CHANGED
@@ -82,7 +82,8 @@ typedef int SOCKET;
|
|
82
82
|
|
83
83
|
#ifdef OS_WIN32
|
84
84
|
// 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h)
|
85
|
-
|
85
|
+
// 18Jun12: fd_setsize must be changed in the ruby binary (not in this extension). redefining it also causes segvs, see eventmachine/eventmachine#333
|
86
|
+
//#define FD_SETSIZE 1024
|
86
87
|
|
87
88
|
#define WIN32_LEAN_AND_MEAN
|
88
89
|
#include <windows.h>
|
data/ext/rubymain.cpp
CHANGED
@@ -233,7 +233,7 @@ static VALUE t_add_oneshot_timer (VALUE self, VALUE interval)
|
|
233
233
|
{
|
234
234
|
const unsigned long f = evma_install_oneshot_timer (FIX2INT (interval));
|
235
235
|
if (!f)
|
236
|
-
rb_raise (rb_eRuntimeError, "ran out of timers; use #set_max_timers to increase limit");
|
236
|
+
rb_raise (rb_eRuntimeError, "%s", "ran out of timers; use #set_max_timers to increase limit");
|
237
237
|
return ULONG2NUM (f);
|
238
238
|
}
|
239
239
|
|
@@ -246,7 +246,7 @@ static VALUE t_start_server (VALUE self, VALUE server, VALUE port)
|
|
246
246
|
{
|
247
247
|
const unsigned long f = evma_create_tcp_server (StringValuePtr(server), FIX2INT(port));
|
248
248
|
if (!f)
|
249
|
-
rb_raise (rb_eRuntimeError, "no acceptor (port is in use or requires root privileges)");
|
249
|
+
rb_raise (rb_eRuntimeError, "%s", "no acceptor (port is in use or requires root privileges)");
|
250
250
|
return ULONG2NUM (f);
|
251
251
|
}
|
252
252
|
|
@@ -269,7 +269,7 @@ static VALUE t_start_unix_server (VALUE self, VALUE filename)
|
|
269
269
|
{
|
270
270
|
const unsigned long f = evma_create_unix_domain_server (StringValuePtr(filename));
|
271
271
|
if (!f)
|
272
|
-
rb_raise (rb_eRuntimeError, "no unix-domain acceptor");
|
272
|
+
rb_raise (rb_eRuntimeError, "%s", "no unix-domain acceptor");
|
273
273
|
return ULONG2NUM (f);
|
274
274
|
}
|
275
275
|
|
@@ -504,10 +504,10 @@ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port)
|
|
504
504
|
try {
|
505
505
|
const unsigned long f = evma_connect_to_server (NULL, 0, StringValuePtr(server), NUM2INT(port));
|
506
506
|
if (!f)
|
507
|
-
rb_raise (EM_eConnectionError, "no connection");
|
507
|
+
rb_raise (EM_eConnectionError, "%s", "no connection");
|
508
508
|
return ULONG2NUM (f);
|
509
509
|
} catch (std::runtime_error e) {
|
510
|
-
rb_raise (EM_eConnectionError, e.what());
|
510
|
+
rb_raise (EM_eConnectionError, "%s", e.what());
|
511
511
|
}
|
512
512
|
return Qnil;
|
513
513
|
}
|
@@ -525,10 +525,10 @@ static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port
|
|
525
525
|
try {
|
526
526
|
const unsigned long f = evma_connect_to_server (StringValuePtr(bind_addr), NUM2INT(bind_port), StringValuePtr(server), NUM2INT(port));
|
527
527
|
if (!f)
|
528
|
-
rb_raise (EM_eConnectionError, "no connection");
|
528
|
+
rb_raise (EM_eConnectionError, "%s", "no connection");
|
529
529
|
return ULONG2NUM (f);
|
530
530
|
} catch (std::runtime_error e) {
|
531
|
-
rb_raise (EM_eConnectionError, e.what());
|
531
|
+
rb_raise (EM_eConnectionError, "%s", e.what());
|
532
532
|
}
|
533
533
|
return Qnil;
|
534
534
|
}
|
@@ -541,7 +541,7 @@ static VALUE t_connect_unix_server (VALUE self, VALUE serversocket)
|
|
541
541
|
{
|
542
542
|
const unsigned long f = evma_connect_to_unix_server (StringValuePtr(serversocket));
|
543
543
|
if (!f)
|
544
|
-
rb_raise (rb_eRuntimeError, "no connection");
|
544
|
+
rb_raise (rb_eRuntimeError, "%s", "no connection");
|
545
545
|
return ULONG2NUM (f);
|
546
546
|
}
|
547
547
|
|
@@ -553,7 +553,7 @@ static VALUE t_attach_fd (VALUE self, VALUE file_descriptor, VALUE watch_mode)
|
|
553
553
|
{
|
554
554
|
const unsigned long f = evma_attach_fd (NUM2INT(file_descriptor), watch_mode == Qtrue);
|
555
555
|
if (!f)
|
556
|
-
rb_raise (rb_eRuntimeError, "no connection");
|
556
|
+
rb_raise (rb_eRuntimeError, "%s", "no connection");
|
557
557
|
return ULONG2NUM (f);
|
558
558
|
}
|
559
559
|
|
@@ -686,6 +686,15 @@ static VALUE t_paused_p (VALUE self, VALUE signature)
|
|
686
686
|
return evma_is_paused(NUM2ULONG (signature)) ? Qtrue : Qfalse;
|
687
687
|
}
|
688
688
|
|
689
|
+
/*********************
|
690
|
+
t_num_close_scheduled
|
691
|
+
*********************/
|
692
|
+
|
693
|
+
static VALUE t_num_close_scheduled (VALUE self)
|
694
|
+
{
|
695
|
+
return INT2FIX(evma_num_close_scheduled());
|
696
|
+
}
|
697
|
+
|
689
698
|
/*****************
|
690
699
|
t_open_udp_socket
|
691
700
|
*****************/
|
@@ -694,7 +703,7 @@ static VALUE t_open_udp_socket (VALUE self, VALUE server, VALUE port)
|
|
694
703
|
{
|
695
704
|
const unsigned long f = evma_open_datagram_socket (StringValuePtr(server), FIX2INT(port));
|
696
705
|
if (!f)
|
697
|
-
rb_raise (rb_eRuntimeError, "no datagram socket");
|
706
|
+
rb_raise (rb_eRuntimeError, "%s", "no datagram socket");
|
698
707
|
return ULONG2NUM (f);
|
699
708
|
}
|
700
709
|
|
@@ -796,7 +805,7 @@ static VALUE t_invoke_popen (VALUE self, VALUE cmd)
|
|
796
805
|
int len = RARRAY (cmd)->len;
|
797
806
|
#endif
|
798
807
|
if (len >= 2048)
|
799
|
-
rb_raise (rb_eRuntimeError, "too many arguments to popen");
|
808
|
+
rb_raise (rb_eRuntimeError, "%s", "too many arguments to popen");
|
800
809
|
char *strings [2048];
|
801
810
|
for (int i=0; i < len; i++) {
|
802
811
|
VALUE ix = INT2FIX (i);
|
@@ -825,7 +834,7 @@ static VALUE t_read_keyboard (VALUE self)
|
|
825
834
|
{
|
826
835
|
const unsigned long f = evma_open_keyboard();
|
827
836
|
if (!f)
|
828
|
-
rb_raise (rb_eRuntimeError, "no keyboard reader");
|
837
|
+
rb_raise (rb_eRuntimeError, "%s", "no keyboard reader");
|
829
838
|
return ULONG2NUM (f);
|
830
839
|
}
|
831
840
|
|
@@ -839,7 +848,7 @@ static VALUE t_watch_filename (VALUE self, VALUE fname)
|
|
839
848
|
try {
|
840
849
|
return ULONG2NUM(evma_watch_filename(StringValuePtr(fname)));
|
841
850
|
} catch (std::runtime_error e) {
|
842
|
-
rb_raise (EM_eUnsupported, e.what());
|
851
|
+
rb_raise (EM_eUnsupported, "%s", e.what());
|
843
852
|
}
|
844
853
|
return Qnil;
|
845
854
|
}
|
@@ -865,7 +874,7 @@ static VALUE t_watch_pid (VALUE self, VALUE pid)
|
|
865
874
|
try {
|
866
875
|
return ULONG2NUM(evma_watch_pid(NUM2INT(pid)));
|
867
876
|
} catch (std::runtime_error e) {
|
868
|
-
rb_raise (EM_eUnsupported, e.what());
|
877
|
+
rb_raise (EM_eUnsupported, "%s", e.what());
|
869
878
|
}
|
870
879
|
return Qnil;
|
871
880
|
}
|
@@ -912,7 +921,7 @@ t__epoll_set
|
|
912
921
|
static VALUE t__epoll_set (VALUE self, VALUE val)
|
913
922
|
{
|
914
923
|
if (t__epoll_p(self) == Qfalse)
|
915
|
-
rb_raise (EM_eUnsupported, "epoll is not supported on this platform");
|
924
|
+
rb_raise (EM_eUnsupported, "%s", "epoll is not supported on this platform");
|
916
925
|
|
917
926
|
evma_set_epoll (val == Qtrue ? 1 : 0);
|
918
927
|
return val;
|
@@ -949,7 +958,7 @@ t__kqueue_set
|
|
949
958
|
static VALUE t__kqueue_set (VALUE self, VALUE val)
|
950
959
|
{
|
951
960
|
if (t__kqueue_p(self) == Qfalse)
|
952
|
-
rb_raise (EM_eUnsupported, "kqueue is not supported on this platform");
|
961
|
+
rb_raise (EM_eUnsupported, "%s", "kqueue is not supported on this platform");
|
953
962
|
|
954
963
|
evma_set_kqueue (val == Qtrue ? 1 : 0);
|
955
964
|
return val;
|
@@ -987,7 +996,7 @@ static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename)
|
|
987
996
|
|
988
997
|
int b = evma_send_file_data_to_connection (NUM2ULONG (signature), StringValuePtr(filename));
|
989
998
|
if (b == -1)
|
990
|
-
rb_raise(rb_eRuntimeError, "File too large. send_file_data() supports files under 32k.");
|
999
|
+
rb_raise(rb_eRuntimeError, "%s", "File too large. send_file_data() supports files under 32k.");
|
991
1000
|
if (b > 0) {
|
992
1001
|
char *err = strerror (b);
|
993
1002
|
char buf[1024];
|
@@ -1065,7 +1074,7 @@ static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to, VALUE bufsize, VAL
|
|
1065
1074
|
try {
|
1066
1075
|
evma_start_proxy(NUM2ULONG (from), NUM2ULONG (to), NUM2ULONG(bufsize), NUM2ULONG(length));
|
1067
1076
|
} catch (std::runtime_error e) {
|
1068
|
-
rb_raise (EM_eConnectionError, e.what());
|
1077
|
+
rb_raise (EM_eConnectionError, "%s", e.what());
|
1069
1078
|
}
|
1070
1079
|
return Qnil;
|
1071
1080
|
}
|
@@ -1080,11 +1089,49 @@ static VALUE t_stop_proxy (VALUE self, VALUE from)
|
|
1080
1089
|
try{
|
1081
1090
|
evma_stop_proxy(NUM2ULONG (from));
|
1082
1091
|
} catch (std::runtime_error e) {
|
1083
|
-
rb_raise (EM_eConnectionError, e.what());
|
1092
|
+
rb_raise (EM_eConnectionError, "%s", e.what());
|
1084
1093
|
}
|
1085
1094
|
return Qnil;
|
1086
1095
|
}
|
1087
1096
|
|
1097
|
+
/***************
|
1098
|
+
t_proxied_bytes
|
1099
|
+
****************/
|
1100
|
+
|
1101
|
+
static VALUE t_proxied_bytes (VALUE self, VALUE from)
|
1102
|
+
{
|
1103
|
+
try{
|
1104
|
+
return ULONG2NUM(evma_proxied_bytes(NUM2ULONG (from)));
|
1105
|
+
} catch (std::runtime_error e) {
|
1106
|
+
rb_raise (EM_eConnectionError, "%s", e.what());
|
1107
|
+
}
|
1108
|
+
return Qnil;
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
/***************
|
1112
|
+
t_get_idle_time
|
1113
|
+
****************/
|
1114
|
+
|
1115
|
+
static VALUE t_get_idle_time (VALUE self, VALUE from)
|
1116
|
+
{
|
1117
|
+
try{
|
1118
|
+
uint64_t current_time = evma_get_current_loop_time();
|
1119
|
+
uint64_t time = evma_get_last_activity_time(NUM2ULONG (from));
|
1120
|
+
if (current_time != 0 && time != 0) {
|
1121
|
+
if (time >= current_time)
|
1122
|
+
return ULONG2NUM(0);
|
1123
|
+
else {
|
1124
|
+
uint64_t diff = current_time - time;
|
1125
|
+
float seconds = diff / (1000.0*1000.0);
|
1126
|
+
return rb_float_new(seconds);
|
1127
|
+
}
|
1128
|
+
return Qnil;
|
1129
|
+
}
|
1130
|
+
} catch (std::runtime_error e) {
|
1131
|
+
rb_raise (EM_eConnectionError, "%s", e.what());
|
1132
|
+
}
|
1133
|
+
return Qnil;
|
1134
|
+
}
|
1088
1135
|
|
1089
1136
|
/************************
|
1090
1137
|
t_get_heartbeat_interval
|
@@ -1180,9 +1227,11 @@ extern "C" void Init_rubyeventmachine()
|
|
1180
1227
|
rb_define_module_function (EmModule, "pause_connection", (VALUE (*)(...))t_pause, 1);
|
1181
1228
|
rb_define_module_function (EmModule, "resume_connection", (VALUE (*)(...))t_resume, 1);
|
1182
1229
|
rb_define_module_function (EmModule, "connection_paused?", (VALUE (*)(...))t_paused_p, 1);
|
1230
|
+
rb_define_module_function (EmModule, "num_close_scheduled", (VALUE (*)(...))t_num_close_scheduled, 0);
|
1183
1231
|
|
1184
1232
|
rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 4);
|
1185
1233
|
rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
|
1234
|
+
rb_define_module_function (EmModule, "get_proxied_bytes", (VALUE (*)(...))t_proxied_bytes, 1);
|
1186
1235
|
|
1187
1236
|
rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
|
1188
1237
|
rb_define_module_function (EmModule, "unwatch_filename", (VALUE (*)(...))t_unwatch_filename, 1);
|
@@ -1206,6 +1255,7 @@ extern "C" void Init_rubyeventmachine()
|
|
1206
1255
|
rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
|
1207
1256
|
rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
|
1208
1257
|
rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
|
1258
|
+
rb_define_module_function (EmModule, "get_idle_time", (VALUE(*)(...))t_get_idle_time, 1);
|
1209
1259
|
|
1210
1260
|
rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
|
1211
1261
|
rb_define_module_function (EmModule, "get_sockname", (VALUE(*)(...))t_get_sockname, 1);
|
data/ext/ssl.cpp
CHANGED
@@ -137,7 +137,7 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str
|
|
137
137
|
bLibraryInitialized = true;
|
138
138
|
SSL_library_init();
|
139
139
|
OpenSSL_add_ssl_algorithms();
|
140
|
-
|
140
|
+
OpenSSL_add_all_algorithms();
|
141
141
|
SSL_load_error_strings();
|
142
142
|
ERR_load_crypto_strings();
|
143
143
|
|
@@ -151,6 +151,9 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str
|
|
151
151
|
|
152
152
|
SSL_CTX_set_options (pCtx, SSL_OP_ALL);
|
153
153
|
//SSL_CTX_set_options (pCtx, (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3));
|
154
|
+
#ifdef SSL_MODE_RELEASE_BUFFERS
|
155
|
+
SSL_CTX_set_mode (pCtx, SSL_MODE_RELEASE_BUFFERS);
|
156
|
+
#endif
|
154
157
|
|
155
158
|
if (is_server) {
|
156
159
|
// The SSL_CTX calls here do NOT allocate memory.
|
@@ -524,6 +524,10 @@ public class EmReactor {
|
|
524
524
|
return Connections.get(sig).getPeerName();
|
525
525
|
}
|
526
526
|
|
527
|
+
public Object[] getSockName (long sig) {
|
528
|
+
return Connections.get(sig).getSockName();
|
529
|
+
}
|
530
|
+
|
527
531
|
public long attachChannel (SocketChannel sc, boolean watch_mode) {
|
528
532
|
long b = createBinding();
|
529
533
|
|
@@ -183,6 +183,12 @@ public class EventableDatagramChannel implements EventableChannel {
|
|
183
183
|
}
|
184
184
|
}
|
185
185
|
|
186
|
+
public Object[] getSockName () {
|
187
|
+
DatagramSocket socket = channel.socket();
|
188
|
+
return new Object[]{ socket.getLocalPort(),
|
189
|
+
socket.getLocalAddress().getHostAddress() };
|
190
|
+
}
|
191
|
+
|
186
192
|
public boolean isWatchOnly() { return false; }
|
187
193
|
public boolean isNotifyReadable() { return false; }
|
188
194
|
public boolean isNotifyWritable() { return false; }
|
@@ -302,6 +302,12 @@ public class EventableSocketChannel implements EventableChannel {
|
|
302
302
|
return new Object[]{ sock.getPort(), sock.getInetAddress().getHostAddress() };
|
303
303
|
}
|
304
304
|
|
305
|
+
public Object[] getSockName () {
|
306
|
+
Socket sock = channel.socket();
|
307
|
+
return new Object[]{ sock.getLocalPort(),
|
308
|
+
sock.getLocalAddress().getHostAddress() };
|
309
|
+
}
|
310
|
+
|
305
311
|
public void setWatchOnly() {
|
306
312
|
bWatchOnly = true;
|
307
313
|
updateEvents();
|
data/lib/em/connection.rb
CHANGED
@@ -238,6 +238,12 @@ module EventMachine
|
|
238
238
|
EventMachine::disable_proxy(self)
|
239
239
|
end
|
240
240
|
|
241
|
+
# The number of bytes proxied to another connection. Reset to zero when
|
242
|
+
# EventMachine::Connection#proxy_incoming_to is called, and incremented whenever data is proxied.
|
243
|
+
def get_proxied_bytes
|
244
|
+
EventMachine::get_proxied_bytes(@signature)
|
245
|
+
end
|
246
|
+
|
241
247
|
# EventMachine::Connection#close_connection is called only by user code, and never
|
242
248
|
# by the event loop. You may call this method against a connection object in any
|
243
249
|
# callback handler, whether or not the callback was made against the connection
|
@@ -570,6 +576,11 @@ module EventMachine
|
|
570
576
|
EventMachine::get_subprocess_status @signature
|
571
577
|
end
|
572
578
|
|
579
|
+
# The number of seconds since the last send/receive activity on this connection.
|
580
|
+
def get_idle_time
|
581
|
+
EventMachine::get_idle_time @signature
|
582
|
+
end
|
583
|
+
|
573
584
|
# comm_inactivity_timeout returns the current value (float in seconds) of the inactivity-timeout
|
574
585
|
# property of network-connection and datagram-socket objects. A nonzero value
|
575
586
|
# indicates that the connection or socket will automatically be closed if no read or write
|
data/lib/em/pool.rb
CHANGED
@@ -122,7 +122,10 @@ module EventMachine
|
|
122
122
|
|
123
123
|
def failure resource
|
124
124
|
if @on_error
|
125
|
+
@contents.delete resource
|
125
126
|
@on_error.call resource
|
127
|
+
# Prevent users from calling a leak.
|
128
|
+
@removed.delete resource
|
126
129
|
else
|
127
130
|
requeue resource
|
128
131
|
end
|
@@ -140,7 +143,9 @@ module EventMachine
|
|
140
143
|
else
|
141
144
|
raise ArgumentError, "deferrable expected from work"
|
142
145
|
end
|
146
|
+
rescue Exception
|
147
|
+
failure resource
|
148
|
+
raise
|
143
149
|
end
|
144
|
-
|
145
150
|
end
|
146
|
-
end
|
151
|
+
end
|
@@ -31,38 +31,38 @@ module EventMachine
|
|
31
31
|
# Simple SMTP client
|
32
32
|
#
|
33
33
|
# @example
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
34
|
+
# email = EM::Protocols::SmtpClient.send(
|
35
|
+
# :domain=>"example.com",
|
36
|
+
# :host=>'localhost',
|
37
|
+
# :port=>25, # optional, defaults 25
|
38
|
+
# :starttls=>true, # use ssl
|
39
|
+
# :from=>"sender@example.com",
|
40
|
+
# :to=> ["to_1@example.com", "to_2@example.com"],
|
41
|
+
# :header=> {"Subject" => "This is a subject line"},
|
42
|
+
# :body=> "This is the body of the email"
|
43
|
+
# )
|
44
|
+
# email.callback{
|
45
|
+
# puts 'Email sent!'
|
46
|
+
# }
|
47
|
+
# email.errback{ |e|
|
48
|
+
# puts 'Email failed!'
|
49
|
+
# }
|
50
50
|
#
|
51
51
|
# Sending generated emails (using mailfactory)
|
52
52
|
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
53
|
+
# mail = MailFactory.new
|
54
|
+
# mail.to = 'someone@site.co'
|
55
|
+
# mail.from = 'me@site.com'
|
56
|
+
# mail.subject = 'hi!'
|
57
|
+
# mail.text = 'hello world'
|
58
|
+
# mail.html = '<h1>hello world</h1>'
|
59
59
|
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
60
|
+
# email = EM::P::SmtpClient.send(
|
61
|
+
# :domain=>'site.com',
|
62
|
+
# :from=>mail.from,
|
63
|
+
# :to=>mail.to,
|
64
|
+
# :content=>"#{mail.to_s}\r\n.\r\n"
|
65
|
+
# )
|
66
66
|
#
|
67
67
|
class SmtpClient < Connection
|
68
68
|
include EventMachine::Deferrable
|