Ask a Question related to Ruby, Design and Development.
-
Ara.T.Howard #1
webrick, threads, and i/o
if i want to write a webrick application that mounts many servlets do i need
to be concerned that, if one of the servlets blocks on i/o, the entire
(threaded) webserver will also be blocked?
-a
====================================
| Ara Howard
| NOAA Forecast Systems Laboratory
| Information and Technology Services
| Data Systems Group
| R/FST 325 Broadway
| Boulder, CO 80305-3328
| Email: [email]ara.t.howard@noaa.gov[/email]
| Phone: 303-497-7238
| Fax: 303-497-7259
| The difference between art and science is that science is what we understand
| well enough to explain to a computer. Art is everything else.
| -- Donald Knuth, "Discover"
| ~ > /bin/sh -c 'for lang in ruby perl; do $lang -e "print \"\x3a\x2d\x29\x0a\""; done'
====================================
Ara.T.Howard Guest
-
Webrick doc
I am dumb. Can anyone point to documentation of Webrick? Yes, it is built-in in 1.8, but how do I read/study about it? Tips pls. Thanks in... -
CGI and Webrick
Hey all, I've just started poking at three Ruby tools I haven't yet used: DBI, Webrick, and CGI, and have a few questions: * Is there good... -
webrick and ruby
does anyone know of a development effort being made to support fastcgi in webrick? any interest in the idea out there? i'm thinking that a... -
webrick
I'm looking for a way to implement a standard webrick HTTP server but with a special feature : before serve a HTML page it replace all %foo%... -
Webrick and CGI question
How do I tell Webrick to use ruby to execute a cgi program? The following code example just shows me the script and not the result of executing the... -
NAKAMURA, Hiroshi #2
Re: webrick, threads, and i/o
Hi,
> From: "Ara.T.Howard" <ahoward@fsl.noaa.gov>
> Sent: Saturday, October 04, 2003 11:12 AMNo. WEBrick creates worker thread for each request.> if i want to write a webrick application that mounts many servlets do i need
> to be concerned that, if one of the servlets blocks on i/o, the entire
> (threaded) webserver will also be blocked?
So, take care if you mount a servlet factory which returns
singleton servlet instance. It runs under MT condition.
Regards,
// NaHi
NAKAMURA, Hiroshi Guest
-
Ara.T.Howard #3
Re: webrick, threads, and i/o
On Sat, 4 Oct 2003, NAKAMURA, Hiroshi wrote:
my earlier post could have used an example, here is an example of where> Hi,
>>> > From: "Ara.T.Howard" <ahoward@fsl.noaa.gov>
> > Sent: Saturday, October 04, 2003 11:12 AM>> > if i want to write a webrick application that mounts many servlets do i need
> > to be concerned that, if one of the servlets blocks on i/o, the entire
> > (threaded) webserver will also be blocked?
> No. WEBrick creates worker thread for each request.
> So, take care if you mount a servlet factory which returns
> singleton servlet instance. It runs under MT condition.
>
> Regards,
> // NaHi
blocking in one request seems to block the entire server:
----CUT----
#!/usr/local/ruby-1.8.0/bin/ruby
require 'webrick'
include WEBrick
system 'mkfifo fifo' rescue nil
port = (ARGV[0] or 2003).to_i
s = HTTPServer.new( :Port => port )
#res.body = "<HTML>hello, world.</HTML>"
#res['Content-Type'] = "text/html"
class TimeServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
res['Content-Type'] = "text/plain"
res.body = Time.now.to_s
end
end
class ReadServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
res['Content-Type'] = "text/plain"
fifo = open 'fifo', 'r'
res.body = fifo.read
end
end
class WriteServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
res['Content-Type'] = "text/plain"
fifo = open 'fifo', 'w'
msg = "%s:%s" % [self.class, Time.now.to_s]
fifo.puts msg
res.body = "wrote <%s>" % [msg]
end
end
s.mount("/write", WriteServlet)
s.mount("/read", ReadServlet)
s.mount("/time", TimeServlet)
trap("INT"){ s.shutdown }
s.start
----CUT----
now, if you run this and then point your browser at
[url]http://127.0.0.1:2003/time[/url]
you will see the time. however, if you then try one, or more, of the
following in any order
[url]http://127.0.0.1:2003/read[/url]
[url]http://127.0.0.1:2003/write[/url]
and return to
[url]http://127.0.0.1:2003/time[/url]
you will see ALL windows hanging. does this make sense? how does one go
about designing servlets which will then block, like POST servlets, in a way
that would not block the entire webserver?
thanks.
-a
====================================
| Ara Howard
| NOAA Forecast Systems Laboratory
| Information and Technology Services
| Data Systems Group
| R/FST 325 Broadway
| Boulder, CO 80305-3328
| Email: [email]ara.t.howard@noaa.gov[/email]
| Phone: 303-497-7238
| Fax: 303-497-7259
| The difference between art and science is that science is what we understand
| well enough to explain to a computer. Art is everything else.
| -- Donald Knuth, "Discover"
| ~ > /bin/sh -c 'for lang in ruby perl; do $lang -e "print \"\x3a\x2d\x29\x0a\""; done'
====================================
Ara.T.Howard Guest
-
NAKAMURA, Hiroshi #4
Re: webrick, threads, and i/o
Hi,
> From: "Ara.T.Howard" <ahoward@fsl.noaa.gov>
> Sent: Saturday, October 04, 2003 3:13 PMI didn't check the article, but...> my earlier post could have used an example, here is an example of where
> blocking in one request seems to block the entire server:
You open fifo with blocking mode and read here. Blocking entire process> fifo = open 'fifo', 'r'
> res.body = fifo.read
here is expected behavior if I understand correctly.
> fifo = open 'fifo', 'w'
> msg = "%s:%s" % [self.class, Time.now.to_s]
> fifo.puts msgI think the process is blocked at the second access. Does third> now, if you run this and then point your browser at
>
> [url]http://127.0.0.1:2003/time[/url]
>
> you will see the time. however, if you then try one, or more, of the
> following in any order
>
> [url]http://127.0.0.1:2003/read[/url]
> [url]http://127.0.0.1:2003/write[/url]
access works?
You can open fifo with File::RDONLY|File::NONBLOCK for read side and> you will see ALL windows hanging. does this make sense? how does one go
> about designing servlets which will then block, like POST servlets, in a way
> that would not block the entire webserver?
File::WRONLY|File::NONBLOCK for write side. I think it should work.
In other words, if you want the server never blocks no matter what
servlets do, you should use other process forking WWW server application,
or should make your server using WEBrick as a toolkit.
Regards,
// NaHi
NAKAMURA, Hiroshi Guest
-
Ara.T.Howard #5
Re: webrick, threads, and i/o
On Sat, 4 Oct 2003, NAKAMURA, Hiroshi wrote:
o.k. - that is what i was trying to confirm: that one must be careful using> You open fifo with blocking mode and read here. Blocking entire process
> here is expected behavior if I understand correctly.
webrick when doing something in a servlet that could block a process in the
kernel... good (and not unexpected) to know.
no!? i think it's a case of thread starvation here. one servlet is blocked> I think the process is blocked at the second access. Does third
> access works?
opening the fifo for reading, but the other cannot open it for writing since
the entire process has halting on the first open...
strangley, this does not work:> You can open fifo with File::RDONLY|File::NONBLOCK for read side and
> File::WRONLY|File::NONBLOCK for write side. I think it should work.
----CUT----
#!/usr/local/ruby-1.8.0/bin/ruby
require 'webrick'
include WEBrick
# or set this up by hand before!
system 'mkfifo fifo && chmod 777 fifo' rescue nil
port = (ARGV[0] or 2003).to_i
s = HTTPServer.new( :Port => port )
class TimeServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
res['Content-Type'] = "text/plain"
res.body = Time.now.to_s
end
end
class ReadServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
res['Content-Type'] = "text/plain"
res.body =
begin
fifo = open 'fifo', File::RDWR|File::NONBLOCK
begin
fifo.read
rescue Errno::EWOULDBLOCK
'NO DATA'
end
rescue Exception => e
e.to_s << "\n" << e.backtrace.join("\n")
end
end
end
class WriteServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
res['Content-Type'] = "text/plain"
res.body =
begin
fifo = open 'fifo', File::RDWR|File::NONBLOCK
begin
msg = "%s:%s" % [self.class, Time.now.to_s]
fifo.puts msg
fifo.flush
"WROTE <%s>" % [msg]
rescue Errno::EWOULDBLOCK
'COULD NOT WRITE'
end
rescue Exception => e
e.to_s << "\n" << e.backtrace.join("\n")
end
end
end
s.mount("/write", WriteServlet)
s.mount("/read", ReadServlet)
s.mount("/time", TimeServlet)
trap("INT"){ s.shutdown }
s.start
----CUT----
while this does:
----CUT----
#!/usr/local/ruby-1.8.0/bin/ruby
system 'mkfifo fifo && chmod 777 fifo' rescue nil
r = open 'fifo', File::RDWR|File::NONBLOCK
w = open 'fifo', File::RDWR|File::NONBLOCK
w.puts 'hi'
w.flush
puts r.gets
----CUT----
so i think the logic in my servlets is correct. this is very strange?!
what's really strange about the above is that the WriteServlet DOES work, only
the ReadServlet hangs in the browser. however, even when it hanging the other
servlets (Write, Time) continue to work, so it is not as if the _process_ is
blocked, only the ReadServlet request thread!?
well - the first would require NOT using ruby so that's NOT an option! ;-)> In other words, if you want the server never blocks no matter what servlets
> do, you should use other process forking WWW server application, or should
> make your server using WEBrick as a toolkit.
as for the second, i'm unsure as to the best way to accomplish blocking
tasking from servlets:
a) have a dedicated worker thread so all, IO for example, is done carefully
there...
b) fire up a Drb object (in another process) and use it to perform, for
example, io. (does Drb work on windows?)
??
any other ideas?
thanks very much.
-a
====================================
| Ara Howard
| NOAA Forecast Systems Laboratory
| Information and Technology Services
| Data Systems Group
| R/FST 325 Broadway
| Boulder, CO 80305-3328
| Email: [email]ara.t.howard@noaa.gov[/email]
| Phone: 303-497-7238
| Fax: 303-497-7259
| The difference between art and science is that science is what we understand
| well enough to explain to a computer. Art is everything else.
| -- Donald Knuth, "Discover"
| ~ > /bin/sh -c 'for lang in ruby perl; do $lang -e "print \"\x3a\x2d\x29\x0a\""; done'
====================================
Ara.T.Howard Guest



Reply With Quote

