From: Ivan Shevanski Date: 2009-09-11T08:01:04+09:00 Subject: Re: Asynchronous http POST? Ben Giddings wrote: > On Thursday 10 September 2009 15:48:56 Ivan Shevanski wrote: >> Apparently, since control is not returned to the interpreter, when one >> thread waits the other(s) will not continue. At least that's my >> understanding. > > A quick test seems to show that isn't the case. I wrote a simple > webrick > servlet that accepts a post request and delays for a specified amount of > time > (from the delay parameter to the post), and a client with 2 threads that > post > to those URLs and keep track of when things start and end: > > delay_servlet.rb: > require 'webrick' > require 'time' > > class DelayServlet < WEBrick::HTTPServlet::AbstractServlet > def do_POST(request, response) > start_time = Time.now > delay = 0 > if request.query["delay"] > delay = request.query["delay"].to_i > end > > sleep(delay) > > end_time = Time.now > response.body = "delayed for #{delay}s, started at " + > "#{start_time.iso8601}, ended at #{end_time.iso8601}\n" > end > end > > if __FILE__ == $0 > server = WEBrick::HTTPServer.new(:Port => 8000) > server.mount("/", DelayServlet) > > trap("INT") {server.shutdown} > server.start > end > > > delay_client.rb: > require 'net/http' > require 'time' > > if __FILE__ == $0 > puts "Main thread start at #{Time.now.iso8601}" > > t1 = Thread.new do > puts "Thread 1 start at #{Time.now.iso8601}" > res = Net::HTTP.post_form(URI.parse('http://localhost:8000/'), > {'delay'=>'5'}) > puts "Response: " + res.body > puts "Thread 1 end at #{Time.now.iso8601}" > end > > t2 = Thread.new do > puts "Thread 2 start at #{Time.now.iso8601}" > res = Net::HTTP.post_form(URI.parse('http://localhost:8000/'), > {'delay'=>'7'}) > puts "Response: " + res.body > puts "Thread 2 end at #{Time.now.iso8601}" > end > > t1.join > t2.join > puts "Main thread end at #{Time.now.iso8601}" > end > > Output: > Main thread start at 2009-09-10T16:46:17-04:00 > Thread 1 start at 2009-09-10T16:46:17-04:00 > Thread 2 start at 2009-09-10T16:46:17-04:00 > Response: delayed for 5s, started at 2009-09-10T16:46:17-04:00, ended at > 2009-09-10T16:46:22-04:00 > Thread 1 end at 2009-09-10T16:46:22-04:00 > Response: delayed for 7s, started at 2009-09-10T16:46:17-04:00, ended at > 2009-09-10T16:46:24-04:00 > Thread 2 end at 2009-09-10T16:46:24-04:00 > Main thread end at 2009-09-10T16:46:24-04:00 > > So it sure looks like it isn't blocking all threads when waiting for a > HTTP > response. > > Ben Sure looks like you're right. Here's where I got that idea in my head: http://www.rubycentral.com/pickaxe/tut_threads.html """ Multithreading Often the simplest way to do two things at once is by using Ruby threads. These are totally in-process, implemented within the Ruby interpreter. That makes the Ruby threads completely portable---there is no reliance on the operating system---but you don't get certain benefits from having native threads. You may experience thread starvation (that's where a low-priority thread doesn't get a chance to run). If you manage to get your threads deadlocked, the whole process may grind to a halt. (!!!) And if some thread happens to make a call to the operating system that takes a long time to complete, all threads will hang until the interpreter gets control back. (!!!) However, don't let these potential problems put you off---Ruby threads are a lightweight and efficient way to achieve parallelism in your code. """ (Sorry, I'm unsure if I'm allowed to use html tags or anything here, but I think this will do. Looks like the faq link is broken.) Is this a blatant lie? Maybe someone can explain to me what is actually being referred to? Thanks, Ivan -- Posted via http://www.ruby-forum.com/.