Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added HTTP::Server.run method #3737

Closed
wants to merge 1 commit into from

Conversation

aurimasniekis
Copy link

@aurimasniekis aurimasniekis commented Dec 20, 2016

Hi, today I just discovered the Crystal language and was amazed with performance of HTTP server.

I was trying to implement the fork model based multi process HTTP server but I ran into the problem that once you start listen to the TCPServer I am unable to fork anymore so I add one more method to allow use HTTP::Server.bind & HTTP::Server.run to make possible fork the process and then start accepting connections.

Here is my small code example I was trying to test

require "http"

server = HTTP::Server.new(3000) do |context|
  context.response.content_type = "text/plain"
  context.response.print "Hello world, got #{Process.pid}!"
end

server.bind

puts "Listening on http://127.0.0.1:3000"

process = nil
4.times do |i|  
  process = Process.fork

  if (nil == process)
    server.run
    exit
  end
end
  
process.as(Process).wait()

Here is performance difference between single process and 4 process.

Running 20s test @ http://127.0.0.1:3000/
  2 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.35ms  425.43us  10.29ms   76.25%
    Req/Sec    37.04k     5.02k   51.45k    61.00%
  1474238 requests in 20.01s, 156.06MB read
Requests/sec:  73663.69
Transfer/sec:      7.80MB
Running 20s test @ http://127.0.0.1:3000/
  2 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.13ms  360.19us  15.57ms   85.06%
    Req/Sec    44.28k     5.57k   50.56k    70.75%
  1761893 requests in 20.01s, 186.51MB read
Requests/sec:  88032.69
Transfer/sec:      9.32MB

Difference is not so big as I was only running 2 threads but still really not bad improvement and ability to extend HTTP server to work bit differently then intended.

P.S. I am yet not much familiar with project so if I miss something please tell me I will try to help.
P.P.S I opened this pull request as open discussion on this topic.

@sdogruyol
Copy link
Member

Welcome to Crystal community @aurimasniekis, congrats on your first PR 🎉

@ysbaddaden
Copy link
Contributor

What about first bind, then fork and call listen in them. This will reuse the TCPServer internally.

server.bind

4.times do
  fork do
    server.listen
  end
end

sleep

@aurimasniekis
Copy link
Author

I think it's possible as far as I see as I am less than 24h with Crystal still reading docs... 👍

@asterite
Copy link
Member

I'm closing this because the solution given by @ysbaddaden accomplishes this

@asterite asterite closed this Dec 26, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants