Comments (7)
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.
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.
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 .transfer
ing 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.
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::Task
s 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.
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.
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.
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)
- Unhandled Exception does not stop program running HOT 10
- [Enhanchment] Make alternate exception reporting (the colorful one) opt in. HOT 3
- [Question] How to stop a fiber? HOT 4
- Strange timeout bug. HOT 10
- Dynamic concurrency limiter / adaptive semaphore HOT 3
- Configure log level specificly for Async HOT 4
- Segmentation fault HOT 5
- ActiveRecord best practices support or documentation HOT 1
- [Question] What difference between `Async` and `Sync` HOT 1
- bundle error HOT 1
- Catch all Async errors and report to Sentry? (or other error reporting)
- Properly managing interrupts (works for async v 1.31, "breaks" for async v 2.5.6) HOT 3
- Tasks signaling Conditions leave suspended Fibers behind HOT 8
- Error reporting difference between Sync{} and Async{}.wait HOT 2
- Understanding the difference of Sync usage within Falcon HOT 3
- macOS: `Errno::EINVAL: Invalid argument - IO_Event_Selector_KQueue_io_wait:IO_Event_Selector_KQueue_Waiting_register` HOT 18
- Stopping remaining tasks upon completion of one task HOT 2
- Blocking subprocess (popen3) HOT 10
- Sleep Hook HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from async.