Skip to content

Commit

Permalink
EM::Connection#get_idle_time for number of seconds since LastActivity
Browse files Browse the repository at this point in the history
  • Loading branch information
tmm1 committed Mar 5, 2012
1 parent 1f7bde8 commit 0836b24
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 0 deletions.
15 changes: 15 additions & 0 deletions ext/cmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,21 @@ extern "C" unsigned long evma_proxied_bytes (const unsigned long from)
}


/***************************
evma_get_last_activity_time
****************************/

extern "C" uint64_t evma_get_last_activity_time(const unsigned long from)
{
ensure_eventmachine("evma_get_last_activity_time");
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
if (ed)
return ed->GetLastActivity();
else
return 0;
}


/***************************
evma_get_heartbeat_interval
****************************/
Expand Down
1 change: 1 addition & 0 deletions ext/ed.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class EventableDescriptor: public Bindable_t
virtual int SetCommInactivityTimeout (uint64_t value) {return 0;}
uint64_t GetPendingConnectTimeout();
int SetPendingConnectTimeout (uint64_t value);
uint64_t GetLastActivity() { return LastActivity; }

#ifdef HAVE_EPOLL
struct epoll_event *GetEpollEvent() { return &EpollEvent; }
Expand Down
1 change: 1 addition & 0 deletions ext/eventmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ extern "C" {
float evma_get_pending_connect_timeout (const unsigned long binding);
int evma_set_pending_connect_timeout (const unsigned long binding, float value);
int evma_get_outbound_data_size (const unsigned long binding);
uint64_t evma_get_last_activity_time (const unsigned long);
int evma_send_file_data_to_connection (const unsigned long binding, const char *filename);

void evma_close_connection (const unsigned long binding, int after_writing);
Expand Down
25 changes: 25 additions & 0 deletions ext/rubymain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,30 @@ static VALUE t_proxied_bytes (VALUE self, VALUE from)
return Qnil;
}

/***************
t_get_idle_time
****************/

static VALUE t_get_idle_time (VALUE self, VALUE from)
{
try{
uint64_t current_time = evma_get_current_loop_time();
uint64_t time = evma_get_last_activity_time(NUM2ULONG (from));
if (current_time != 0 && time != 0) {
if (time >= current_time)
return ULONG2NUM(0);
else {
uint64_t diff = current_time - time;
float seconds = diff / (1000.0*1000.0);
return rb_float_new(seconds);
}
return Qnil;
}
} catch (std::runtime_error e) {
rb_raise (EM_eConnectionError, e.what());
}
return Qnil;
}

/************************
t_get_heartbeat_interval
Expand Down Expand Up @@ -1231,6 +1255,7 @@ extern "C" void Init_rubyeventmachine()
rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
rb_define_module_function (EmModule, "get_idle_time", (VALUE(*)(...))t_get_idle_time, 1);

rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
rb_define_module_function (EmModule, "get_sockname", (VALUE(*)(...))t_get_sockname, 1);
Expand Down
5 changes: 5 additions & 0 deletions lib/em/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,11 @@ def get_status
EventMachine::get_subprocess_status @signature
end

# The number of seconds since the last send/receive activity on this connection.
def get_idle_time
EventMachine::get_idle_time @signature
end

# comm_inactivity_timeout returns the current value (float in seconds) of the inactivity-timeout
# property of network-connection and datagram-socket objects. A nonzero value
# indicates that the connection or socket will automatically be closed if no read or write
Expand Down
23 changes: 23 additions & 0 deletions tests/test_idle_connection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'em_test_helper'

class TestIdleConnection < Test::Unit::TestCase
if EM.respond_to?(:get_idle_time)
def test_idle_time
EM.run{
conn = EM.connect 'www.google.com', 80
EM.add_timer(3){
$idle_time = conn.get_idle_time
conn.send_data "GET / HTTP/1.0\r\n\r\n"
EM.next_tick{
$idle_time_after_send = conn.get_idle_time
conn.close_connection
EM.stop
}
}
}

assert_in_delta 3, $idle_time, 0.2
assert_equal 0, $idle_time_after_send
end
end
end

0 comments on commit 0836b24

Please sign in to comment.