benoitc / couchbeam

Apache CouchDB client in Erlang
Other
242 stars 114 forks source link

Same TCP connection for multiple requests #3

Closed karalabe closed 15 years ago

karalabe commented 15 years ago

The component has a serious issue... it opens a new TCP connection for every single request... In a heavy usage scenario the computer simply runs out of TCP ports (TCP ports are kept in a zombie state for 2 minutes after closing them). In my application I have about 100 database requests per second... so even with all the system limits set to maximum, the 65K ports are finished within half an hour. Please take a look into this as the component otherwise is very good, but this issue kills it.

karalabe commented 15 years ago

I played around with it a bit and managed to solve the TCP issue. Here's what I did:

  1. I added a sock field to the couchdb_node
  2. In the couchbeam_client init method I opened the TCP conenction to the database and saved the socket in the "state".
  3. I removed the outermost nesting from the do_req (socket opening) and all the socket closing calls.
  4. I moved the recv_body call in the do_req up to be executed always, even if an error status was sent back by the database (as we're not closing the TCP connection, we need it to be empty for the next request... so always read the body)
  5. Added a keepalive = true option for the socket when connecting so that the TCP won't timeout on some NAT router on the way.

This was just my quick-fix. But I thought I'd post it anyway so that if you'd like to solve teh issue you would have a starting point. I'm not saying that this will 100% always work, as I'm not so familiar with the internals of couchbeam... but it seems to work.

karalabe commented 15 years ago

PS: A little error handling should be inserted in case the TCP connection does somehow get closed, to reopen it.

karalabe commented 15 years ago

Corrected a few minor things, one single test fails (6.2, but only the returned result is something else than expected, otherwise that also works ok... I'll sort it out). Anyway if you're interested in the changes then signal it and I'll send them over.

karalabe commented 15 years ago

All test run fine. :)... Hmm... maybe some reaction... it;s getting boring writing to myself :))

benoitc commented 15 years ago

sorry was awfully busy these days :/ I will release a new version of couchbeam fixing this error tomorrow. this version will manage a pool of connection and will keep them alive. Maybe this released will be based on ibrowse but it's not decided for now.

Anyway don't be shy post your patch :)

karalabe commented 15 years ago

Well... my patch was rather a quick fix. I'm not particularly happy with it. The ugly part is catching closed sockets and reopening them (only in active mode does the process receive a message with the closing event). Another thing... raise the gen_server timeout to infinity or allow manual setting, because the default 5 sec to much too short for a big database request. (Anyway, here's my patched version... not very nice, but works: http://193.16.218.158/~karalabe/patches/couchbeam/couchbeam_0.1.2.patch )

If you're thinking about rewriting the client part, consider using the lhttpc client. It's been designed to be very fast and lightweight. The other benefit is that it's written and maintained by Erlang Training and Consulting. http://bitbucket.org/etc/lhttpc/wiki/Home

benoitc commented 15 years ago

i've rewritten some bits from actual client. also api have somehow change to allow you to maintain a pool of connections. basically it now works like it :

Connection = couchbeam:create_connection(Host, Password)

then you can reuse your connectiion everywhere. It will be out tonight or tomorrow.