Project

General

Profile

Feature #3944

Add Fiber#root? method

Added by Mike Perham about 6 years ago. Updated 14 days ago.

Status:
Feedback
Priority:
Normal
Assignee:
[ruby-core:32777]

Description

Since the root fiber is treated differently than other Fibers (e.g. you can't yield from the root), code which can optionally use fibers for high-performance IO (in my case, the Mysql2 driver) needs Fiber#root? to know when it can use Fibers to execute a query versus using a standard blocking call.

History

#1 Updated by Yui NARUSE about 6 years ago

  • Status changed from Open to Assigned
  • Assignee set to Koichi Sasada

#2 [ruby-core:42778] Updated by Lin Jen-Shin almost 5 years ago

Any progress on this?

#3 [ruby-core:45849] Updated by Koichi Sasada over 4 years ago

  • Description updated (diff)

Sorry for long absent.

I'm not sure why Fiber#root? is needed.
Could you give the examples?
I think if you don't use Fiber#root, then Fiber#root? is not needed.
And I can't understand why Fiber#root is needed.
(I think Fiber#root is for Fiber#transfer)

#4 [ruby-core:47641] Updated by Koichi Sasada about 4 years ago

  • Status changed from Assigned to Feedback

#5 [ruby-core:48560] Updated by Koichi Sasada about 4 years ago

  • Status changed from Feedback to Assigned
  • Target version set to Next Major

#6 [ruby-core:53068] Updated by Julien A almost 4 years ago

what is Next Major ? 3.0 ???
The issue was more than 2 years ago, after looking at the code the implementation should not be a challenge and yet nothing.
it is so depressing watching the ruby redmine seriously...

#7 [ruby-core:53071] Updated by Zachary Scott almost 4 years ago

Julien please see ruby-core:45849 and also read up on the wiki: http://bugs.ruby-lang.org/projects/ruby/wiki/HowToRequestFeatures

#8 [ruby-core:57481] Updated by Koichi Sasada about 3 years ago

  • Status changed from Assigned to Feedback

#9 [ruby-core:62708] Updated by jy j over 2 years ago

Fiber#root is useful.
For example, I want write a method, when under EM::Synchrony environment it should use EM::Synchrony call(in fact is async call, and writing in sync, power by fiber), and when under Fiber#root, it should use sync call, so I need detect whether current fiber is root fiber.

#10 [ruby-core:63037] Updated by Koichi Sasada over 2 years ago

(2014/05/23 15:17), jjyruby@gmail.com wrote:

For example, I want write a method, when under EM::Synchrony environment it should use EM::Synchrony call(in fact is async call, and writing in sync, power by fiber), and when under Fiber#root, it should use sync call, so I need detect whether current fiber is root fiber.

Could you break down the description?
I don't know EM::Synchrony.

Why you need to choose root or not root?

--
// SASADA Koichi at atdot dot net

#11 [ruby-core:74280] Updated by Victor Maslov 9 months ago

For example, the Facebook Graph API server accepts POST request to calculate smth heavy and returns id of the 'async job'. Then I GET status until it's "complete" and then I GET the actual result.

To process thousands of requests I call my method_that_gets_data from inside Fiber.new for each URL and cycle through them until they are done. Inside method_that_gets_data there are yeilds when doing the first POST and when status is not "complete", so I know when the fiber is done or I should just check another one.

Now I want to reuse the method_that_gets_data without fibers -- to know whether to yield or to work until done I need to know if I'm running inside Fiber or not.

#12 [ruby-core:75596] Updated by Nobuyoshi Nakada 7 months ago

  • Description updated (diff)

Couldn't anyone explain how the method will be used and why it will be necessary?
As far as I read, it sounds that it's EM specific and EM should take care of it.

#13 [ruby-core:75606] Updated by B Kelly 7 months ago

Nobuyoshi Nakada wrote:

Couldn't anyone explain how the method will be used and why it will be necessary?
As far as I read, it sounds that it's EM specific and EM should take care of it.

It might indeed be EM-specific.

I have an RPC library based around EventMachine and fibers. It needs to record
Fiber.current at the point EventMachine.run is called.

The library then uses RPC.on_em_fiber? (i.e. Fiber.current == @em_fiber)
to make necessary choices similar to those described by earlier posters.

If this is indeed equivalent to what earlier posters have requested, it does
seem like functionality that could be provided by EM or EM::Synchrony.

Regards,

Bill

#14 [ruby-core:75610] Updated by Victor Maslov 7 months ago

It might indeed be EM-specific.

I didn't use EM and not going to in the case I've described above.

#15 [ruby-core:78280] Updated by Christopher Aue 14 days ago

I also need Fiber#root?. My Scenario looks similar to the ones above, but I'm not using EM:

I have a loop watching sockets. This loop runs in a fiber. Each time a socket is readable another fiber is created to handle the request.

So, if I have a server only listening for requests:
1) I resume (i.e. start) the loop fiber,
2) resume (i.e. start) a dedicated fiber for each request,
3) yield to the loop fiber when the request itself needs to send a request to another server and must wait for the response,
4) resume the request fiber again once the response is there,
5) go to step 3) until the request is fully handled
6) yield to the main loop and go to step 1)

The loops starts at the beginning and runs forever. But that is what I expect a server to do. No problem.

But there is a second scenario, when I have a linear script with start and finish. This script uses the same code as the server above and during its course calls the same methods the server uses to handle its requests. Calling these methods sends the same requests to another server for which responses the script needs to wait. After the request is fully processed the script continues. Then the flow looks like this:

1) I'm processing the script on the root fiber.
2) When a request in need of a response from a server is encountered, I'm actually at a point corresponding to step 3) from above. But, I cannot yield back to the loop since it has not been started yet. I have to resume it.
3) From here, I'm at step 1) from above and can proceed accordingly.
4) Once my request is fully handled I need to yield from the loop to the root fiber to continue the script.

To decide if I need to resume the loop or yield to it, I need to know if the request originated from the root fiber or from one of the request fibers of the loop.

For a solution now, I have created a small gem monkey patching Thread and Fiber to get the root fiber: https://github.com/christopheraue/ruby-thread_root_fiber

Also available in: Atom PDF