# Ruby/Gnome app hangs when http'ing from inside a thread (linux only)

**URL:** <https://www.ruby-forum.com/t/ruby-gnome-app-hangs-when-httping-from-inside-a-thread-linux-only/122895>\
**Category:** Ruby\
**Created:** [December 12, 2007, 8:06pm UTC](https://www.ruby-forum.com/t/ruby-gnome-app-hangs-when-httping-from-inside-a-thread-linux-only/122895 "2007-12-12T20:06:13Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![AndrSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/e99b99/32.png) [@AndrSSSS](https://www.ruby-forum.com/u/AndrSSSS)\
**Post date:** [December 12, 2007, 8:06pm UTC](https://www.ruby-forum.com/t/ruby-gnome-app-hangs-when-httping-from-inside-a-thread-linux-only/122895/1 "2007-12-12T20:06:13Z")

</div>

Hello,

I’m writing a Ruby/Gnome application that auto-updates itself from the  
internet when a new version is available.

The auto-update function runs in a different thread, so the user won’t  
even notice that the application is checking for a new version.

It all works fine, EXCEPT when there’s no network connection. In this  
case, the WHOLE application simply hangs for one or two minutes, with  
no regard for the fact that this code is running in a thread, or that  
the timeout property is set.

And this error only happens on linux. Has anybody ever experienced  
anything like it?

A sample code follows:

Thread.new do  
http = Net::HTTP.new(‘[myhost.com](http://myhost.com)’)  
http.open\_timeout = 5  
http.read\_timeout = 5  
http.start  
resp = http.get(‘/somefile.html’)  
puts resp.body  
end

Andr

---

<div class="post-metadata">

**Author:** ![AndrSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/e99b99/32.png) [@AndrSSSS](https://www.ruby-forum.com/u/AndrSSSS)\
**Post date:** [December 13, 2007, 5:26pm UTC](https://www.ruby-forum.com/t/ruby-gnome-app-hangs-when-httping-from-inside-a-thread-linux-only/122895/2 "2007-12-13T17:26:14Z")

</div>

Anyone?

---

<div class="post-metadata">

**Author:** ![AndrSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/e99b99/32.png) [@AndrSSSS](https://www.ruby-forum.com/u/AndrSSSS)\
**Post date:** [December 13, 2007, 9:44pm UTC](https://www.ruby-forum.com/t/ruby-gnome-app-hangs-when-httping-from-inside-a-thread-linux-only/122895/3 "2007-12-13T21:44:58Z")

</div>

On Thu, Dec 13, 2007 at 04:05:19AM +0900, André wrote:

> The auto-update function runs in a different thread, so the user won’t  
> even notice that the application is checking for a new version.
> 
> It all works fine, EXCEPT when there’s no network connection. In this  
> case, the WHOLE application simply hangs for one or two minutes, with  
> no regard for the fact that this code is running in a thread, or that  
> the timeout property is set.

I think your problem may be caused by a blocking name lookup, and  
there seems to be a fix in the standard library (see below)

Explanation:

From what I understand, the builtin DNS resolver just hands off to a  
blocking system call – which given the Ruby thread model means that  
for the duration of that call no other threads will be scheduled (at  
least, in 1.8).

The timeouts you specify won’t apply to the system call, and I don’t  
think there’s any way to specify ones that will given the standard  
implementation, so it’ll wait for the system default timeout (that 2m  
delay sounds awfully familiar) before returning an error.

Possible solution:

I think the way to fix this is to replace the default resolver with an  
alternative version that plays nicely with ruby threads - i.e. by  
wrapping a native async DNS library, or a implementing one in pure  
ruby.

While I haven’t tried this, I think you might be able to magically  
solve this simply through the wonders of the standard library:

require ‘resolv-replace’

Which seems to provide a pure-ruby resolver which should play nice  
with threads. I’m not sure if there are any consequences of doing  
this though.

If that doesn’t work, there seem to be several DNS related gems, maybe  
someone else can provide more detail.

> And this error only happens on linux. Has anybody ever experienced  
> anything like it?

Why it happens only on linux, I’m not really sure - if this is  
something like ethernet with an unplugged network cable, I have this  
vague idea that most linuxes don’t actually take the interface down  
when its unplugged, whereas maybe windows does - so on linux it tries  
to send packets and wait for timeouts anyway, but maybe windows  
disables/takes down the interface so it returns an immediate error?  
Pure speculation on my part 🙂

Hope that helps (and please excuse the long-windedness :),  
Stephen L.

---

<div class="post-metadata">

**Author:** ![AndrSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/e99b99/32.png) [@AndrSSSS](https://www.ruby-forum.com/u/AndrSSSS)\
**Post date:** [December 14, 2007, 12:09pm UTC](https://www.ruby-forum.com/t/ruby-gnome-app-hangs-when-httping-from-inside-a-thread-linux-only/122895/4 "2007-12-14T12:09:16Z")

</div>

> I think your problem may be caused by a blocking name lookup, and  
> there seems to be a fix in the standard library (see below)
> 
> …

Thank you SO MUCH! That’s exactly what I needed to know. I’ll try to  
change something and check if it works.

Regards!

Andr

---

<div class="post-metadata">

**Author:** ![AndrSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/e99b99/32.png) [@AndrSSSS](https://www.ruby-forum.com/u/AndrSSSS)\
**Post date:** [December 14, 2007, 9:34pm UTC](https://www.ruby-forum.com/t/ruby-gnome-app-hangs-when-httping-from-inside-a-thread-linux-only/122895/5 "2007-12-14T21:34:52Z")

</div>

On Fri, Dec 14, 2007 at 09:00:01PM +0900, André wrote:

> > While I haven’t tried this, I think you might be able to magically  
> > solve this simply through the wonders of the standard library:
> > 
> > require ‘resolv-replace’
> 
> It worked great under Linux! Unfortunately, this seems not to work  
> under Windows… ☹ It simply doesn’t resolve.

I have no idea why it doesn’t work under Windows - looking at the  
source it seems to have explicitly support it ☹

It might be worth experimenting with Socket.gethostbyname and see if  
it is returning any sort of useful errors? But I don’t really know  
what you should be looking for, sorry 😕

> I think this might be the way to go under Windows. The problem is: the  
> page where I’m downloading from depends on virtual host. So I can’t  
> open with HTTP.new(‘10.20.30.40’) since it’ll return different results  
> that opening with HTTP.new(‘[virtual.host.com](http://virtual.host.com)’).
> 
> Is there any way that I can open a HTTP connection with a IP and then  
> send a virtual host on the HTTP request?

You’ll need to set the ‘Host’ header on the request. So using  
your example before, do something like:

http = Net::HTTP.new(‘127.0.0.1’)  
…  
http.start  
resp = http.get(‘/somefile.html’, {‘Host’=\>‘[myhost.com](http://myhost.com)’})  
…

But getting the resolver to work properly is probably a better long  
term solution 🙂

---

<div class="post-metadata">

**Author:** ![AndrSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/e99b99/32.png) [@AndrSSSS](https://www.ruby-forum.com/u/AndrSSSS)\
**Post date:** [December 14, 2007, 1:00pm UTC](https://www.ruby-forum.com/t/ruby-gnome-app-hangs-when-httping-from-inside-a-thread-linux-only/122895/6 "2007-12-14T13:00:58Z")

</div>

> > And this error only happens on linux. Has anybody ever experienced  
> > anything like it?
> 
> Why it happens only on linux, I’m not really sure

I made a mistake: the same problem happens both in Linux and Windows.

> While I haven’t tried this, I think you might be able to magically  
> solve this simply through the wonders of the standard library:
> 
> require ‘resolv-replace’

It worked great under Linux! Unfortunately, this seems not to work  
under Windows… ☹ It simply doesn’t resolve.

> I think the way to fix this is to replace the default resolver with an  
> alternative version that plays nicely with ruby threads - i.e. by  
> wrapping a native async DNS library, or a implementing one in pure  
> ruby.

I think this might be the way to go under Windows. The problem is: the  
page where I’m downloading from depends on virtual host. So I can’t  
open with HTTP.new(‘10.20.30.40’) since it’ll return different results  
that opening with HTTP.new(‘[virtual.host.com](http://virtual.host.com)’).

Is there any way that I can open a HTTP connection with a IP and then  
send a virtual host on the HTTP request?

Regards,

Andr
