Skip to content

Commit

Permalink
[ECO-5013][CHA-RL4] Updated RoomLifecycleManager
Browse files Browse the repository at this point in the history
1. Updated init method to include setting up ContributorListeners
2. Initialized property contributorStateChangeMonitor using ScopedEmitter
to track feature channel state changes
  • Loading branch information
sacOO7 committed Jan 7, 2025
1 parent a7323c1 commit 4275f88
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
49 changes: 48 additions & 1 deletion chat-android/src/main/java/com/ably/chat/RoomLifecycleManager.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.ably.chat

import io.ably.lib.realtime.ChannelEvent
import io.ably.lib.realtime.ChannelState
import io.ably.lib.realtime.ChannelStateListener
import io.ably.lib.types.AblyException
import io.ably.lib.types.ErrorInfo
import kotlin.coroutines.resume
Expand Down Expand Up @@ -63,6 +65,11 @@ internal abstract class ContributesToRoomLifecycleImpl(logger: Logger) : Contrib
}
}

internal data class ContributorStateChange(
val contributor: ContributesToRoomLifecycle,
val stateChange: ChannelStateListener.ChannelStateChange,
)

/**
* The order of precedence for lifecycle operations, passed to PriorityQueueExecutor which allows
* us to ensure that internal operations take precedence over user-driven operations.
Expand Down Expand Up @@ -118,6 +125,7 @@ internal class RoomLifecycleManager(
private val statusLifecycle: DefaultRoomLifecycle,
private val contributors: List<ContributesToRoomLifecycle>,
roomLogger: Logger,
transientDetachTimeout: Long = 5000,
) {
private val logger = roomLogger.withContext(
"RoomLifecycleManager",
Expand All @@ -131,6 +139,13 @@ internal class RoomLifecycleManager(
*/
private val atomicCoroutineScope = AtomicCoroutineScope(roomScope)

/**
* contributorStateChangeEmitter is responsible for emitting and subscribing to ContributorStateChange events.
* Events are emitted by room contributors/features using the underlying channel.
* All emitted events are processed sequentially under the specified roomScope.
*/
private val contributorStateChangeMonitor = ScopedEmitter<ContributorStateChange>(roomScope)

/**
* This flag indicates whether some sort of controlled operation is in progress (e.g. attaching, detaching, releasing).
*
Expand Down Expand Up @@ -160,7 +175,39 @@ internal class RoomLifecycleManager(
private val retryDurationInMs: Long = 250

init {
// TODO - [CHA-RL4] set up room monitoring here
// CHA-RL4
setupContributorListeners(transientDetachTimeout)
}

/**
* Sets up listeners for each contributor to the room status.
* Spec : CHA-RL4
* @param transientDetachTimeout The number of milliseconds to consider a detach to be "transient"
*/
@Suppress("UnusedParameter")
private fun setupContributorListeners(transientDetachTimeout: Long) {
contributorStateChangeMonitor.on { change ->
if (change.stateChange.event == ChannelEvent.update) {
TODO("Do some stuff when update event received")
}
when (change.stateChange.event) {
ChannelEvent.initialized -> TODO()
ChannelEvent.attaching -> TODO()
ChannelEvent.attached -> TODO()
ChannelEvent.detaching -> TODO()
ChannelEvent.detached -> TODO()
ChannelEvent.failed -> TODO()
ChannelEvent.suspended -> TODO()
else -> {
}
}
}
// Set up channel state change listener for each contributor
for (contributor in contributors) {
contributor.channel.on {
contributorStateChangeMonitor.emit(ContributorStateChange(contributor, it))
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,17 @@ class RetryTest {
val contributors = createRoomFeatureMocks()
val messagesContributor = contributors.first { it.featureName == "messages" }

// Ignore room monitoring listeners
contributors.forEach {
justRun { it.channel.on(any<ChannelStateListener>()) }
}

every {
messagesContributor.channel.once(eq(ChannelState.attached), any<ChannelStateListener>())
} answers {
secondArg<ChannelStateListener>().onChannelStateChanged(null)
}

justRun {
messagesContributor.channel.once(eq(ChannelState.failed), any<ChannelStateListener>())
}
Expand Down

0 comments on commit 4275f88

Please sign in to comment.