# Asynchronous network access with Rack?

**URL:** <https://www.ruby-forum.com/t/asynchronous-network-access-with-rack/184809>\
**Category:** Ruby\
**Created:** [March 8, 2010, 11:50pm UTC](https://www.ruby-forum.com/t/asynchronous-network-access-with-rack/184809 "2010-03-08T23:50:38Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nicken](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/d07c76/32.png) [@nicken](https://www.ruby-forum.com/u/nicken)\
**Post date:** [March 8, 2010, 11:50pm UTC](https://www.ruby-forum.com/t/asynchronous-network-access-with-rack/184809/1 "2010-03-08T23:50:38Z")

</div>

I’ve read that “threading is considered harmful” for Ruby web apps.  
Well, I’m writing a Sinatra app which will build a page based on the  
responses of several servers (Net::HTTP.get). I want to do these .gets  
in parallel, as doing them synchronously would obviously mean the users  
would wait for a long time.

Would it be “considered harmful” to do:

resp\_a, resp\_b, resp\_c = nil  
thread\_a = Thread.new { resp\_a = Net::HTTP.get site\_a }  
thread\_b = Thread.new { resp\_b = Net::HTTP.get site\_b }  
thread\_c = Thread.new { resp\_c = Net::HTTP.get site\_c }  
thread\_a.join  
thread\_b.join  
thread\_c.join

Is there any possible harm that could come from this? Can threading  
interfere with Rack in some way? I haven’t done much previous  
development of threaded apps, so I would appreciate any tips.

---

<div class="post-metadata">

**Author:** ![nicken](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/d07c76/32.png) [@nicken](https://www.ruby-forum.com/u/nicken)\
**Post date:** [March 9, 2010, 12:14am UTC](https://www.ruby-forum.com/t/asynchronous-network-access-with-rack/184809/2 "2010-03-09T00:14:05Z")

</div>

I’ve used threading with getting several web pages for a long time and  
I’ve never had any problem so long as you catch errors if a specifc web  
page can’t be obtained.  
Tom R.

---

<div class="post-metadata">

**Author:** ![nicken](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/d07c76/32.png) [@nicken](https://www.ruby-forum.com/u/nicken)\
**Post date:** [March 9, 2010, 12:53am UTC](https://www.ruby-forum.com/t/asynchronous-network-access-with-rack/184809/3 "2010-03-09T00:53:18Z")

</div>

On Mar 8, 2010, at 3:13 PM, Tom R. wrote:

> > Would it be “considered harmful” to do:  
> > interfere with Rack in some way? I haven’t done much previous  
> > development of threaded apps, so I would appreciate any tips.

IMHO you would be better served using the ‘thin’ rack comat web server  
and using its async mode along with EM::HTTP::Request. This way you  
could use event driven style to hve zero threads and basically pause the  
clients request connection while you make async calls to all the other  
web services, once they all return then you fire the async callback for  
thin to resume the clients connection and return the results.

Doing it this way will require a bit more mental twisting to get all  
the async stuff correct but it will be far more scalable and will serve  
you much better in the end.

Cheers-

Ezra Z.  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![nicken](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/d07c76/32.png) [@nicken](https://www.ruby-forum.com/u/nicken)\
**Post date:** [March 9, 2010, 1:03am UTC](https://www.ruby-forum.com/t/asynchronous-network-access-with-rack/184809/4 "2010-03-09T01:03:15Z")

</div>

On Mon, Mar 8, 2010 at 10:50 PM, Nick B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’ve read that “threading is considered harmful” for Ruby web apps.  
> Well, I’m writing a Sinatra app which will build a page based on the  
> responses of several servers (Net::HTTP.get). I want to do these .gets  
> in parallel, as doing them synchronously would obviously mean the users  
> would wait for a long time.

There are some historical reasons behind threading == harmful (defaults  
for  
Rails,  
GIL & native gems, and a general lack of robustness in older Ruby thread  
implementations).

> Is there any possible harm that could come from this? Can threading  
> interfere with Rack in some way? I haven’t done much previous  
> development of threaded apps, so I would appreciate any tips.

I believe Sinatra/Rack is thread safe, so you should be fine on that  
count.

Whats more important is that this model isn’t exactly a good  
architecture.  
You are spawning a lot of threads per request and you have no real  
external  
oversight into how they are working. You can’t send back your response  
until you have received all your outbound responses and you are  
particularly  
vulnerable to timeouts - in particular the client browser can timeout  
your request, while you are still waiting on responses to outbound  
connections.

You see a lot of solutions that use process level concurrency  
(BackgroundRb,  
DelayedJob etc) but most web solutions that aggregate content from  
multiple  
sites (i.e. mashups) do it all in the browser, with some cross site  
scripting  
& javascript.

Technically I dont see too many issues with the multi-threaded approach  
you  
propose for smaller requests, but you will want to set an aggressive  
timeout  
on the outbound requests.

---

<div class="post-metadata">

**Author:** ![nicken](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/d07c76/32.png) [@nicken](https://www.ruby-forum.com/u/nicken)\
**Post date:** [March 9, 2010, 5:34am UTC](https://www.ruby-forum.com/t/asynchronous-network-access-with-rack/184809/5 "2010-03-09T05:34:36Z")

</div>

Tom R.:

> I’ve never had any problem…

Awesome! Good to hear 🙂

Ezra Z.:

> you would be better served using the ‘thin’ rack comat web  
> server and using its async mode along with EM::HTTP::Request.

Thanks. I’ve been using Apache+Passenger because that’s what I know, but  
I will investigate Thin if it is indeed more scalable. Are you referring  
to RAM usage when you say it’s more scalable?

Richard C.:

> javascript … you will want to set an aggressive timeout

This must happen server-side. But you’re right about the timeouts. And  
some searching has revealed Timeout::timeout() to me! It would appear  
that:

resp\_a = nil  
thread\_a = Thread.new{ Timeout::timeout(4){ resp\_a = Net::HTTP.get  
site\_a }}  
…  
thread\_a.join

will do what I need, so long as I catch exceptions, too. And again, I’m  
still open to other suggestions if anyone else has any!

---

<div class="post-metadata">

**Author:** ![nicken](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/d07c76/32.png) [@nicken](https://www.ruby-forum.com/u/nicken)\
**Post date:** [March 9, 2010, 10:46am UTC](https://www.ruby-forum.com/t/asynchronous-network-access-with-rack/184809/6 "2010-03-09T10:46:24Z")

</div>

Or this slightly shorter version:

thread\_a = Thread.new { Net::HTTP.get site\_a }  
thread\_b = Thread.new { Net::HTTP.get site\_b }  
thread\_c = Thread.new { Net::HTTP.get site\_c }  
val1 = thread\_a.value  
val2 = thread\_b.value  
val3 = thread\_c.value
