Project

General

Profile

Feature #3944

Add Fiber#root? method

Added by mperham (Mike Perham) over 6 years ago. Updated about 2 months ago.

Status:
Rejected
Priority:
Normal
Target version:
-
[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 naruse (Yui NARUSE) over 6 years ago

  • Assignee set to ko1 (Koichi Sasada)
  • Status changed from Open to Assigned

#2 [ruby-core:42778] Updated by godfat (Lin Jen-Shin) about 5 years ago

Any progress on this?

#3 [ruby-core:45849] Updated by ko1 (Koichi Sasada) almost 5 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 ko1 (Koichi Sasada) over 4 years ago

  • Status changed from Assigned to Feedback

#5 [ruby-core:48560] Updated by ko1 (Koichi Sasada) over 4 years ago

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

#6 [ruby-core:53068] Updated by schmurfy (Julien A) about 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 zzak (Zachary Scott) about 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 ko1 (Koichi Sasada) over 3 years ago

  • Status changed from Assigned to Feedback

#9 [ruby-core:62708] Updated by jjyr (jy j) almost 3 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 ko1 (Koichi Sasada) almost 3 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 Nakilon (Victor Maslov) about 1 year 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 nobu (Nobuyoshi Nakada) 10 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 spatulasnout (B Kelly) 10 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 Nakilon (Victor Maslov) 10 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 christopheraue (Christopher Aue) 4 months 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

#16 [ruby-core:79340] Updated by ko1 (Koichi Sasada) about 2 months ago

Sorry for very late response.

Victor Maslov wrote:

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.

You shouldn't rely on root? because some libraries (for example, some kind of Enumerator objects) use fibers.

#17 [ruby-core:79341] Updated by ko1 (Koichi Sasada) about 2 months ago

  • Status changed from Feedback to Rejected

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 same reason of #16, you shouldn't use it.

Also available in: Atom PDF