Stylianos Gakis
02/03/2023, 6:42 PMinterface AuthenticationListener {
suspend fun loggedIn()
suspend fun loggedOut()
}
This will be in a common module without more dependencies, and whichever module is interested can provide implementations of this interface to do stuff that it may need to do on login or logout.
Then there should be some class which is called ??? Let’s just say AuthenticationEventDispatcher
for now
class AuthenticationEventDispatcher(
authenticationListeners: Set<AuthenticationListener>, // injected
applicationScope: ApplicationScope,
coroutineContext: CoroutineContext,
) {
private val authEvents = Channel<AuthenticationEvent>(Channel.UNLIMITED)
init {
applicationScope.launch(coroutineContext) {
authEvents.consumeAsFlow()
.collect { event ->
authenticationListeners.map { authenticationListener ->
async { when (event) { LOGGED_IN -> authenticationListener.loggedIn(); LOGGED_OUT -> authenticationListener.loggedOut() } }
}.awaitAll()
}
}
}
fun loggedIn() { authEvents.trySend(LOGGED_IN) }
fun loggedOut() { authEvents.trySend(LOGGED_OUT) }
private enum class AuthenticationEvent { LOGGED_IN, LOGGED_OUT }
}
Which should just take these events and inform all the AuthenticationListener instances to do whatever it is that they’re gonna do (One example is that I want to get a member ID when logging in from the backend and save it, but this only works after having logged in first)
So with all this context, how would you better name “AuthenticationEventDispatcher” or even the “AuthenticationListener” which I am also not happy about?Emil Kantis
02/03/2023, 9:29 PMenum class AuthenticationEvent { LOGGED_IN, LOGGED_OUT }
val authState = MutableStateFlow(LOGGED_OUT);
consumers collect directly on the state flow?
Names seem fine to me 🙂 Would perhaps consider naming the listener methods onX()
to signal that it's triggered by an event.
Did you try asking ChatGPT btw? Given all that context it might give some good suggestions 😄Stylianos Gakis
02/03/2023, 9:55 PMMutableSharedFlow<Event>(replay = 0, extraBufferCapacity = Int.MAX_VALUE)
That’d mean that this global MutableStateFlow would need to be on the “leaf” module though, while now my dispatcher can stay in the :app module and another super straightforward module can exist which simply contains this AuthenticationListener interface and all of my modules can simply depend on that module if the need to do anything with these events. I think I prefer it that way?You can name "AuthenticationEventDispatcher" as "AuthEventBroadcaster" to indicate its role in broadcasting authentication events. "AuthenticationListener" can be named "AuthEventObserver" to indicate its role in observing and responding to authentication events.
Broadcaster is a name I didn’t consider, I think I like that one. But I may keep the …Listener suffix, as it reminds me of other such listeners like from OkHttp.
Also I think I will also go with AuthEvent… at the start.
Damn this is the first time I try it and it helps 😂 Maybe I should try it more often.dewildte
04/26/2023, 8:13 PMStylianos Gakis
04/26/2023, 11:20 PMdewildte
04/27/2023, 5:52 PM