Nazar Hussain
Nazar Hussain

Reputation: 5162

Concurrency with EventMachine for a high performance need

I need a high performance network tcp server. I wrote this code in EventMachine.

class ReactingServer < EventMachine::Connection
  attr_accessor :packet, :packet_class
  @@packet_count = 0

  def initialize(packet_class)
    super
    @packet_class = eval(packet_class)
    @packet = @packet_class.new
    @@packet_count = 0
  end

  def receive_data(data)
    @packet.clear

    operation = proc do
      @packet.read(data)
      @@packet_count = @@packet_count +1
    end

    call_back = proc do
      puts @packet.inspect
      puts "-------------------#{@@packet_count}------------------------\n"
    end
    EventMachine.defer operation, call_back
  end
end

Then i wrote a ruby client.

require 'rubygems'
require 'socket'

sock = TCPSocket.new("192.168.15.5", 8181)

500.times do |n|
    packet = "\x00\x01\x1\x0\x1FNazar Hu\x00\x0F\xF\xF\xF\xF\xF\xF"
    sock.send packet, 0
  sleep 0.01
end

The first problem i am facing is that, if i remove sleep from client many of the packets can't be received on server end. If i send 5 packets, on average 3 packets are received. Why this is been happening.

Other question is that my server needed to server around 20K connection and on average 10 connections would be sending packets to server per second. Does EventMachine is capable of handling this kind of load?

Upvotes: 1

Views: 698

Answers (3)

kbrock
kbrock

Reputation: 1017

There is a neat article http://www.slideshare.net/igrigorik/ruby-c10k-high-performance-networking-rubykaigi-09

I don't know what your main block looks like, but have you tried adding epoll to the beginning of your event_machine::server ?

EM.epoll
trap("TERM") { EM.stop }
trap("INT")  { EM.stop }
EM.run do
  EM.start_server("0.0.0.0", 8181, ReactingServer, "PacketClass") do
    # ...
  end
end

Also, that eval looks a little funny. Can you change "PacketClass" to :class => PacketClass instead?

I'm guessing here at what your code looks like.

Upvotes: 0

phil pirozhkov
phil pirozhkov

Reputation: 4919

receive_data is not called each time someone is sending something to the socket, it's buffered. And data size may differ from your several bytes to several KB. It's your responsibility to properly parse data. Two things you can be sure of is that all data which is sent will be received and the order will be correct.

Upvotes: 2

Aleksander Pohl
Aleksander Pohl

Reputation: 1705

Have you checked goliath? It is based on EventMachine and fibers. It is reported that it can serve up to 3000 req/s.

Upvotes: 0

Related Questions