#!/home/cabo/src/bin/ruby require 'webrick' require 'monitor' include WEBrick class SyncState < Monitor attr_reader :value def initialize @value = '' @cond = new_cond super end def set(value) synchronize do @value = value l = @cond.count_waiters @cond.broadcast l end end def news(oldvalue) synchronize do @cond.wait_while {oldvalue == @value}; @value end end end def no_cache(resp) resp['Content-Type'] = "text/plain" resp['Pragma'] = "no-cache" resp['Cache-Control'] = "no-cache" resp['Expires'] = "Thu, 01 Dec 1994 16:00:00 GMT" end class MyServlet < HTTPServlet::AbstractServlet def initialize(server, state) super @state = state end def do_GET(req, resp) no_cache(resp) url = req.query['url'] do_it(req, resp, url) end alias do_POST do_GET end class LeadServlet < MyServlet def do_it(req, resp, url) puts "before set ov=#{@state[url].value} nv=#{req.query['value']} #{Thread.list}" l = @state[url].set(req.query['value']) puts "after set nw=#{l}" resp.body = l.to_s end end class FollowServlet < MyServlet def do_it(req, resp, url) puts "before news #{req.query['value']} #{Thread.list}" resp.body = @state[url].news(req.query['value']) puts "after news #{resp.body}" end end state = Hash.new {|hash, key| hash[key] = SyncState.new } s = HTTPServer.new( :Port => 2000, :DocumentRoot => "/home/cabo/src/sync/site" ) s.mount("/lead", LeadServlet, state) s.mount("/follow", FollowServlet, state) trap("INT"){ s.shutdown } s.start