Multiple Threads?

I need to create a little client for a third party web service. The
client should poll the service constantly. I need to monitor for new
events (they don’t have callbacks apparently…) so they keep the
connection open for 15 seconds and returns nothing if nothing has
happened. If an event happens then it returns when it actually happens.
After returning I should immediately request again.

This is fine as long as I only need to poll for one customer (since one
request only can check for one customer). The problem is that we need to
poll this service for multiple customers at the same time and then I of
course need threads.

I was thinking along the following lines (something is wrong with the
threading parts, when I run it without threads it works so it is not the
soap stuff that is wrong)

require ‘soap/rpc/driver’

CreateSessionResponse = Struct.new(:response_code, :session_id, :host)

proxy = SOAP::RPC::Driver.new('url_to_service, ‘urn:webservice’)
[
%w(createSession password name type tenant domain application),
%w(getEvents sessionId)
].each do |signature|
proxy.add_method(*signature)
end

class Client

def initialize(name = “”, password = “”, type = “”, tenant = “”,
domain = “”, application = “”)
@name, @password, @type, @tenant, @domain, @application = name,
password, type, tenant, domain, application
end

def run(proxy)
thread = Thread.new {
while true
# log in to server and get a session id
session =
CreateSessionResponse.new(*proxy.createSession(@password, @name, @type,
@tenant, @domain, @application))
# fetch events. returns after 15 seconds if no new events
events = proxy.getEvents(session.session_id)
if events
notify_stb(events)
else
puts “no new events” # never see’s this
end
end
}
thread.join # without joining the program exits immediately
end

def notify_stb(events)
puts “Notifying client with data #{events}” # never see’s this
end

end

puts “Starting…”

when testing I only have data for one client, will be more later

clients = [[“name”, “pwd”,"","",“domain”,“application”]].inject([]) {
|result, client_data| result << Client.new(*client_data)}
clients.each { |client| client.run(proxy) }

It might be that I actually do requests. The service is remote and I
don’t have a chance to check if the requests are actually getting there
(and there is also this 4:th of July in the States apparently…).

Can anyone see anything obviously wrong? I haven’t really done anything
with threads in Ruby before so…

Regards,

Marcus

Francis C. skrev:

Look at EventMachine in Rubyforge.

On Windows XP:

C:\Downloads>gem install eventmachine-0.5.3-mswin32.gem
Attempting local installation of ‘eventmachine-0.5.3-mswin32.gem’
ERROR: Error installing gem eventmachine-0.5.3-mswin32.gem[.gem]:
buffer error

I looked in the readme. There is an example there on how to create a
server. How would I use EventMachine to work as a client app?

Regards,

/Marcus

Look at EventMachine in Rubyforge.

Marcus A. skrev:

Francis C. skrev:

Look at EventMachine in Rubyforge.

On Windows XP:

C:\Downloads>gem install eventmachine-0.5.3-mswin32.gem
Attempting local installation of ‘eventmachine-0.5.3-mswin32.gem’
ERROR: Error installing gem eventmachine-0.5.3-mswin32.gem[.gem]:
buffer error

Also tried to do

gem install eventmachine

But then it tried to build native extensions and I don’t have a build
environment for C on my WinXP setup.

/Marcus

On Jul 4, 2006, at 1:27 PM, Francis C. wrote:

EventMachine). I can also write you a sample app based on my
understanding
of what you’re trying to do. If it works and you like it, we can
post it
back to this list for the benefit of others.

Francis-

I am interested in EventMachine as well so I would love to follow

your process of building something simple like this with
EventMachine. So I vote to keep it on the list or please cc me in the
process.

Thanks
-Ezra

Ezra: I sent Marcus the following description of an approach to his
application, and will post more to this list if the approach turns out
to be
worth something.

(snipped from a private email:)
Ok, here’s what I would do:
I assume you have a global hash that maps the description of each
“customer”
with a status indicating whether or not it currently has an active
client.
(You can use the same data structure to store and report status results
received from the connections.)
Have the EventMachine fire a timer every five seconds that examines each
of
the customers and starts up a new client connection for every one that
is
inactive. Once a connection is open for each customer, your
connection-handling code can start up a new connection whenever they
close
(which is an event passed by EM to your code). The five-second timer is
only
there for a heartbeat, to bootstrap the system, and in case an
unexpected
exception occurs. Because there are no threads, there are no race
conditions. Very simple.

Your application sounds in many ways like a “server” in the sense that
it
needs to maintain a lot of open connections (the fact that a threaded
implementation seems natural to you is a strong clue). The only real
difference here is that you originate the connections instead of
accepting
them. Feel free to write me a private email and I can support you
through
the Windows install problem you’re having (you need a compiler to
install
EventMachine). I can also write you a sample app based on my
understanding
of what you’re trying to do. If it works and you like it, we can post it
back to this list for the benefit of others.

Quoting Ezra Z. [email protected]:

of what you’re trying to do. If it works and you like it, we can post it
back to this list for the benefit of others.

Francis-

I am interested in EventMachine as well so I would love to follow your
process of building something simple like this with EventMachine. So I
vote to keep it on the list or please cc me in the process.

Thanks
-Ezra

Me too, please.