Closed VerTiGoEtrex closed 3 years ago
Hmmm, I would suggest using the Bloc pattern instead, this will allow you to carefully manage the disposal of past events. (see https://pub.dev/packages/bloc)
When implementing a Bloc here, you can do something like this:
GoogleSignInStatus _lastStatus;
@override
Stream<GoogleSignInStatus> mapEventToState(GoogleSignInEvent event) async* {
// maybe dispose the last status
_lastStatus?.dispose();
// create a valid status given the event
var status = processFromEvent(event);
// assign this to be the new last event
_lastStatus = status;
// finally, add it
yield status;
}
@override
void dispose() {
super.dispose();
// maybe dispose the last status
_lastStatus?.dispose();
}
If you want to use the provided architecture then your first solution looks to be the best. There are no destructors in dart so you can't attach any behavior to the lifetime of an object. Call to dispose is arbitrary and you have to decide yourself when it is right to call it.
You can try implementing your own version of BehaviorSubject or a wrapper that would accept only objects that have dispose method and call it when they are replaced by something else. However it may result in issues when using replay etc. because disposed objects could be passed.
filter event and use switchMap
Hi there,
I'm trying to write a clean Google signin scoping bloc, as best I can describe it.
Google sign in has three states -
SignedIn
,SigningIn
, andSignedOut
. Notice that the SignedIn state owns aClient
that it needs to dispose.Simple enough thus far. The part I'm not sure about is how to put these states into a stream and also ensure that as new states are generated, the old ones are disposed. Here's my class, minus some trivial details to make it as simple as possible.
The problem I have is that my BehaviorSubject
_signInStatusSubject
contains state object of typeGoogleSignInStatus
as pasted above. TheSignedIn
state is disposable! What happens if I go from SignedIn to the SignedOut state. As of now, that SignedIn object will leak it's internalClient
object since the behavior subject will not calldispose()
on its previous value.I see a few potential solutions, but it seems they suck.
_signInStatusSubject.value
in theonCurrentUserChanged
subscription before the_signInStatusSubject.add
call.????
to get the previous value of_signInStatusSubject
to dispose it, and then give a null.listen
to that fold stream.Is there an established best practice here? How would rx experts handle streams that contain values with pseudo-destructors or pseudo java-like
finalize()
calls?I hope my example was clean enough to understand - if not, let me know and I will gladly see if I can simplify it further.
Thanks!