librelist archives

« back to archive

How to broadcast?

How to broadcast?

From:
Makoto Inoue
Date:
2010-03-14 @ 01:53
Hi Eric.

I remember I asked something similar at the end of last year, but I am
trying to use Sunshowers to broadcast message to all connected clients.

Here is the code I wrote. It uses ThreadPool mode.

http://gist.github.com/331696

I remember that I once asked you how to count all the connections, and you
told me not to use global variable or class variable to share all connection
info, as threaded pool mode does not share these variables.

To avoid that, I tried to persist the connection using Tokyo Tyrant (it can
be Redis or MySQL), but got TCPSocket error when I was trying to serialize
it.

TypeError: can't dump TCPSocket
config.ru:19:in `dump'
config.ru:19:in `add'
config.ru:48
/Library/Ruby/Gems/1.8/gems/rack-1.1.0/lib/rack/content_type.rb:17:in `call'
/Library/Ruby/Gems/1.8/gems/rack-1.1.0/lib/rack/content_type.rb:17:in `call'
/Library/Ruby/Gems/1.8/gems/rack-1.1.0/lib/rack/content_length.rb:13:in
`call'
/Library/Ruby/Gems/1.8/gems/rack-1.1.0/lib/rack/lint.rb:47:in `_call'
/Library/Ruby/Gems/1.8/gems/rack-1.1.0/lib/rack/lint.rb:35:in `call'
/Library/Ruby/Gems/1.8/gems/rack-1.1.0/lib/rack/showexceptions.rb:24:in
`call'
/Library/Ruby/Gems/1.8/gems/rack-1.1.0/lib/rack/commonlogger.rb:18:in `call'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows/base.rb:52:in
`process_client'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows/thread_pool.rb:47:in
`sync_worker'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows/thread_pool.rb:31:in
`worker_loop'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows/thread_pool.rb:31:in
`initialize'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows/thread_pool.rb:31:in
`new'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows/thread_pool.rb:31:in
`worker_loop'
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `map'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows/thread_pool.rb:30:in
`each'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows/thread_pool.rb:30:in
`map'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows/thread_pool.rb:30:in
`worker_loop'
/Library/Ruby/Gems/1.8/gems/unicorn-0.95.3/lib/unicorn.rb:531:in
`spawn_missing_workers'
/Library/Ruby/Gems/1.8/gems/unicorn-0.95.3/lib/unicorn.rb:531:in `fork'
/Library/Ruby/Gems/1.8/gems/unicorn-0.95.3/lib/unicorn.rb:531:in
`spawn_missing_workers'
/Library/Ruby/Gems/1.8/gems/unicorn-0.95.3/lib/unicorn.rb:527:in `each'
/Library/Ruby/Gems/1.8/gems/unicorn-0.95.3/lib/unicorn.rb:527:in
`spawn_missing_workers'
/Library/Ruby/Gems/1.8/gems/unicorn-0.95.3/lib/unicorn.rb:537:in
`maintain_worker_count'
/Library/Ruby/Gems/1.8/gems/unicorn-0.95.3/lib/unicorn.rb:215:in `start'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/lib/rainbows.rb:58:in `run'
/Library/Ruby/Gems/1.8/gems/rainbows-0.90.0/bin/rainbows:166
/usr/bin/rainbows:19:in `load'
/usr/bin/rainbows:19
127.0.0.1 - - [14/Mar/2010 01:32:41

I guess I can not serialize TCPSocket. Do you have any alternative
suggestions to broadcast message to all  the connections? If I use
EventMachine with single process, probably I can just use global variable to
store all the websockets connections. However, I am currently investigating
how to scale out WebSocket server environment either by utilising single
machine's multi core environment, or even using multiple machines if
possible.

Thanks.

Makoto

Re: [sunshowers] How to broadcast?

From:
Eric Wong
Date:
2010-03-14 @ 03:13
Makoto Inoue <inouemak@googlemail.com> wrote:
> Hi Eric.
> 
> I remember I asked something similar at the end of last year, but I am
> trying to use Sunshowers to broadcast message to all connected clients.
> 
> Here is the code I wrote. It uses ThreadPool mode.
> 
> http://gist.github.com/331696
> 
> I remember that I once asked you how to count all the connections, and you
> told me not to use global variable or class variable to share all connection
> info, as threaded pool mode does not share these variables.
> 
> To avoid that, I tried to persist the connection using Tokyo Tyrant (it can
> be Redis or MySQL), but got TCPSocket error when I was trying to serialize
> it.
> 
> TypeError: can't dump TCPSocket

<snip>

> I guess I can not serialize TCPSocket. Do you have any alternative
> suggestions to broadcast message to all  the connections? If I use
> EventMachine with single process, probably I can just use global variable to
> store all the websockets connections. However, I am currently investigating
> how to scale out WebSocket server environment either by utilising single
> machine's multi core environment, or even using multiple machines if
> possible.

Hi Makoto,

Correct, you can't serialize a TCPSocket.  You do need to keep a global,
per-process array of TCPSocket objects in this case...

As for triggering an action across multiple processes, trapping
SIGCONT is may be easiest, you can just "killall -CONT rainbows"
to trigger broadcast...

For other signals, you'd have to setup the signal handler only in the
workers and be sure to not hit the master Rainbows! process...

If you don't want to use signals, you can have a special endpoint in
your app:

  if env["PATH_INFO"] == "/private/broadcast"
    # the trusted? method is for you to implement:
    if trusted?(env["REMOTE_ADDR"])
      broadcast_all
    end
  end

Then, have a per-worker listener in Rainbows! so each worker is awoken:

  after_fork do |server, worker|
    # per-process listener ports for debugging/admin/migrations
    addr = "127.0.0.1:#{9293 + worker.nr}"
    server.listen(addr, :tries => -1, :delay => 5)
  end

Finally, just hit the endpoints for all ports:

  base = 9293
  nr_workers = 4 # match this to the number of Rainbows! worker_processes
  nr_workers.times do |i|
    uri = URI.parse("http://127.0.0.1:#{base+i}/private/broadcast")
    Net::HTTP.post_form(uri, {})
  end

For multiple machines, you would probably want to use UDP multicast
to trigger the per-machine broadcast.

Let us know if that works for you, I don't have much experience
here, actually.  Maybe somebody else can chime in with their
experiences.

-- 
Eric Wong

Re: [sunshowers] How to broadcast?

From:
Makoto Inoue
Date:
2010-03-14 @ 17:14
On Sun, Mar 14, 2010 at 3:13 AM, Eric Wong <normalperson@yhbt.net> wrote:

> Makoto Inoue <inouemak@googlemail.com> wrote:
> > Hi Eric.
> >
> > I remember I asked something similar at the end of last year, but I am
> > trying to use Sunshowers to broadcast message to all connected clients.
> >
> > Here is the code I wrote. It uses ThreadPool mode.
> >
> > http://gist.github.com/331696
> >
> > I remember that I once asked you how to count all the connections, and
> you
> > told me not to use global variable or class variable to share all
> connection
> > info, as threaded pool mode does not share these variables.
> >
> > To avoid that, I tried to persist the connection using Tokyo Tyrant (it
> can
> > be Redis or MySQL), but got TCPSocket error when I was trying to
> serialize
> > it.
> >
> > TypeError: can't dump TCPSocket
>
> <snip>
>
> > I guess I can not serialize TCPSocket. Do you have any alternative
> > suggestions to broadcast message to all  the connections? If I use
> > EventMachine with single process, probably I can just use global variable
> to
> > store all the websockets connections. However, I am currently
> investigating
> > how to scale out WebSocket server environment either by utilising single
> > machine's multi core environment, or even using multiple machines if
> > possible.
>
> Hi Makoto,
>
> Correct, you can't serialize a TCPSocket.  You do need to keep a global,
> per-process array of TCPSocket objects in this case...
>
> As for triggering an action across multiple processes, trapping
> SIGCONT is may be easiest, you can just "killall -CONT rainbows"
> to trigger broadcast...
>
> For other signals, you'd have to setup the signal handler only in the
> workers and be sure to not hit the master Rainbows! process...
>
> If you don't want to use signals, you can have a special endpoint in
> your app:
>
>  if env["PATH_INFO"] == "/private/broadcast"
>    # the trusted? method is for you to implement:
>    if trusted?(env["REMOTE_ADDR"])
>      broadcast_all
>    end
>  end
>
> Then, have a per-worker listener in Rainbows! so each worker is awoken:
>
>  after_fork do |server, worker|
>    # per-process listener ports for debugging/admin/migrations
>    addr = "127.0.0.1:#{9293 + worker.nr}"
>    server.listen(addr, :tries => -1, :delay => 5)
>  end
>
> Finally, just hit the endpoints for all ports:
>
>  base = 9293
>  nr_workers = 4 # match this to the number of Rainbows! worker_processes
>  nr_workers.times do |i|
>    uri = URI.parse("http://127.0.0.1:#{base+i}/private/broadcast")
>    Net::HTTP.post_form(uri, {})
>  end
>
> For multiple machines, you would probably want to use UDP multicast
> to trigger the per-machine broadcast.
>
> Let us know if that works for you, I don't have much experience
> here, actually.  Maybe somebody else can chime in with their
> experiences.
>
> --
> Eric Wong
>


Hi, Eric.

Thank you very much for your detailed advice. The signaling way is a bit
beyond my brain capacity , but the second option looks more sane ;-)  It's a
bit unfortunate that we loose the low latency of websockets if we do http
post. Maybe it can be TCP connections because they are rather server to
server communication? My friends advised me to use messaging system, such a
s AMQP, so I might look into that as well.


Makoto

Re: [sunshowers] How to broadcast?

From:
Makoto Inoue
Date:
2010-03-15 @ 11:04
On Sun, Mar 14, 2010 at 5:14 PM, Makoto Inoue <inouemak@googlemail.com>wrote:

>
> On Sun, Mar 14, 2010 at 3:13 AM, Eric Wong <normalperson@yhbt.net> wrote:
>
>> Makoto Inoue <inouemak@googlemail.com> wrote:
>> > Hi Eric.
>> >
>> > I remember I asked something similar at the end of last year, but I am
>> > trying to use Sunshowers to broadcast message to all connected clients.
>> >
>> > Here is the code I wrote. It uses ThreadPool mode.
>> >
>> > http://gist.github.com/331696
>> >
>> > I remember that I once asked you how to count all the connections, and
>> you
>> > told me not to use global variable or class variable to share all
>> connection
>> > info, as threaded pool mode does not share these variables.
>> >
>> > To avoid that, I tried to persist the connection using Tokyo Tyrant (it
>> can
>> > be Redis or MySQL), but got TCPSocket error when I was trying to
>> serialize
>> > it.
>> >
>> > TypeError: can't dump TCPSocket
>>
>> <snip>
>>
>> > I guess I can not serialize TCPSocket. Do you have any alternative
>> > suggestions to broadcast message to all  the connections? If I use
>> > EventMachine with single process, probably I can just use global
>> variable to
>> > store all the websockets connections. However, I am currently
>> investigating
>> > how to scale out WebSocket server environment either by utilising single
>> > machine's multi core environment, or even using multiple machines if
>> > possible.
>>
>> Hi Makoto,
>>
>> Correct, you can't serialize a TCPSocket.  You do need to keep a global,
>> per-process array of TCPSocket objects in this case...
>>
>> As for triggering an action across multiple processes, trapping
>> SIGCONT is may be easiest, you can just "killall -CONT rainbows"
>> to trigger broadcast...
>>
>> For other signals, you'd have to setup the signal handler only in the
>> workers and be sure to not hit the master Rainbows! process...
>>
>> If you don't want to use signals, you can have a special endpoint in
>> your app:
>>
>>  if env["PATH_INFO"] == "/private/broadcast"
>>    # the trusted? method is for you to implement:
>>    if trusted?(env["REMOTE_ADDR"])
>>      broadcast_all
>>    end
>>  end
>>
>> Then, have a per-worker listener in Rainbows! so each worker is awoken:
>>
>>  after_fork do |server, worker|
>>    # per-process listener ports for debugging/admin/migrations
>>    addr = "127.0.0.1:#{9293 + worker.nr}"
>>    server.listen(addr, :tries => -1, :delay => 5)
>>  end
>>
>> Finally, just hit the endpoints for all ports:
>>
>>  base = 9293
>>  nr_workers = 4 # match this to the number of Rainbows! worker_processes
>>  nr_workers.times do |i|
>>    uri = URI.parse("http://127.0.0.1:#{base+i}/private/broadcast")
>>    Net::HTTP.post_form(uri, {})
>>  end
>>
>> For multiple machines, you would probably want to use UDP multicast
>> to trigger the per-machine broadcast.
>>
>> Let us know if that works for you, I don't have much experience
>> here, actually.  Maybe somebody else can chime in with their
>> experiences.
>>
>> --
>> Eric Wong
>>
>
>
> Hi, Eric.
>
> Thank you very much for your detailed advice. The signaling way is a bit
> beyond my brain capacity , but the second option looks more sane ;-)  It's a
> bit unfortunate that we loose the low latency of websockets if we do http
> post. Maybe it can be TCP connections because they are rather server to
> server communication? My friends advised me to use messaging system, such a
> s AMQP, so I might look into that as well.
>
>
> Makoto
>
>

Hi, Eric.

Which concurrency model supports to have just use one process/one thread
which can share @connection without trying to implement complex logic like
we are discussing now?


worker_processes 1
Rainbows! do
  use :Revactor
  worker_connections 200
end

When I chose Revactor (with ruby 1.9) with one process like the above, I am
getting this error message. The same code works fine if I use ThreadPool
(but it won't share @connections among threads).


[#<struct Sunshowers::IO to_io=#<Revactor::TCP::Socket:0x80a21e80
127.0.0.1:50587>, buf="", keep_binary=nil>]
[#<struct Sunshowers::IO to_io=#<Revactor::TCP::Socket:0x80a21e80
127.0.0.1:50587>, buf="", keep_binary=nil>, #<struct Sunshowers::IO
to_io=#<Revactor::TCP::Socket:0x809e56f8 127.0.0.1:50590>, buf="",
keep_binary=nil>]
"{\"name\":\"mousedown\",\"content\":[65,40]}"
RuntimeError: already being called synchronously

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/revactor-0.1.5/lib/revactor/tcp.rb:215:in
`write'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/sunshowers-0.2.0/lib/sunshowers/io.rb:72:in
`syswrite'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/sunshowers-0.2.0/lib/sunshowers/io.rb:82:in
`write_utf8'
config.ru:109:in `block (4 levels) in <main>'
config.ru:107:in `each'
config.ru:107:in `block (3 levels) in <main>'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/sunshowers-0.2.0/lib/sunshowers/io.rb:47:in
`each'
config.ru:105:in `block (2 levels) in <main>'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib/rack/content_type.rb:17:in
`call'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib/rack/content_type.rb:17:in
`call'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib/rack/content_length.rb:13:in
`call'
/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib/rack/lint.rb:47:in
`_call'
/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib/rack/lint.rb:35:in
`call'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib/rack/showexceptions.rb:24:in
`call'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib/rack/commonlogger.rb:18:in
`call'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/rainbows-0.91.0/lib/rainbows/revactor.rb:57:in
`process_client'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/rainbows-0.91.0/lib/rainbows/revactor.rb:107:in
`block (5 levels) in worker_loop'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/revactor-0.1.5/lib/revactor/actor.rb:143:in
`call'

/Users/makoto/.rvm/gems/ruby-1.9.1-p378/gems/revactor-0.1.5/lib/revactor/actor.rb:143:in
`block in _spawn'
127.0.0.1 - - [15/Mar/2010 10:45:07] "GET / HTTP/1.1" 500 56556 2.4034

