event-manager: Add onSuccess and onFailure callbacks to EventListener

This commit is contained in:
Jorge Martin 2021-11-22 09:10:19 +00:00
parent 2e5a7179c0
commit 9582624601
5 changed files with 113 additions and 7 deletions

View File

@ -1,3 +1,13 @@
## EventManager Version [1.19.2]
Nov 19, 2021
### New Features
- Added two new callbacks to `EventListener`:
- `onSuccess` will be called when the modifications are executed with no issues.
- `onFailure` will be called after the modifications failed too many times and `resetAll` has run.
## EventManager Version [1.19.1]
Nov 18, 2021

View File

@ -24,7 +24,7 @@ plugins {
kotlin("android")
}
libVersion = Version(1, 19, 1)
libVersion = Version(1, 19, 2)
android()

View File

@ -100,7 +100,7 @@ class EventManagerImpl @AssistedInject constructor(
State.NotifyPrepare -> notifyPrepare(metadata)
State.NotifyEvents -> notifyPrepare(metadata)
State.NotifyResetAll -> notifyResetAll(metadata)
State.NotifyComplete -> notifyComplete(metadata)
State.NotifyComplete -> notifyComplete(metadata, true)
State.Completed -> Unit
}
}
@ -166,7 +166,7 @@ class EventManagerImpl @AssistedInject constructor(
CoreLogger.e(LogTag.NOTIFY_ERROR, it)
enqueue(requireNotNull(metadata.eventId), immediately = true)
}.onSuccess {
notifyComplete(metadata)
notifyComplete(metadata, success = false)
}
}
@ -211,11 +211,11 @@ class EventManagerImpl @AssistedInject constructor(
CoreLogger.e(LogTag.NOTIFY_ERROR, it)
enqueue(metadata.eventId, immediately = true)
}.onSuccess {
notifyComplete(metadata)
notifyComplete(metadata, success = true)
}
}
private suspend fun notifyComplete(metadata: EventMetadata) {
private suspend fun notifyComplete(metadata: EventMetadata, success: Boolean) {
runCatching(
config = config,
eventId = requireNotNull(metadata.eventId),
@ -225,6 +225,11 @@ class EventManagerImpl @AssistedInject constructor(
) {
// Fully sequential and ordered.
eventListenersByOrder.values.flatten().forEach { eventListener ->
if (success) {
eventListener.notifySuccess(config)
} else {
eventListener.notifyFailure(config)
}
eventListener.notifyComplete(config)
}
}.onFailure {
@ -284,7 +289,7 @@ class EventManagerImpl @AssistedInject constructor(
isStarted = true
}
private suspend fun internalStop() {
private fun internalStop() {
if (!isStarted) return
observeAccountJob?.cancel()

View File

@ -279,4 +279,62 @@ class EventManagerImplTest {
}
assertEquals(calendarId, calendarEventListener.config.asCalendar().calendarId)
}
@Test
fun notifyCompleteCallsOnSuccess() = runBlocking {
// GIVEN
coEvery { eventMetadataRepository.get(any()) } returns
listOf(
EventMetadata(
UserId("userId"),
EventId("eventId"),
EventManagerConfig.Calendar(UserId("userId"), "calendarId"),
state = State.NotifyComplete,
createdAt = 0L,
)
)
// WHEN
calendarManager.process()
// THEN
coVerify(exactly = 1) { calendarEventListener.onSuccess(any()) }
coVerify(exactly = 1) { calendarEventListener.onComplete(any()) }
coVerify(exactly = 0) { calendarEventListener.onFailure(any()) }
coVerify(exactly = 0) { calendarEventListener.onResetAll(any()) }
coVerify(exactly = 0) { calendarEventListener.onPrepare(any(), any()) }
coVerify(exactly = 0) { calendarEventListener.onCreate(any(), any()) }
coVerify(exactly = 0) { calendarEventListener.onUpdate(any(), any()) }
coVerify(exactly = 0) { calendarEventListener.onDelete(any(), any()) }
}
@Test
fun notifyResetAllCallsOnFailure() = runBlocking {
// GIVEN
coEvery { eventMetadataRepository.get(any()) } returns
listOf(
EventMetadata(
UserId("userId"),
EventId("eventId"),
EventManagerConfig.Calendar(UserId("userId"), "calendarId"),
state = State.NotifyResetAll,
createdAt = 0L,
)
)
// WHEN
calendarManager.process()
// THEN
coVerify(exactly = 1) { calendarEventListener.onResetAll(any()) }
coVerify(exactly = 1) { calendarEventListener.onFailure(any()) }
coVerify(exactly = 1) { calendarEventListener.onComplete(any()) }
coVerify(exactly = 0) { calendarEventListener.onPrepare(any(), any()) }
coVerify(exactly = 0) { calendarEventListener.onCreate(any(), any()) }
coVerify(exactly = 0) { calendarEventListener.onUpdate(any(), any()) }
coVerify(exactly = 0) { calendarEventListener.onDelete(any(), any()) }
coVerify(exactly = 0) { calendarEventListener.onSuccess(any()) }
}
}

View File

@ -131,6 +131,20 @@ abstract class EventListener<Key : Any, Type : Any> : TransactionHandler {
setActionMap(config, emptyList())
}
/**
* Notify successful completion of the [EventListener]'s loop. Called before [onComplete].
*
* Note: No transaction wraps this function.
*/
suspend fun notifySuccess(config: EventManagerConfig) = onSuccess(config)
/**
* Notify completion with failures of the [EventListener]'s loop. Called before [onComplete] and after [onResetAll].
*
* Note: No transaction wraps this function.
*/
suspend fun notifyFailure(config: EventManagerConfig) = onFailure(config)
/**
* Deserialize [response] into a typed list of [Event].
*/
@ -146,12 +160,31 @@ abstract class EventListener<Key : Any, Type : Any> : TransactionHandler {
open suspend fun onPrepare(config: EventManagerConfig, entities: List<Type>) = Unit
/**
* Called at the end of a set of modifications, whether it is successful or not.
* Called at the end of a set of modifications, whether it is successful or not. It can be used to clean up any
* resources that are no longer needed.
*
* @see onPrepare
*/
open suspend fun onComplete(config: EventManagerConfig) = Unit
/**
* Called at the end of a set of modifications when it is successful.
*
* Note: [onComplete] will be called right after.
*
* @see onComplete
*/
open suspend fun onSuccess(config: EventManagerConfig) = Unit
/**
* Called at the end of a set of modifications after it failed.
*
* Note: [onComplete] will be called right after.
*
* @see onComplete
*/
open suspend fun onFailure(config: EventManagerConfig) = Unit
/**
* Called to created entities in persistence.
*