diff --git a/CHANGELOG.md b/CHANGELOG.md index dd6f9d4aac..e75747bdec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Cache notification callback JNI references at startup to ensure that symbols can be resolved in core callbacks. (Issue [#1577](https://github.com/realm/realm-kotlin/issues/1577)) * Using `Realm.asFlow()` could miss an update if a write was started right after opening the Realm. (Issue [#1582](https://github.com/realm/realm-kotlin/issues/1582)) * Snapshot publishing with Github Action. (Issue [#1654](https://github.com/realm/realm-kotlin/issues/1654) [JIRA](https://jira.mongodb.org/browse/RKOTLIN-1018)) +* [Sync] `NullPointerException` while waiting for the synchronization of a subscription set if the client was set in `AwaitingMark` state. (Issue [#1671](https://github.com/realm/realm-kotlin/issues/1671) [JIRA](https://jira.mongodb.org/browse/RKOTLIN-1027)) ### Compatibility * File format: Generates Realms with file format v23. diff --git a/packages/cinterop/src/androidInstrumentedTest/kotlin/io/realm/kotlin/test/sync/SyncEnumTests.kt b/packages/cinterop/src/androidInstrumentedTest/kotlin/io/realm/kotlin/test/sync/SyncEnumTests.kt index 4d12f28409..aba2ef41a4 100644 --- a/packages/cinterop/src/androidInstrumentedTest/kotlin/io/realm/kotlin/test/sync/SyncEnumTests.kt +++ b/packages/cinterop/src/androidInstrumentedTest/kotlin/io/realm/kotlin/test/sync/SyncEnumTests.kt @@ -22,6 +22,7 @@ import io.realm.kotlin.internal.interop.ErrorCode import io.realm.kotlin.internal.interop.realm_auth_provider_e import io.realm.kotlin.internal.interop.realm_errno_e import io.realm.kotlin.internal.interop.realm_error_category_e +import io.realm.kotlin.internal.interop.realm_flx_sync_subscription_set_state_e import io.realm.kotlin.internal.interop.realm_sync_client_metadata_mode_e import io.realm.kotlin.internal.interop.realm_sync_connection_state_e import io.realm.kotlin.internal.interop.realm_sync_errno_connection_e @@ -33,6 +34,7 @@ import io.realm.kotlin.internal.interop.realm_user_state_e import io.realm.kotlin.internal.interop.realm_web_socket_errno_e import io.realm.kotlin.internal.interop.sync.AuthProvider import io.realm.kotlin.internal.interop.sync.CoreConnectionState +import io.realm.kotlin.internal.interop.sync.CoreSubscriptionSetState import io.realm.kotlin.internal.interop.sync.CoreSyncSessionState import io.realm.kotlin.internal.interop.sync.CoreUserState import io.realm.kotlin.internal.interop.sync.MetadataMode @@ -137,6 +139,13 @@ class SyncEnumTests { } } + @Test + fun syncSubscriptionSetState() { + checkEnum(realm_flx_sync_subscription_set_state_e::class) { nativeValue -> + CoreSubscriptionSetState.of(nativeValue) + } + } + @Test fun websocketResultCode() { checkEnum(realm_sync_socket_callback_result_e::class) { nativeValue -> diff --git a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt index 2425def8f5..6544f6653e 100644 --- a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt +++ b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt @@ -26,5 +26,6 @@ expect enum class CoreSubscriptionSetState { RLM_SYNC_SUBSCRIPTION_BOOTSTRAPPING, RLM_SYNC_SUBSCRIPTION_COMPLETE, RLM_SYNC_SUBSCRIPTION_ERROR, - RLM_SYNC_SUBSCRIPTION_SUPERSEDED; + RLM_SYNC_SUBSCRIPTION_SUPERSEDED, + RLM_SYNC_SUBSCRIPTION_AWAITING_MARK; } diff --git a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt index e134e03cca..dbcfe0f8ca 100644 --- a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt +++ b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt @@ -25,11 +25,12 @@ actual enum class CoreSubscriptionSetState(override val nativeValue: Int) : Nati RLM_SYNC_SUBSCRIPTION_BOOTSTRAPPING(realm_flx_sync_subscription_set_state_e.RLM_SYNC_SUBSCRIPTION_BOOTSTRAPPING), RLM_SYNC_SUBSCRIPTION_COMPLETE(realm_flx_sync_subscription_set_state_e.RLM_SYNC_SUBSCRIPTION_COMPLETE), RLM_SYNC_SUBSCRIPTION_ERROR(realm_flx_sync_subscription_set_state_e.RLM_SYNC_SUBSCRIPTION_ERROR), - RLM_SYNC_SUBSCRIPTION_SUPERSEDED(realm_flx_sync_subscription_set_state_e.RLM_SYNC_SUBSCRIPTION_SUPERSEDED); + RLM_SYNC_SUBSCRIPTION_SUPERSEDED(realm_flx_sync_subscription_set_state_e.RLM_SYNC_SUBSCRIPTION_SUPERSEDED), + RLM_SYNC_SUBSCRIPTION_AWAITING_MARK(realm_flx_sync_subscription_set_state_e.RLM_SYNC_SUBSCRIPTION_AWAITING_MARK); companion object { fun of(state: Int): CoreSubscriptionSetState { - for (value in values()) { + for (value in entries) { if (value.nativeValue == state) { return value } diff --git a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt index 554d0f62ee..02bbaf2cfc 100644 --- a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt +++ b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/sync/CoreSubscriptionSetState.kt @@ -26,11 +26,12 @@ actual enum class CoreSubscriptionSetState( RLM_SYNC_SUBSCRIPTION_BOOTSTRAPPING(realm_wrapper.RLM_SYNC_SUBSCRIPTION_BOOTSTRAPPING), RLM_SYNC_SUBSCRIPTION_COMPLETE(realm_wrapper.RLM_SYNC_SUBSCRIPTION_COMPLETE), RLM_SYNC_SUBSCRIPTION_ERROR(realm_wrapper.RLM_SYNC_SUBSCRIPTION_ERROR), - RLM_SYNC_SUBSCRIPTION_SUPERSEDED(realm_wrapper.RLM_SYNC_SUBSCRIPTION_SUPERSEDED); + RLM_SYNC_SUBSCRIPTION_SUPERSEDED(realm_wrapper.RLM_SYNC_SUBSCRIPTION_SUPERSEDED), + RLM_SYNC_SUBSCRIPTION_AWAITING_MARK(realm_wrapper.RLM_SYNC_SUBSCRIPTION_AWAITING_MARK); companion object { fun of(state: realm_flx_sync_subscription_set_state_e): CoreSubscriptionSetState { - for (value in values()) { + for (value in entries) { if (value.nativeValue == state) { return value } diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/BaseSubscriptionSetImpl.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/BaseSubscriptionSetImpl.kt index 2ecf15e5d9..aa73fe4586 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/BaseSubscriptionSetImpl.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/BaseSubscriptionSetImpl.kt @@ -129,6 +129,8 @@ internal abstract class BaseSubscriptionSetImpl( SubscriptionSetState.ERROR CoreSubscriptionSetState.RLM_SYNC_SUBSCRIPTION_SUPERSEDED -> SubscriptionSetState.SUPERCEDED + CoreSubscriptionSetState.RLM_SYNC_SUBSCRIPTION_AWAITING_MARK -> + SubscriptionSetState.AWAITING_MARK else -> TODO("Unsupported state: $coreState") } } diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SubscriptionSetState.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SubscriptionSetState.kt index b30ee965ac..dc9b98c56c 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SubscriptionSetState.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SubscriptionSetState.kt @@ -55,5 +55,11 @@ public enum class SubscriptionSetState { * are ignored by the server. Get the latest subscription set by calling * [SubscriptionSet.refresh]. */ - SUPERCEDED; + SUPERCEDED, + + /** + * The last bootstrap message containing the initial state for this subscription set has been received. The + * client is awaiting a mark message to mark this subscription as fully caught up to history. + */ + AWAITING_MARK; }