Git Product home page Git Product logo

Comments (7)

ioquatix avatar ioquatix commented on June 7, 2024

Async::Task is a form of promise which makes coordination easy.

Fiber.schedule provides no such mechanism.

If you want a promise style mechanism, you need to use something, e.g. Thread::ConditionVariable or Thread::Queue. Alternatively, we could introduce something, like Fiber::Promise or Fiber::Result - it's straight forward to implement.

For trivial Fiber#resume usage, no coordination is needed, but for fan-out or map-reduce style workloads, coordination is needed. Different primitives suit different use cases.

from async.

rmosolgo avatar rmosolgo commented on June 7, 2024

Thanks for sharing your thoughts on this, @ioquatix. It sounds like I'm barking up the wrong tree. I really wanted to stay in Fibers so that I could be sure that, for CPU, only one thing was happening at a time (and I have this fear of spinning up new Threads?!). I'll investigate Async::Task!

I tried Thread::ConditionVariable and Thread::Queue a while back but had trouble getting it to work with the current Fiber-based implementation, where (IIRC) Fibers couldn't be started or stopped by different Threads. But because of my previously-mentioned fear of Threads, I backed away slowly.

Because I'm generally curious, I'd love to hear more about what you mean by Fiber::Promise or Fiber::Result if you have a few minutes to spell it out sometime!

In any case, I'll try re-working it with Async::Task and follow up if I run into any more trouble. Thanks again!

from async.

rmosolgo avatar rmosolgo commented on June 7, 2024

Hot take after reviewing the Async::Task docs: I think what I'm missing to make a seamless switch is a way to pause and resume Tasks, as I might with Fiber.yield or .transfering back to a parent fiber. It looks like Tasks can start, then terminate, but not be paused and resumed.

Pausing and resuming is a core feature of the current Dataloader implementation because it supports seamless code like

record = dataloader.with(RecordSource).load(1) # The fiber pauses here until we've loaded this value from the DB
record.name 

In that case, no block-based chaining is required, which I consider a feature because it avoids "what color is my function"-type code, where some methods return Promise-ish things while others return plain values. I guess that makes it like await ... in application code.

from async.

trevorturk avatar trevorturk commented on June 7, 2024

Apologies in advance if this is missing the point, but I wanted to note that you have Async::Task#wait which may be usable here. See docs here: https://socketry.github.io/async/guides/asynchronous-tasks/index#waiting-for-tasks and note also Async::Barrier may be interesting. I also worked up some GraphQL examples using Async::Tasks here: https://github.com/socketry/async-examples which allow me to completely avoid the Dataloader system FWIW, just using lazy_resolve, which might be interesting for reference.

I suppose I'm just wondering if the load method in your example called wait on the Async::Task associated with the record 1...?

from async.

rmosolgo avatar rmosolgo commented on June 7, 2024

Thanks for sharing that link, @trevorturk -- I hadn't seen those! That's great.

I definitely know you can do async data loading with GraphQL if you hand-code the concurrency. But what I really want is to live in the world I think Fiber.scheduler promises, where, if you have I/O in a Fiber, the scheduler will background it (if it can).

If I understand the possibility right, then you could say something like:

  • Write I/O in Dataloader::Sources; It'll be backgrounded if the scheduler supports it (and it seems like Async does support a lot!)
  • In your schema, make sequential (not chained, because yuck) calls to the dataloader, knowing that GraphQL-Ruby will be batching, caching, and backgrounding dataloads as it goes.

That would deliver good performance and good DX ... if it's possible! (Maybe it's not :S)

from async.

trevorturk avatar trevorturk commented on June 7, 2024

Hmm, I'm sorry but I'm not totally following the description of your ideal state here! I'd be happy to chat more if it might be helpful, but I think I'm misunderstanding something (probably more than one thing lol).

Other possible reading that might interest you, just in case it's helpful: https://brunosutic.com/blog/async-ruby and https://brunosutic.com/blog/ruby-fiber-scheduler

I think (but I'm not sure) that you might want to be looking higher up the Async stack, as opposed to looking at Fibers directly, but hopefully @ioquatix can provide some guidance if he understands what you're shooting for.

from async.

rmosolgo avatar rmosolgo commented on June 7, 2024

Hey @trevorturk, thanks again for sharing those examples. I reviewed them, and sometime while they were cookin' in there, I think I finally understood how it might look to use Async primitives inside GraphQL::Dataloader. I've got a nicely-working implementation here: rmosolgo/graphql-ruby#4727

I'm going to do a bit of follow-up before I merge but if either you have any thoughts, I'd appreciate a review on the PR!

from async.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.