celluloid / reel

UNMAINTAINED: See celluloid/celluloid#779 - Celluloid::IO-powered web server
https://celluloid.io
MIT License
595 stars 87 forks source link

Cannot execute blocks on sender in exclusive mode #78

Closed kostya closed 11 years ago

kostya commented 11 years ago
require 'bundler/setup'
require 'reel'
require 'celluloid'

class A
  include Celluloid

  def run
    exclusive { start_server }
  end

  def start_server
    @server = Reel::Server.supervise('127.0.0.1', 12345) do |connection|
      while request = connection.request
        connection.respond(Reel::Response.new(:ok, "Hello world"))
      end
    end
  end
end

a = A.new
a.run

sleep
D, [2013-08-12T02:31:09.789693 #19693] DEBUG -- : Terminating 5 actors...
E, [2013-08-12T02:31:09.790925 #19693] ERROR -- : A crashed!
RuntimeError: Cannot execute blocks on sender in exclusive mode
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:11:in `initialize'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:58:in `initialize'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/proxies/sync_proxy.rb:20:in `new'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/proxies/sync_proxy.rb:20:in `method_missing'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/legacy.rb:14:in `method_missing'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/proxies/actor_proxy.rb:25:in `_send_'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid.rb:129:in `new'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/supervisor.rb:10:in `supervise'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid.rb:148:in `supervise'
    12.rb:13:in `start_server'
    12.rb:9:in `block in run'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/actor.rb:208:in `exclusive'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid.rb:452:in `exclusive'
    12.rb:9:in `run'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:25:in `public_send'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:25:in `dispatch'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:67:in `dispatch'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/actor.rb:326:in `block in handle_message'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/tasks.rb:42:in `block in initialize'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/tasks/task_fiber.rb:11:in `block in create'
    (celluloid):0:in `remote procedure call'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:95:in `value'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/proxies/sync_proxy.rb:28:in `method_missing'
    /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/legacy.rb:14:in `method_missing'
    12.rb:22:in `<main>'
D, [2013-08-12T02:31:09.798722 #19693] DEBUG -- : Shutdown completed cleanly
/home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:11:in `initialize': Cannot execute blocks on sender in exclusive mode (RuntimeError)
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:58:in `initialize'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/proxies/sync_proxy.rb:20:in `new'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/proxies/sync_proxy.rb:20:in `method_missing'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/legacy.rb:14:in `method_missing'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/proxies/actor_proxy.rb:25:in `_send_'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid.rb:129:in `new'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/supervisor.rb:10:in `supervise'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid.rb:148:in `supervise'
    from 12.rb:13:in `start_server'
    from 12.rb:9:in `block in run'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/actor.rb:208:in `exclusive'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid.rb:452:in `exclusive'
    from 12.rb:9:in `run'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:25:in `public_send'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:25:in `dispatch'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:67:in `dispatch'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/actor.rb:326:in `block in handle_message'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/tasks.rb:42:in `block in initialize'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/tasks/task_fiber.rb:11:in `block in create'
    from (celluloid):0:in `remote procedure call'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/calls.rb:95:in `value'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/proxies/sync_proxy.rb:28:in `method_missing'
    from /home/kostya/.rvm/gems/ruby-2.0.0-p0/gems/celluloid-0.14.1/lib/celluloid/legacy.rb:14:in `method_missing'
    from 12.rb:22:in `<main>'

0.13.0 works

tarcieri commented 11 years ago

I'm guessing this is a limitation of the present block implementation /cc @halorgium

halorgium commented 11 years ago

The main issue here is the supervisor implementation, it sometimes uses blocks for configuration which show this error in exclusive mode. Is there a reason you are using an exclusive block? I am guessing there is more surrounding code.

kostya commented 11 years ago

just found

exclusive :start_server

this is works, thanks.

kostya commented 11 years ago

bug remains when call method directly

require 'bundler/setup'
require 'reel'
require 'celluloid'

class A
  include Celluloid

  exclusive :start_server

  def run
    start_server
  end

  def start_server
    @server = Reel::Server.supervise('127.0.0.1', 12345) do |connection|
      while request = connection.request
        connection.respond(Reel::Response.new(:ok, "Hello world"))
      end
    end
  end
end

when

a = A.new
a.run
sleep

all is ok

when

a = A.new
a.start_server
sleep

Cannot execute blocks on sender in exclusive mode

tarcieri commented 11 years ago

@kostya can you try master of both Celluloid and Reel? There were some bugs in the block changes where it wasn't being reflected by Reel.

Reel's block (the one passed to initialize) should get called on Reel itself, not "A", but that's what appears to be happening.

kostya commented 11 years ago

on master all the same, run works, start_server fails.

except that, when stopping run script, got (if it matter)

[2013-08-13T00:34:25.732398 #7571] DEBUG -- : Terminating 7 actors...
D, [2013-08-13T00:34:25.748397 #7571] DEBUG -- : Discarded message (mailbox is dead): #<Celluloid::ExitEvent:0x86672b0>
D, [2013-08-13T00:34:25.749087 #7571] DEBUG -- : Discarded message (mailbox is dead): #<Celluloid::TerminationRequest:0x8667738>
D, [2013-08-13T00:34:25.754866 #7571] DEBUG -- : Discarded message (mailbox is dead): #<Celluloid::TerminationRequest:0x8667990>
D, [2013-08-13T00:34:25.755403 #7571] DEBUG -- : Discarded message (mailbox is dead): #<Celluloid::ExitEvent:0x8667968>
D, [2013-08-13T00:34:25.757106 #7571] DEBUG -- : Discarded message (mailbox is dead): #<Celluloid::TerminationRequest:0x8666360>
W, [2013-08-13T00:34:25.757695 #7571]  WARN -- : Terminating task: type=:call, meta={:method_name=>:run}, status=:iowait
D, [2013-08-13T00:34:25.758461 #7571] DEBUG -- : Discarded message (mailbox is dead): #<Celluloid::ExitEvent:0x86661d0>
12.rb:26:in `sleep': Interrupt
    from 12.rb:26:in `<main>'
tarcieri commented 11 years ago

It's odd you would get this error on master as Reel is specifically configured to execute its #initialize block on itself:

https://github.com/celluloid/reel/blob/master/lib/reel/server.rb#L8

/cc @halorgium any ideas?

tarcieri commented 11 years ago

@kostya can you open an issue on Celluloid instead, if the issue persists in Celluloid 0.15?