Mark Van De Vyver
2007-May-11 05:14 UTC
[Eventmachine-talk] Redefining receive_data using define_method
Hi, In a vanilla ruby class and module I can define and redefine an instance method using define_method. However in EventMachine the redefinition does not ''take'' _and_ no exception is thrown. I am ''run''ing EventMachine in a thread, and this might have side effects? Specifically: - I define receive_data at the end of post_init - I redefine receive_data at the end of connection_completed I only see the first definition ''at work'' Should this be possible with EventMachine? Can anyone hint at a work around? I include a working example below Regards Mark require ''thread'' require ''rubygems'' require ''eventmachine'' class EchoServer < EventMachine::Connection def post_init puts "Received a new connection" @data_received = "" @line_count = 0 self.class.send(:define_method, "receive_data" ){ |data| receive_handshake_data( data ) } end def connection_completed puts "connection completed... #{self.class.name}" # EchoServer.remove_method( :receive_data ) self.class.send(:define_method, "receive_data" ){ |data| receive_regular_data( data ) } end def receive_handshake_data( data ) puts ''receive_data for connection handshake data.'' send_data ">> #{data}" puts "The server received: #{data} \nThen the server sent: >> #{data}" close_connection if data =~ /quit/i end def receive_regular_data( data ) puts ''receive_data for regular data.'' send_data ">> #{data}" puts "The server received: #{data} \nThen the server sent: >> #{data}" close_connection if data =~ /quit/i end end class Echo < EventMachine::Connection @@conn_list = [] def self.print_connections @@conn_list.each {|conn| puts conn.inspect } end def initialize *args super @@conn_list << self end def post_init # your normal processing end def connection_completed puts "connection completed... #{self.class.name}" end def receive_data data # your normal processing puts "The client received: #{data}" # puts Echo.print_connections end def client_send_data data puts "The client is sending: #{data}" send_data data end def unbind @@conn_list.delete self end end host,port = "192.168.1.1", 8090 Thread.abort_on_exception = true begin @my_em_run_thread = Thread.new do EventMachine::run { Thread.current[:server] = EventMachine::start_server host, port, EchoServer puts "Now accepting connections on address #{host}, port #{port}..." Thread.current[:client_1] = EventMachine::connect host, port, Echo Thread.current[:client_2] = EventMachine::connect host, port, Echo Thread.current[:client_3] = EventMachine::connect host, port, Echo Thread.current[:client_4] = EventMachine::connect host, port, Echo # EventMachine::add_periodic_timer( 10 ) { # $stderr.write "*...\n" # Echo.print_connections # } } # EventMachine::run end # Thread.new rescue => err puts err end # begin # # Using one connection # puts @my_em_run_thread.status @my_em_run_thread[:client_1].client_send_data "On client_1 connection, we should see this text... first \n" @my_em_run_thread[:client_1].client_send_data "On client_1 connection, we should see this text... second \n" sleep(1) @my_em_run_thread[:client_1].client_send_data "On client_1 connection, we should see this text... third \n" sleep(1) @my_em_run_thread[:client_1].client_send_data "On client_1 connection, we should see this text... last! \n" # # Using all connections # @my_em_run_thread[:client_4].client_send_data "On client_4 connection, we _should_ see this text... out of order \n" @my_em_run_thread[:client_3].client_send_data "On client_3 connection, we _should_ see this text... out of order \n" sleep(1) @my_em_run_thread[:client_2].client_send_data "On client_2 connection, we should see this text... third \n" sleep(1) @my_em_run_thread[:client_1].client_send_data "On client_1 connection, we should see this text... last! \n" puts @my_em_run_thread.status
Francis Cianfrocca
2007-May-14 04:29 UTC
[Eventmachine-talk] Redefining receive_data using define_method
On 5/11/07, Mark Van De Vyver <mvyver at gmail.com> wrote:> > Hi, > In a vanilla ruby class and module I can define and redefine an > instance method using define_method. > > However in EventMachine the redefinition does not ''take'' _and_ no > exception is thrown. I am ''run''ing EventMachine in a thread, and this > might have side effects? > > Specifically: > - I define receive_data at the end of post_init > - I redefine receive_data at the end of connection_completed > > I only see the first definition ''at work'' > > Should this be possible with EventMachine? Can anyone hint at a work > around? > I include a working example below > > Regards > MarkI didn''t take the time to read your code in great detail but it appears that you''re trying to do the method redefinition in connection_completed. However, this event is NOT delivered to TCP servers, only to TCP clients. Does this shed any light on your problem? If so, then write back here and I''ll explain the semantics of connection_completed if they are not clear. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/eventmachine-talk/attachments/20070514/53bea875/attachment-0001.html