-
Notifications
You must be signed in to change notification settings - Fork 154
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
Subject equivalent? #176
Comments
This would be a nice addition as it's a tool vastly used in Rx as well (BehaviorSubjects, PublishSubjects, BehaviorRelays, PublishRelays etc...) I guess for the time being we could build one using continuations with something in this flavour. class BehaviorRelay<V: Sendable> {
init(_ initialValue: V) {
self.currentValue = initialValue
self.continuations = []
}
var currentValue: V
var continuations: [AsyncStream<V>.Continuation]
let lock = NSLock()
func accept(newValue: V) {
lock.lock()
defer { lock.unlock() }
currentValue = newValue
continuations.forEach { continuation in
continuation.yield(newValue)
}
}
func makeStream() -> AsyncStream<V> {
AsyncStream { continuation in
lock.lock()
defer { lock.unlock() }
continuation.yield(currentValue)
continuations.append(continuation)
}
}
} |
If the Relay itself would be a asyncsequence, would be great |
Any news on integrating a subject equivalent in the lib at this time ? @phausler maybe ^^ |
AsyncChannel serves this purpose to some extent (it is not a current value but a pass through subject style behavior with back pressure) |
The thing we are still missing is a |
I put up a draft PR #208 and am hoping to fill out all the placeholders with a more polished version of the approach I'm using here where I am wrapping an AsyncStream and hosting it in a Task to ensure sequencing (relative to caller) https://github.com/rustle/TaskHostedAsyncSequence/tree/main/Sources/TaskHostedAsyncSequence. Would love to collaborate with any of y'all on this. |
Pushed up a working (so far) AsyncSubject. I'll work on AsyncThrowingSubject next. Then I'll flesh out tests for both. |
Hi @rustle I allow my self to post a comment here since I’ve made the same kind of implementation in a pitch on the forum -> https://forums.swift.org/t/pitch-async-buffered-channel/59854 The outcome seemed to be that it was too close to AsyncStream and that having a factory function like https://github.com/sideeffect-io/AsyncExtensions/blob/main/Sources/Creators/AsyncStream%2BPipe.swift should be enough (and could be pitched to the standard library). |
Cool. I've seen a few versions floating around and will definitely check out yours. |
I would warmly recommend considering adopting the semantics of ReactiveSwift's Basically, a This means that you can do things like:
While also allowing you to stream the values of all of a, b and c as they update. This allows you to mix and match reactive and imperative programming as you prefer, which is massively convenient in lots of situations. |
I've been experimenting with this AsyncSubject from ConcurrencyPlus, which essentially is a convenience wrapper for this annoyance:
When using it I've noticed a difference in behaviour in combineLatest compared to Combine's and currently debugging where the problem lies. The problem is if combining 2 streams and multiple values are sent to the first stream, when the second stream receives its first value the for await loops for all the previous first stream values instead of just once for the latest pair. Edit: its because the linked AsyncSubject uses AsyncStream that buffers, even setting |
Here is my attempt at an AsyncCurrentValueSubject loosely based on code found in this repository:
|
I'm curious. Is async-algorithms is a replacement of Combine as reactive programming? Is that why Subject equivalent is needed while Combine already provides them? Or is it unnecessary as concurrency programming library because Subject is concept of reactive programming? |
After using it for a while I've learned it's more like the opposite of Combine. Rather than receive publishers from different places and combine them, instead you just write the code procedurally like normal. |
|
No; this is not true - Combine uses a demand based model; everything is pull based. |
I was talking about the mechanics how elements are delivered. You are right that demand is pull based in the end. |
Apple decided to break all of the nice combine features with their @observable macro. So now if you want to design a viewModel and pipe values, you need to use the old process of inheriting classes with @observableobject. The problem is that, using the @observable macro, you cannot do data bindings. Which makes life a complex hell when working with state to view bindings from external sources. **WORKS **
DOES NOT WORK
Are there plans to get this Subject equivalent to work? |
Any progress on this feature? Because
output
|
We need a way to imperatively pipe events into a AsyncSequence same asi Subjects from Combine did, or Kotlin's MutableState/SharedFlow
AsynchChannel feels like a low level primitive to be used for state tracking the way CurrentValueSubject was
The text was updated successfully, but these errors were encountered: