Skip to content
This repository has been archived by the owner on May 17, 2023. It is now read-only.

FiberError when calling ContentDirectory#Browse #14

Open
sidoh opened this issue Jun 23, 2015 · 0 comments
Open

FiberError when calling ContentDirectory#Browse #14

sidoh opened this issue Jun 23, 2015 · 0 comments

Comments

@sidoh
Copy link

sidoh commented Jun 23, 2015

I'm using the following adaptation of the example in the Readme:

require 'playful/ssdp'
require 'playful/control_point/device'

EM.run do
  searcher = Playful::SSDP.search 'uuid'

  # Create a deferrable object that can be notified when the device we want
  # has been found and created.
  device_controller = EventMachine::DefaultDeferrable.new

  # This callback will get called when the device_creator callback is called
  # (which is called after the device has been created).
  device_controller.callback do |device|
    p device.service_list.map(&:service_type).inspect
    content_service = device.service_list.reject { |x| !x.service_type.include? 'ContentDirectory' }.first

    raise RuntimeError.new("Couldn't find ContentDirectory service") if content_service.nil?

      p content_service.Browse ObjectID: '0',
                               BrowseFlag: 'BrowseMetadata',
                               Filter: '*',
                               StartingIndex: '0',
                               RequestedCount: '0'
  end

  # Note that you don't have to check for items in the Channel or for when the
  # Channel is empty: EventMachine will pop objects off the Channel as soon as
  # they're put there and stop when there are none left.
  searcher.discovery_responses.pop do |notification|

    # Playful::ControlPoint::Device objects are EventMachine::Deferrables, so you
    # need to define callback and errback blocks to handle when the Device
    # object is done being created.
    device_creator = Playful::ControlPoint::Device.new(ssdp_notification: notification)

    device_creator.errback do
      puts "Failed creating the device."
      exit!
    end

    device_creator.callback do |built_device|
      puts "Device has been created now."

      # This lets the device_controller know that the device has been created,
      # calls its callback, and passes the built device to it.
      device_controller.set_deferred_status(:succeeded, built_device)
    end

    # This actually starts the Device creation process and will call the
    # callback or errback (above) when it's done.
    device_creator.fetch
  end
end

I always get this error:

(eval):11:in `yield': can't yield from root fiber (FiberError)
    from (eval):11:in `post'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/httpi-2.4.1/lib/httpi/adapter/em_http.rb:50:in `block in request'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/httpi-2.4.1/lib/httpi/adapter/em_http.rb:68:in `_request'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/httpi-2.4.1/lib/httpi/adapter/em_http.rb:50:in `request'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/httpi-2.4.1/lib/httpi.rb:161:in `request'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/httpi-2.4.1/lib/httpi.rb:133:in `post'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/savon-2.11.1/lib/savon/operation.rb:94:in `block in call_with_logging'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/savon-2.11.1/lib/savon/request_logger.rb:12:in `call'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/savon-2.11.1/lib/savon/request_logger.rb:12:in `log'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/savon-2.11.1/lib/savon/operation.rb:94:in `call_with_logging'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/savon-2.11.1/lib/savon/operation.rb:54:in `call'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/savon-2.11.1/lib/savon/client.rb:36:in `call'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/playful-0.1.0.alpha.1/lib/playful/control_point/service.rb:280:in `block in define_method_from_action'
    from /home/cmullins/code/me/echo/playground/control_point_test.rb:19:in `block (2 levels) in <top (required)>'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/em/deferrable.rb:151:in `call'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/em/deferrable.rb:151:in `set_deferred_status'
    from /home/cmullins/code/me/echo/playground/control_point_test.rb:64:in `block (3 levels) in <top (required)>'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/em/deferrable.rb:151:in `call'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/em/deferrable.rb:151:in `set_deferred_status'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/playful-0.1.0.alpha.1/lib/playful/control_point/device.rb:176:in `block in fetch'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/em/tick_loop.rb:55:in `call'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/em/tick_loop.rb:55:in `stop'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/em/tick_loop.rb:77:in `block in schedule'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/eventmachine.rb:968:in `call'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/eventmachine.rb:968:in `block in run_deferred_callbacks'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/eventmachine.rb:965:in `times'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/eventmachine.rb:965:in `run_deferred_callbacks'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `run_machine'
    from /home/cmullins/.rvm/gems/ruby-2.0.0-rc1/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `run'
    from /home/cmullins/code/me/echo/playground/control_point_test.rb:4:in `<top (required)>'
    from -e:1:in `load'
    from -e:1:in `<main>'

From poking around, it looks like it's related to em-synchrony doing stuff with http requests:

  1. unexpected "can't yield from root fiber" error igrigorik/em-synchrony#33
  2. [Faye::RackAdapter] can't yield from root fiber faye/faye#229

If I wrap the code that initiates the SOAP request in a Fiber.new block, it works:

fiber = Fiber.new do
      p content_service.Browse ObjectID: '0',
                               BrowseFlag: 'BrowseMetadata',
                               Filter: '*',
                               StartingIndex: '0',
                               RequestedCount: '0'
end
fiber.resume

Not sure if that's the correct thing to do. Would love to hear if there's a more idiomatic way to solve this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant