Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make pg more Ruby-3.0 fiber scheduler friendly #342

Closed
larskanis opened this issue Jul 6, 2020 · 7 comments · Fixed by #397
Closed

Make pg more Ruby-3.0 fiber scheduler friendly #342

larskanis opened this issue Jul 6, 2020 · 7 comments · Fixed by #397

Comments

@larskanis
Copy link
Collaborator

This was raised by @ioquatix in ffi/ffi#797 (comment) :

In order to support the upcoming Ruby 3.0 fiber scheduler, you need to do only one thing:

When you would call a blocking function that does I/O, instead call IO#wait_readable or IO#wait_writable respectively.

If you want to support Ruby 2.x, then allow the user to inject a custom IO class, which responds to .new and implements #wait_readable and #wait_writable.

You can check how to do it here:

https://github.com/socketry/db-postgres/blob/6fbdd03dd6b04c57c5b7995b60e3f626c674e609/lib/db/postgres/native/connection.rb#L106-L139

We will be augmenting the C interface with some improvements for invoking IO#wait_readable/wait_writable but it hasn't landed yet.

Feature description is here: https://bugs.ruby-lang.org/issues/16786

@ioquatix
Copy link
Contributor

ioquatix commented Jul 6, 2020

Awesome, let me know if I can provide any further help :)

cc @tenderlove

@jasl
Copy link
Contributor

jasl commented Dec 23, 2020

I just wrote a PoC

class PG::Connection
  module FiberScheduler
    [
      :exec, :query, :exec_params, :prepare,
      :exec_prepared, :describe_portal, :describe_prepared
    ].each do |method|
      module_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{method}
          Fiber.scheduler.io_wait(socket_io, IO::WRITABLE, 5)
          super
          Fiber.scheduler.io_wait(socket_obj, IO::READABLE, 5)
        end
      CODE
    end
  end
  include FiberScheduler
end

then do set evt as Fiber scheduler in spec_helpers

It's dirty, but pass all tests (except connection_spec and connection_sync_spec tests)

Any directive or guidance?

A question, I'm stucking on adding evt to Gemfile but failed to require it for 10 minutes, then I found I need to declare it in Rakefile, any historical reason for using Hoe not use standard Gemfile directly?

@jasl
Copy link
Contributor

jasl commented Dec 24, 2020

@larskanis @ioquatix could you take a look PR #364 ?

I'm done a PR:

  • Change behavior of PG::Connection.async_api = false
    • It will raise error if Fiber Scheduler set, because the scheduler leading blocking IO will stucking,
  • Update rake spec, test both with and without fiber on Ruby 3.0 (ruby-head)

Todo:

  • OS thread support test cases disabled for now, they will hanging, I don't know how to fix

Help needed:

  • I don't know my work is right and covered all cases, although test cases pass

@ioquatix
Copy link
Contributor

ioquatix commented Dec 25, 2020

If the scheduler is set you should use non-blocking event driven I/O. There shouldn't be a need to add PG::Connection.use_fiber= or any other "configuration".

@jasl
Copy link
Contributor

jasl commented Dec 25, 2020

If the scheduler is set you should use non-blocking event driven I/O. There shouldn't be a need to add PG::Connection.use_fiber= or any other "configuration".

You're right, I redo my work, only 2 test cases I don't know how to fix https://github.com/ged/ruby-pg/blob/master/spec/pg/connection_spec.rb#L1670-L1695

@jasl
Copy link
Contributor

jasl commented Dec 30, 2020

One pain point I've met is somewhere hanging when fiber scheduler enabled, but I don't know where.
Any sugguest about debugging this situation?

@ioquatix
Copy link
Contributor

Fiber#backtrace may help. If you use async you can print out all the backtraces using Reactor#print_hierarchy.

larskanis added a commit to larskanis/ruby-pg that referenced this issue Aug 23, 2021
larskanis added a commit to larskanis/ruby-pg that referenced this issue Aug 23, 2021
larskanis added a commit to larskanis/ruby-pg that referenced this issue Aug 24, 2021
larskanis added a commit to larskanis/ruby-pg that referenced this issue Aug 24, 2021
larskanis added a commit to larskanis/ruby-pg that referenced this issue Aug 24, 2021
larskanis added a commit to larskanis/ruby-pg that referenced this issue Aug 24, 2021
larskanis added a commit to larskanis/ruby-pg that referenced this issue Aug 24, 2021
larskanis added a commit to larskanis/ruby-pg that referenced this issue Sep 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants