# Threaded Socket call blocks main thread

**URL:** <https://www.ruby-forum.com/t/threaded-socket-call-blocks-main-thread/73085>\
**Category:** Ruby\
**Created:** [October 21, 2006, 2:24am UTC](https://www.ruby-forum.com/t/threaded-socket-call-blocks-main-thread/73085 "2006-10-21T02:24:01Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![joost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/6de8d8/32.png) [@joost](https://www.ruby-forum.com/u/joost)\
**Post date:** [October 21, 2006, 2:24am UTC](https://www.ruby-forum.com/t/threaded-socket-call-blocks-main-thread/73085/1 "2006-10-21T02:24:01Z")

</div>

Hi all. A blocking IO issue is puzzling me, maybe someone can offer  
any insights.

I have written a plugin for Rails that does dns requests (to real-  
time blackhole lists). It works quite well. I am doing the dns  
requests (using Socket.gethostbyname) in separate threads.  
Unfortunately, when the call to Socket blocks, the main thread is  
blocking as well. And even though I have specified a parameter to  
thread.join, the script won’t kill the blocked thread.

This is only a problem when no dns servers can be found or when  
they’re terribly slow, but I must harden the plugin for these cases.

I have read posts on this list and it seems that any blocked IO such  
as what I am doing will block the main thread in Ruby. Is there a  
different way for me to kill the blocked thread and just move on? As  
this plugin is meant for web applications, a timely response is quite  
important. One or two seconds delay is fine, but no more.

Any help greatly appreciated.

require ‘socket’

module DNSBL\_Check  
$dnsbl\_passed ||= []  
DNSBLS = %w{[list.dsbl.org](http://list.dsbl.org) [bl.spamcop.net](http://bl.spamcop.net) [sbl-xbl.spamhaus.org](http://sbl-xbl.spamhaus.org)}

private

# Filter to check if the client is listed. This will be run before

all requests.  
def dnsbl\_check  
return true if $dnsbl\_passed.include? request.remote\_addr

```
 passed = true
 threads = []
 request.remote_addr =~ /(\d+).(\d+).(\d+).(\d+)/

 # Check the remote address against each dnsbl in a separate thread
 DNSBLS.each do |dnsbl|
   threads << Thread.new("#$4.#$3.#$2.#$1.#{dnsbl}") do |host|
     logger.warn("Checking DNSBL #{host}")
     if Socket.gethostbyname("#{host}")[3][0,2]=="\177\000"
       logger.info("#{request.remote_addr} found using DNSBL #

```

{host}")  
passed = false  
end  
end  
end  
threads.each {|thread| thread.join(2)} # join threads, but  
use timeout to kill blocked ones

```
 # Add client ip to global passed cache if no dnsbls objected.

```

else deny service.  
if passed  
$dnsbl\_passed = $dnsbl\_passed[0,49].unshift request.remote\_addr  
logger.warn(“#{request.remote\_addr} added to DNSBL passed cache”)  
else  
render :text =\> ‘Access denied’, :status =\> 403  
return false  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![joost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/6de8d8/32.png) [@joost](https://www.ruby-forum.com/u/joost)\
**Post date:** [October 21, 2006, 8:12am UTC](https://www.ruby-forum.com/t/threaded-socket-call-blocks-main-thread/73085/2 "2006-10-21T08:12:12Z")

</div>

joost baaij wrote:

> Hi all. A blocking IO issue is puzzling me, maybe someone can offer  
> any insights.
> 
> I have written a plugin for Rails that does dns requests (to real-  
> time blackhole lists). It works quite well. I am doing the dns  
> requests (using Socket.gethostbyname) in separate threads.  
> Unfortunately, when the call to Socket blocks, the main thread is  
> blocking as well. And even though I have specified a parameter to  
> thread.join, the script won’t kill the blocked thread.

Obviously when you join the thread, it can block the main thread. But in  
my  
experience with Ruby threads, if you don’t join the thread, it dies.  
Which  
leads a reasonable person to ask “what’s the point of the threads?”

---

<div class="post-metadata">

**Author:** ![joost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/6de8d8/32.png) [@joost](https://www.ruby-forum.com/u/joost)\
**Post date:** [October 21, 2006, 9:14am UTC](https://www.ruby-forum.com/t/threaded-socket-call-blocks-main-thread/73085/3 "2006-10-21T09:14:20Z")

</div>

Op 21-okt-2006, om 8:10 heeft Paul L. het volgende geschreven:

> Obviously when you join the thread, it can block the main thread.  
> But in my  
> experience with Ruby threads, if you don’t join the thread, it  
> dies. Which  
> leads a reasonable person to ask “what’s the point of the threads?”

It seems very limited then. Just an easy way to parallelize (sp?)  
_some_ tasks.

Foregoing threads, is there a way to continue a script that’s waiting  
for a blocked Socket.gethostbyname call? Afaik only actual files can  
be opened non-blocking, right?

Thanks.

---

<div class="post-metadata">

**Author:** ![joost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/6de8d8/32.png) [@joost](https://www.ruby-forum.com/u/joost)\
**Post date:** [October 21, 2006, 9:32am UTC](https://www.ruby-forum.com/t/threaded-socket-call-blocks-main-thread/73085/4 "2006-10-21T09:32:22Z")

</div>

[http://shnoo.gr/articles/2005/12/13/resolv-replace](http://shnoo.gr/articles/2005/12/13/resolv-replace)

---

<div class="post-metadata">

**Author:** ![joost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/6de8d8/32.png) [@joost](https://www.ruby-forum.com/u/joost)\
**Post date:** [October 21, 2006, 10:00am UTC](https://www.ruby-forum.com/t/threaded-socket-call-blocks-main-thread/73085/5 "2006-10-21T10:00:22Z")

</div>

Truly a hidden ruby gem. I would have never found it on my own. Many  
thanks!!

Op 21-okt-2006, om 9:30 heeft snacktime het volgende geschreven:
