Comments (4)
@ioquatix I noticed you wrote code like this in your Ruby Gems Source Code Analysis and was thinking it'd be useful if this were documented.
My feedback is that I think we would have a need for this. It's useful to be able to set a limit on the number of simultaneous async operations, for various reasons including:
- prevent DOS on myself by creating an arbitrarily large number of fibers
- prevent DOS on servers that my code calls
I do find this API pretty hard to wrap my head around, though. I see how it works but I'd have to think about it every time I see the code.
from async.
I do find this API pretty hard to wrap my head around, though. I see how it works but I'd have to think about it every time I see the code.
This was my first impression as well. If this is expected to be a common pattern, would it be worth supporting it more directly? Maybe some new object that behaves like a queue but also has a Barrier
and Semaphore
internally:
instance = Async::QueueLikeObject.new(10)
instance.async do |item|
...
end
instance.wait
from async.
I'm definitely a fan of composition of simple objects, so I'd avoid things like QueueLikeObject
in the core async code, but have no issue of building those more complex abstractions in user code where it makes sense.
The reason why I ended up with this kind of composition is it naturally emerged from the need to control flow and limits...
The reason why I was unsure about it, is because injecting a barrier into a semaphore kind of seems odd to me. It's actually not necessary as long as you only want to go one level deep, e.g.
barrier = Async::Barrier.new
semaphore = Async::Semaphore.new(10)
queue.each do |item|
semaphore.async(parent: barrier) do
# Do something with item...
end
end
# Wait for all outstanding tasks.
barrier.wait
But as soon as you want to do more complex things, or even just inject a barrier into code that takes a parent task, it can get more complicated:
x.report("async-http (pipelined)") do
Async do |task|
internet = Async::HTTP::Internet.new
semaphore = Async::Semaphore.new(100, parent: task)
barrier = Async::Barrier.new(parent: semaphore)
# Warm up the connection pool...
response = internet.get(URL)
response.read
i = 0
while i < REPEATS
barrier.async do
response = internet.get(URL)
response.read
end
i += 1
end
barrier.wait
ensure
internet&.close
end
end
In the above benchmark, we bind the semaphore to the task
. Then we bind the barrier to the semaphore.
That way, we avoid dynamically looking up Task.current
for every iteration, and we also bind to a specific task from the POV of the task hierarchy. It's suggested that most top level entry points take a parent: Task.current
keyword argument, which allows users to control the task tree and resource usage, and now it's relatively trivial to provide a semaphore or barrier or any kind of nested task allocation strategy.
from async.
Okay, I am planning to merge this.
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)
- How to wait for `.schedule`'d fibers to finish? HOT 7
- 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.