# Threading and it is more of a ruby question, than a rails question

**URL:** <https://www.ruby-forum.com/t/threading-and-it-is-more-of-a-ruby-question-than-a-rails-question/185762>\
**Category:** Rails\
**Created:** [March 25, 2010, 6:45pm UTC](https://www.ruby-forum.com/t/threading-and-it-is-more-of-a-ruby-question-than-a-rails-question/185762 "2010-03-25T18:45:06Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![n4d4](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/7c8e57/32.png) [@n4d4](https://www.ruby-forum.com/u/n4d4)\
**Post date:** [March 25, 2010, 6:45pm UTC](https://www.ruby-forum.com/t/threading-and-it-is-more-of-a-ruby-question-than-a-rails-question/185762/1 "2010-03-25T18:45:06Z")

</div>

I needed an email queueing system for a project I am writing. The  
script  
below runs every minute via a cronjob on one of my servers. I am using  
a  
table in mysql to keep track of the number of email bot threads to spawn  
and  
their current state. They need to be threaded(or at least run  
concurrently)  
since some email lists will be longer than others, and some emails have  
a  
higher priority. The thought is that this way I can quickly add more  
email  
threads as is needed, as well as have a simple web ui to check their  
state  
and turn them on or off as is necessary.

It works perfectly, most of the time. But sometime, arbitrarily, one of  
the  
threads does not finish and an email bot state is left as processing.  
In  
the log file, it actually says that it completes, but the entry in the  
database still says processing. Any ideas?

======== Email Bots Table ===========  
±—±-------±---------------------------------------------±---------------±--------------------+  
| id | status | query\_constraints | state  
| updated\_at |  
±—±-------±---------------------------------------------±---------------±--------------------+  
| 1 | on | select \* from email\_queue where priority = 0 |  
idle | 2010-03-25 17:33:14 |  
| 2 | on | select \* from email\_queue WHERE priority \> 0 |  
idle | 2010-03-25 17:33:14 |  
±—±-------±---------------------------------------------±---------------±--------------------+

======== Email bot Script that runs via cronjob ===========

require ‘rubygems’  
require ‘net/smtp’  
require ‘timeout’  
require ‘mysql’  
require ‘activesupport’  
require ‘activerecord’

begin  
require ‘openssl’  
rescue LoadError  
end

ActiveRecord::Base.establish\_connection(  
:adapter =\> ‘mysql’,  
:host =\> ‘localhost’,  
:database =\> ‘adevelopment’,  
:username =\> ‘username’,  
:password =\> ‘password’  
)

def send\_email(from, to, subject, message)  
msg = \<\<END\_OF\_MESSAGE  
From: #{from}  
To: #{to}  
MIME-Version: 1.0  
Content-type: text/html  
Subject: #{subject}

#{message}  
END\_OF\_MESSAGE

```
Net::SMTP.start('server', 25, '<sending domain>','username', 

```

‘password’,  
:login) do |smtp|  
smtp.send\_message msg, from.gsub(/[^\<]+\</,’’).gsub(/\>/,’’),  
to.gsub(/[^\<]+\</,’’).gsub(/\>/,’’)  
end  
end

# gather email bots

mysql = ActiveRecord::Base.connection.execute(“SELECT \* FROM  
email\_bots”)  
emailbots = {}  
mysql.each\_hash do |p|  
emailbots[p[‘id’]] = p  
end  
mysql.free

threads = []  
emailbots.each do |emailbot|  
if emailbot[1][‘status’] == ‘on’ && emailbot[1][‘state’] == ‘idle’  
threads \<\< Thread.new{  
ebot = emailbot[1]  
ActiveRecord::Base.connection.execute(“UPDATE email\_bots SET  
state=‘processing’, updated\_at=UTC\_TIMESTAMP() WHERE id=#{ebot[‘id’]}”)  
sent = “”  
mysql =  
ActiveRecord::Base.connection.execute(ebot[‘query\_constraints’])  
i = 1  
mysql.each\_hash do |email|  
puts email[‘id’]  
begin  
send\_email(email[‘sender’], email[‘recipient’],  
email[‘subject’], email[‘message’])  
sent += email[‘id’] + “,”  
rescue Exception =\> e

ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(“sanitize\_sql\_array”,[“UPDATE  
email\_queue SET error=’%s’ WHERE id=#{email[‘id’]}”, “#{e.message}  
#{e.backtrace.inspect}”]))  
end  
i = i + 1  
if i % 100 == 0  
if sent != “”  
ActiveRecord::Base.connection.execute(“INSERT INTO  
email\_sent  
(SELECT priority, user\_id, #{ebot[‘id’]}, sender, recipient, subject,  
message, error, UTC\_TIMESTAMP FROM email\_queue WHERE id in  
(#{sent.chop!}))”)  
ActiveRecord::Base.connection.execute(“DELETE FROM  
email\_queue  
WHERE id in (#{sent})”)  
sent = “”  
end  
end  
end  
mysql.free  
if sent != “”  
ActiveRecord::Base.connection.execute(“INSERT INTO email\_sent  
(SELECT priority, user\_id, #{ebot[‘id’]}, sender, recipient, subject,  
message, error, UTC\_TIMESTAMP FROM email\_queue WHERE id in  
(#{sent.chop!}))”)  
ActiveRecord::Base.connection.execute(“DELETE FROM email\_queue  
WHERE id in (#{sent})”)  
end  
ActiveRecord::Base.connection.execute(“UPDATE email\_bots SET  
state=‘idle’ WHERE id=#{ebot[‘id’]}”)  
}  
else

# This is a potential work around which i am not too excited about.

# mysql =

ActiveRecord::Base.connection.execute(ebot[‘query\_constraints’])

# if mysql.num\_rows == 0

# ActiveRecord::Base.connection.execute("UPDATE email\_bots SET

current\_action=‘idle’ WHERE id=#{ebot[‘id’]}")  
end  
end  
end  
threads.each { |t|  
t.join  
}

---

<div class="post-metadata">

**Author:** ![n4d4](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/7c8e57/32.png) [@n4d4](https://www.ruby-forum.com/u/n4d4)\
**Post date:** [March 25, 2010, 7:09pm UTC](https://www.ruby-forum.com/t/threading-and-it-is-more-of-a-ruby-question-than-a-rails-question/185762/2 "2010-03-25T19:09:43Z")

</div>

Actually looking it is terminating when i call mysql.free after  
finishing walking through all of the sends