Re: [sunshowers] How to broadcast?

From:
Eric Wong
Date:
2010-03-15 @ 17:53
Makoto Inoue <inouemak@googlemail.com> wrote:
> On Sun, Mar 14, 2010 at 5:14 PM, Makoto Inoue <inouemak@googlemail.com>wrote:
> > On Sun, Mar 14, 2010 at 3:13 AM, Eric Wong <normalperson@yhbt.net> wrote:
> >
> >> Makoto Inoue <inouemak@googlemail.com> wrote:
> >> > Hi Eric.
> >> >
> >> > I remember I asked something similar at the end of last year, but I am
> >> > trying to use Sunshowers to broadcast message to all connected clients.
> >> >
> >> > Here is the code I wrote. It uses ThreadPool mode.
> >> >
> >> > http://gist.github.com/331696
> >> >
> >> > I remember that I once asked you how to count all the connections, and
> >> you
> >> > told me not to use global variable or class variable to share all
> >> connection
> >> > info, as threaded pool mode does not share these variables.
> >> >
> >> > To avoid that, I tried to persist the connection using Tokyo Tyrant (it
> >> can
> >> > be Redis or MySQL), but got TCPSocket error when I was trying to
> >> serialize
> >> > it.
> >> >
> >> > TypeError: can't dump TCPSocket
> >>
> >> <snip>
> >>
> >> > I guess I can not serialize TCPSocket. Do you have any alternative
> >> > suggestions to broadcast message to all  the connections? If I use
> >> > EventMachine with single process, probably I can just use global
> >> variable to
> >> > store all the websockets connections. However, I am currently
> >> investigating
> >> > how to scale out WebSocket server environment either by utilising single
> >> > machine's multi core environment, or even using multiple machines if
> >> > possible.
> >>
> >> Hi Makoto,
> >>
> >> Correct, you can't serialize a TCPSocket.  You do need to keep a global,
> >> per-process array of TCPSocket objects in this case...
> >>
> >> As for triggering an action across multiple processes, trapping
> >> SIGCONT is may be easiest, you can just "killall -CONT rainbows"
> >> to trigger broadcast...
> >>
> >> For other signals, you'd have to setup the signal handler only in the
> >> workers and be sure to not hit the master Rainbows! process...
> >>
> >> If you don't want to use signals, you can have a special endpoint in
> >> your app:
> >>
> >>  if env["PATH_INFO"] == "/private/broadcast"
> >>    # the trusted? method is for you to implement:
> >>    if trusted?(env["REMOTE_ADDR"])
> >>      broadcast_all
> >>    end
> >>  end
> >>
> >> Then, have a per-worker listener in Rainbows! so each worker is awoken:
> >>
> >>  after_fork do |server, worker|
> >>    # per-process listener ports for debugging/admin/migrations
> >>    addr = "127.0.0.1:#{9293 + worker.nr}"
> >>    server.listen(addr, :tries => -1, :delay => 5)
> >>  end
> >>
> >> Finally, just hit the endpoints for all ports:
> >>
> >>  base = 9293
> >>  nr_workers = 4 # match this to the number of Rainbows! worker_processes
> >>  nr_workers.times do |i|
> >>    uri = URI.parse("http://127.0.0.1:#{base+i}/private/broadcast")
> >>    Net::HTTP.post_form(uri, {})
> >>  end
> >>
> >> For multiple machines, you would probably want to use UDP multicast
> >> to trigger the per-machine broadcast.
> >>
> >> Let us know if that works for you, I don't have much experience
> >> here, actually.  Maybe somebody else can chime in with their
> >> experiences.
> >
> > Hi, Eric.
> >
> > Thank you very much for your detailed advice. The signaling way is a bit
> > beyond my brain capacity , but the second option looks more sane ;-)  It's a
> > bit unfortunate that we loose the low latency of websockets if we do http
> > post. Maybe it can be TCP connections because they are rather server to
> > server communication? My friends advised me to use messaging system, such a
> > s AMQP, so I might look into that as well.
> 
> Hi, Eric.
> 
> Which concurrency model supports to have just use one process/one thread
> which can share @connection without trying to implement complex logic like
> we are discussing now?
> 
> 
> worker_processes 1
> Rainbows! do
>   use :Revactor
>   worker_connections 200
> end
> 
> When I chose Revactor (with ruby 1.9) with one process like the above, I am
> getting this error message. The same code works fine if I use ThreadPool
> (but it won't share @connections among threads).

Hi Makoto,

Can you try FiberSpawn or RevFiberSpawn out?  There are some issues in
Revactor that are still confusing to me, you might want to check the
Revactor mailing list and see if someone there can help us.

-- 
Eric Wong

Re: [sunshowers] How to broadcast?

From:
Makoto Inoue
Date:
2010-03-15 @ 22:06
On Mon, Mar 15, 2010 at 5:53 PM, Eric Wong <normalperson@yhbt.net> wrote:

> Makoto Inoue <inouemak@googlemail.com> wrote:
> > On Sun, Mar 14, 2010 at 5:14 PM, Makoto Inoue <inouemak@googlemail.com
> >wrote:
> > > On Sun, Mar 14, 2010 at 3:13 AM, Eric Wong <normalperson@yhbt.net>
> wrote:
> > >
> > >> Makoto Inoue <inouemak@googlemail.com> wrote:
> > >> > Hi Eric.
> > >> >
> > >> > I remember I asked something similar at the end of last year, but I
> am
> > >> > trying to use Sunshowers to broadcast message to all connected
> clients.
> > >> >
> > >> > Here is the code I wrote. It uses ThreadPool mode.
> > >> >
> > >> > http://gist.github.com/331696
> > >> >
> > >> > I remember that I once asked you how to count all the connections,
> and
> > >> you
> > >> > told me not to use global variable or class variable to share all
> > >> connection
> > >> > info, as threaded pool mode does not share these variables.
> > >> >
> > >> > To avoid that, I tried to persist the connection using Tokyo Tyrant
> (it
> > >> can
> > >> > be Redis or MySQL), but got TCPSocket error when I was trying to
> > >> serialize
> > >> > it.
> > >> >
> > >> > TypeError: can't dump TCPSocket
> > >>
> > >> <snip>
> > >>
> > >> > I guess I can not serialize TCPSocket. Do you have any alternative
> > >> > suggestions to broadcast message to all  the connections? If I use
> > >> > EventMachine with single process, probably I can just use global
> > >> variable to
> > >> > store all the websockets connections. However, I am currently
> > >> investigating
> > >> > how to scale out WebSocket server environment either by utilising
> single
> > >> > machine's multi core environment, or even using multiple machines if
> > >> > possible.
> > >>
> > >> Hi Makoto,
> > >>
> > >> Correct, you can't serialize a TCPSocket.  You do need to keep a
> global,
> > >> per-process array of TCPSocket objects in this case...
> > >>
> > >> As for triggering an action across multiple processes, trapping
> > >> SIGCONT is may be easiest, you can just "killall -CONT rainbows"
> > >> to trigger broadcast...
> > >>
> > >> For other signals, you'd have to setup the signal handler only in the
> > >> workers and be sure to not hit the master Rainbows! process...
> > >>
> > >> If you don't want to use signals, you can have a special endpoint in
> > >> your app:
> > >>
> > >>  if env["PATH_INFO"] == "/private/broadcast"
> > >>    # the trusted? method is for you to implement:
> > >>    if trusted?(env["REMOTE_ADDR"])
> > >>      broadcast_all
> > >>    end
> > >>  end
> > >>
> > >> Then, have a per-worker listener in Rainbows! so each worker is
> awoken:
> > >>
> > >>  after_fork do |server, worker|
> > >>    # per-process listener ports for debugging/admin/migrations
> > >>    addr = "127.0.0.1:#{9293 + worker.nr}"
> > >>    server.listen(addr, :tries => -1, :delay => 5)
> > >>  end
> > >>
> > >> Finally, just hit the endpoints for all ports:
> > >>
> > >>  base = 9293
> > >>  nr_workers = 4 # match this to the number of Rainbows!
> worker_processes
> > >>  nr_workers.times do |i|
> > >>    uri = URI.parse("http://127.0.0.1:#{base+i}/private/broadcast")
> > >>    Net::HTTP.post_form(uri, {})
> > >>  end
> > >>
> > >> For multiple machines, you would probably want to use UDP multicast
> > >> to trigger the per-machine broadcast.
> > >>
> > >> Let us know if that works for you, I don't have much experience
> > >> here, actually.  Maybe somebody else can chime in with their
> > >> experiences.
> > >
> > > Hi, Eric.
> > >
> > > Thank you very much for your detailed advice. The signaling way is a
> bit
> > > beyond my brain capacity , but the second option looks more sane ;-)
>  It's a
> > > bit unfortunate that we loose the low latency of websockets if we do
> http
> > > post. Maybe it can be TCP connections because they are rather server to
> > > server communication? My friends advised me to use messaging system,
> such a
> > > s AMQP, so I might look into that as well.
> >
> > Hi, Eric.
> >
> > Which concurrency model supports to have just use one process/one thread
> > which can share @connection without trying to implement complex logic
> like
> > we are discussing now?
> >
> >
> > worker_processes 1
> > Rainbows! do
> >   use :Revactor
> >   worker_connections 200
> > end
> >
> > When I chose Revactor (with ruby 1.9) with one process like the above, I
> am
> > getting this error message. The same code works fine if I use ThreadPool
> > (but it won't share @connections among threads).
>
> Hi Makoto,
>
> Can you try FiberSpawn or RevFiberSpawn out?  There are some issues in
> Revactor that are still confusing to me, you might want to check the
> Revactor mailing list and see if someone there can help us.
>
> --
> Eric Wong
>


Thanks Eric. FiberSpawn seems working fine with one process