Comments (5)
The reason this is not included is that I actually imagined a composition through Arc<Semaphore>
being sufficient. Channels have dedicated shared types to be able to split senders and receivers and to be able to hide them easier behind traits. But for Mutex/Semaphore/Event I didn’t see a need for it.
What would be the use-case where the external Arc isn’t sufficient?
from futures-intrusive.
Say you had:
struct Foo {
sema: Arc<Semaphore>,
}
impl Foo {
async fn bar(&self) -> Bar {
Bar {
permits: self.sema.acquire(1).await,
}
}
}
struct Bar {
permits: SemaphoreReleaser<???>,
}
What would be the lifetime of the SemaphoreReleaser
? If its static
, then bar
borrows Foo
for static. If its not static
then Bar
cannot be used on a separate thread.
You could put a copy of the semaphore in Bar
and make Bar
a self referencing struct, but that seems overly complicated.
from futures-intrusive.
It would have a lifetime of 'self
. Or actually it would be a little bit more messy, due to how lifetime interference in async fn
s works. I agree that if you want to store the releaser somewhere else, it isn't ideal. However it's not the typical use-case of the semaphore. That one is more like:
// Acquire one or more permits, e.g. to limit resources
let _releaser = self.sema.acquire(1).await;
do_another_async_action_which_needs_to_be_guarded().await;
drop(_releaser); // or implicit drop
The store permits and release elsewhere use-case is more rare. But nevertheless it exists - that's why the explicit release
and disarm
methods exist. Would they be applicable for your use-case in combination with Arc<Semaphore>
? You use them together with a custom releaser type to keep the RAII semantics.
struct ArcReleaser {
sem: Arc<Semaphore>,
permits: usize,
}
impl ArcReleaser {
fn from_releaser(releaser: SemaphoreReleaser, sem: Arc<Semaphore>) -> ArcReleaser {
let permits = releaser.disarm(); // Take over commits
ArcReleaser {
sem,
permits,
}
}
impl Drop for ArcReleaser {
fn drop(&mut self) {
self.sem.release(self.permits);
}
}
async fn your_async_fn() {
let releaser = arc_sem.acquire(1).await;
let arc_releaser = ArcReleaser::from_releaser(releaser, arc_sem.clone());
// Can now move around arc_releaser without lifetime
}
I am aware that's more boilerplate than a builtin shared
type. However as you discovered the code-duplication for adding those types isn't ideal, and I would prefer to keep the library surface as small and maintainable as possible.
from futures-intrusive.
It would have a lifetime of 'self. Or actually it would be a little bit more messy, due to how lifetime interference in async fns works.
Yep, but as far as I know you can't enforce a 'self lifetime.
Would they be applicable for your use-case in combination with Arc?
Sure that would work. I agree that the code-duplication is quite horrendous.
My use case is to implement a bounded channel where each element has arbitrary weight (in bytes). Its pretty usefull when doing I/O. I don't know if that's considered a rare use-case.
I guess I'll write a small wrapper based on you suggestion.
from futures-intrusive.
My use case is to implement a bounded channel where each element has arbitrary weight (in bytes). Its pretty usefull when doing I/O. I don't know if that's considered a rare use-case.
That's actually a great use for an async semaphore! I required something similar recently, where I wanted to give various streams a flow-control budget. I however had use-cases where I could not use Arc
s for that purpose (due to pure no-std
) and therefore stored the permits as plain number.
I guess I'll write a small wrapper based on you suggestion.
Sounds good. I will close your PR then.
Maybe it makes sense to include the code from above as
SemaphoreReleaser::to_owned(self, sem: Arc<Semaphore>) -> ArcSemaphoreReleaser
which is like a compromise on between duplicating it in every application and adding a full shared semaphore with all the duplication to the library. But I think I want to wait for a bit more of experiences/application usages on this. Adding the few lines to projects which need it isn't too bad to make it work.
from futures-intrusive.
Related Issues (20)
- Channels with growing capacity HOT 2
- GenericWaitForEventFuture doesn't handle task migration. HOT 3
- GenericSemaphoreAcquireFuture isn't Sync HOT 7
- `Semaphore` cost O(waiters) time to wake up on, and quadratic in total HOT 2
- Channel::close should return previous state
- Unwind safety HOT 4
- shared::OneshotReceiver and cancellation HOT 2
- GenericOneshotBroadcastReceiver incorrectly requires MutexType to be Clone HOT 4
- LocalChannel backed by non-ArrayBuf RingBuf HOT 2
- NoopLock is unsound HOT 7
- Update `parking_lot` and `lock_api` HOT 1
- Pulling out intrusive data structures into another crate HOT 2
- GenericMutexGuard should be marked !Sync HOT 3
- Cut New Release With Updated Dependencies HOT 1
- Does this crate alias mutable references? HOT 1
- Add a mechanism to wake-up an external eventloop when a timer is inserted
- Maintenance Status HOT 1
- Possible breaking change in 0.4.1 release HOT 2
- Use alloc instead of std HOT 2
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 futures-intrusive.