diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletLiveSubscriptions.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletLiveSubscriptions.kt index 8429a0b721..1e33c16323 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletLiveSubscriptions.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletLiveSubscriptions.kt @@ -80,7 +80,7 @@ class NappletLiveSubscriptions { val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ClinkDebitPayer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ClinkDebitPayer.kt index 664b55ed61..3ea9d1678d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ClinkDebitPayer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ClinkDebitPayer.kt @@ -113,7 +113,7 @@ object ClinkDebitPayer { val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ClinkOfferPayer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ClinkOfferPayer.kt index 28a0d64fb0..a5911dc6c7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ClinkOfferPayer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ClinkOfferPayer.kt @@ -85,7 +85,7 @@ object ClinkOfferPayer { val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/diagnostics/BootRelayDiagnostics.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/diagnostics/BootRelayDiagnostics.kt index 1966bac786..054f6f855e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/diagnostics/BootRelayDiagnostics.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/diagnostics/BootRelayDiagnostics.kt @@ -158,7 +158,7 @@ class BootRelayDiagnostics( } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/diagnostics/DmRelayDiagnosticsLogger.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/diagnostics/DmRelayDiagnosticsLogger.kt index 4aefae6ba6..07f13fbd0b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/diagnostics/DmRelayDiagnosticsLogger.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/diagnostics/DmRelayDiagnosticsLogger.kt @@ -112,7 +112,7 @@ class DmRelayDiagnosticsLogger( Log.d(TAG) { "[+${at()}ms] REQ -> ${relay.url.url} success=$success ${cmdStr.take(400)}" } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUniqueIdEoseManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUniqueIdEoseManager.kt index 0427380423..61c297887e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUniqueIdEoseManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUniqueIdEoseManager.kt @@ -78,7 +78,7 @@ abstract class PerUniqueIdEoseManager( newEose(key, relay, TimeUtils.now(), forFilters) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUserAndFollowListEoseManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUserAndFollowListEoseManager.kt index cc55f02d7a..7f53cbd0aa 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUserAndFollowListEoseManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUserAndFollowListEoseManager.kt @@ -90,7 +90,7 @@ abstract class PerUserAndFollowListEoseManager( newEose(key, relay, TimeUtils.now(), forFilters) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUserEoseManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUserEoseManager.kt index b904bf4ab9..c89d53a6e0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUserEoseManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/PerUserEoseManager.kt @@ -77,7 +77,7 @@ abstract class PerUserEoseManager( newEose(key, relay, TimeUtils.now(), forFilters) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/SingleSubNoEoseCacheEoseManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/SingleSubNoEoseCacheEoseManager.kt index d4df1e5deb..a80357e283 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/SingleSubNoEoseCacheEoseManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/eoseManagers/SingleSubNoEoseCacheEoseManager.kt @@ -53,7 +53,7 @@ abstract class SingleSubNoEoseCacheEoseManager( } } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/notifyCommand/model/NotifyCoordinator.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/notifyCommand/model/NotifyCoordinator.kt index 92b40d456e..c7e146b5bf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/notifyCommand/model/NotifyCoordinator.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/notifyCommand/model/NotifyCoordinator.kt @@ -78,7 +78,7 @@ class NotifyCoordinator( } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/follows/AccountFollowsLoaderSubAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/follows/AccountFollowsLoaderSubAssembler.kt index 08ec932e0e..dcda63f127 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/follows/AccountFollowsLoaderSubAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/follows/AccountFollowsLoaderSubAssembler.kt @@ -116,7 +116,7 @@ class AccountFollowsLoaderSubAssembler( newEose(TimeUtils.now(), relay, forFilters) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip01Notifications/AccountNotificationsHistoryEoseManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip01Notifications/AccountNotificationsHistoryEoseManager.kt index 485f8fb9f9..5f15938130 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip01Notifications/AccountNotificationsHistoryEoseManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip01Notifications/AccountNotificationsHistoryEoseManager.kt @@ -193,7 +193,7 @@ class AccountNotificationsHistoryEoseManager( // cursors so a late callback can't move another account's cursors. newEose runs regardless. val myCursors = key.account.notificationHistory return object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip47WalletConnect/NwcNotificationsEoseManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip47WalletConnect/NwcNotificationsEoseManager.kt index 384c89df06..97098d765e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip47WalletConnect/NwcNotificationsEoseManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip47WalletConnect/NwcNotificationsEoseManager.kt @@ -124,7 +124,7 @@ class NwcNotificationsEoseManager( newEose(key, relay, TimeUtils.now(), forFilters) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip59GiftWraps/AccountGiftWrapsHistoryEoseManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip59GiftWraps/AccountGiftWrapsHistoryEoseManager.kt index 02d351be88..911e6fb132 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip59GiftWraps/AccountGiftWrapsHistoryEoseManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/nip59GiftWraps/AccountGiftWrapsHistoryEoseManager.kt @@ -115,7 +115,7 @@ class AccountGiftWrapsHistoryEoseManager( // cursors so a late callback can't move another account's cursors. newEose runs regardless. val myCursors = key.account.chatroomList.giftWrapHistory return object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/watchers/UserWatcherSubAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/watchers/UserWatcherSubAssembler.kt index d695cd8e7e..f5381a9be1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/watchers/UserWatcherSubAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/watchers/UserWatcherSubAssembler.kt @@ -74,7 +74,7 @@ class UserWatcherSubAssembler( newEose(relay, TimeUtils.now(), forFilters) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/speedLogger/RelaySpeedLogger.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/speedLogger/RelaySpeedLogger.kt index 66718a9ea1..32942920eb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/speedLogger/RelaySpeedLogger.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/speedLogger/RelaySpeedLogger.kt @@ -42,7 +42,7 @@ class RelaySpeedLogger( private val clientListener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/resourceusage/RelayUsageListener.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/resourceusage/RelayUsageListener.kt index a8ba773138..5d97ef56cb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/resourceusage/RelayUsageListener.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/resourceusage/RelayUsageListener.kt @@ -48,7 +48,7 @@ class RelayUsageListener( } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/datasource/ChatroomNip04HistorySubAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/datasource/ChatroomNip04HistorySubAssembler.kt index 4cbe77bffb..c9e30794a4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/datasource/ChatroomNip04HistorySubAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/datasource/ChatroomNip04HistorySubAssembler.kt @@ -116,7 +116,7 @@ class ChatroomNip04HistorySubAssembler( // so a late callback can't move another room's cursors. newEose (framework bookkeeping) runs anyway. val myCursors = cursorsFor(key) return object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/datasource/ConcordChannelHistoryFilterAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/datasource/ConcordChannelHistoryFilterAssembler.kt index 2720cb1d77..a6cb65f165 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/datasource/ConcordChannelHistoryFilterAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/datasource/ConcordChannelHistoryFilterAssembler.kt @@ -170,7 +170,7 @@ class ConcordChannelHistorySubAssembler( // cursors so a late callback can't move another channel's cursors. newEose runs regardless. val myCursors = cursorsFor(key) return object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/datasource/RelayGroupOpenChatHistoryFilterAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/datasource/RelayGroupOpenChatHistoryFilterAssembler.kt index 7b6f7bbcac..f75b814bf7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/datasource/RelayGroupOpenChatHistoryFilterAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/datasource/RelayGroupOpenChatHistoryFilterAssembler.kt @@ -126,7 +126,7 @@ class RelayGroupOpenChatHistorySubAssembler( // cursors so a late callback can't move another group's cursors. newEose runs regardless. val myCursors = cursorsFor(key) return object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/datasource/RelayGroupOpenThreadsHistoryFilterAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/datasource/RelayGroupOpenThreadsHistoryFilterAssembler.kt index ddbef10a9a..cb2d8cc4b3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/datasource/RelayGroupOpenThreadsHistoryFilterAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/datasource/RelayGroupOpenThreadsHistoryFilterAssembler.kt @@ -123,7 +123,7 @@ class RelayGroupOpenThreadsHistorySubAssembler( // cursors so a late callback can't move another group's cursors. newEose runs regardless. val myCursors = cursorsFor(key) return object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/datasource/ChatroomListNip04HistorySubAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/datasource/ChatroomListNip04HistorySubAssembler.kt index bf7f2fee05..60a41ede35 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/datasource/ChatroomListNip04HistorySubAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/datasource/ChatroomListNip04HistorySubAssembler.kt @@ -108,7 +108,7 @@ class ChatroomListNip04HistorySubAssembler( // cursors so a late callback can't move another account's cursors. newEose runs regardless. val myCursors = key.account.chatroomList.nip04History return object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chess/datasource/ChessFeedFilterSubAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chess/datasource/ChessFeedFilterSubAssembler.kt index 01616b65a6..0780530666 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chess/datasource/ChessFeedFilterSubAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chess/datasource/ChessFeedFilterSubAssembler.kt @@ -70,7 +70,7 @@ class ChessFeedFilterSubAssembler( newEose(key, relay, TimeUtils.now(), forFilters) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/eventsync/EventSync.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/eventsync/EventSync.kt index 653003ecf4..0918f1a13b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/eventsync/EventSync.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/eventsync/EventSync.kt @@ -456,7 +456,7 @@ class EventSync( } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt index b36cb843e3..02b482bebf 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt @@ -668,7 +668,7 @@ class Context( val filters = relays.associateWith { listOf(responseFilter) } val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GeochatCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GeochatCommands.kt index 2547025b63..22c74904ce 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GeochatCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GeochatCommands.kt @@ -133,7 +133,7 @@ object GeochatCommands { val subId = newSubId() val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NipCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NipCommand.kt index 786eefed70..21c69fabf9 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NipCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NipCommand.kt @@ -167,7 +167,7 @@ object NipCommand { val remaining = SEARCH_RELAYS.toMutableSet() val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NostrConnect.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NostrConnect.kt index 33d51fe403..03629f9922 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NostrConnect.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NostrConnect.kt @@ -118,7 +118,7 @@ object NostrConnect { val subId = newSubId() val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/SubscribeCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/SubscribeCommand.kt index b8afce7b90..5779bacf6c 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/SubscribeCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/SubscribeCommand.kt @@ -81,7 +81,7 @@ object SubscribeCommand { val subId = newSubId() val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessRelayFetchHelper.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessRelayFetchHelper.kt index f45c499791..2a9c5a407c 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessRelayFetchHelper.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessRelayFetchHelper.kt @@ -100,7 +100,7 @@ class ChessRelayFetchHelper( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/assemblers/FeedMetadataCoordinator.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/assemblers/FeedMetadataCoordinator.kt index 659ca97dcd..2260b279a5 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/assemblers/FeedMetadataCoordinator.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/assemblers/FeedMetadataCoordinator.kt @@ -99,7 +99,7 @@ class FeedMetadataCoordinator( val listener = if (onEvent != null) { object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -295,7 +295,7 @@ class FeedMetadataCoordinator( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -371,7 +371,7 @@ class FeedMetadataCoordinator( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/eoseManagers/PerKeyEoseManager.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/eoseManagers/PerKeyEoseManager.kt index b609d52dc2..101216858c 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/eoseManagers/PerKeyEoseManager.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/eoseManagers/PerKeyEoseManager.kt @@ -90,7 +90,7 @@ abstract class PerKeyEoseManager( newEose(queryState, relay, TimeUtils.now(), forFilters) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/eoseManagers/SingleSubEoseManager.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/eoseManagers/SingleSubEoseManager.kt index fd2c6f4922..da0c3c66d9 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/eoseManagers/SingleSubEoseManager.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/eoseManagers/SingleSubEoseManager.kt @@ -86,7 +86,7 @@ abstract class SingleSubEoseManager( newEose(relay, TimeUtils.now(), forFilters) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relays/health/RelayHealthListener.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relays/health/RelayHealthListener.kt index b90d9e1502..6e564e356e 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relays/health/RelayHealthListener.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relays/health/RelayHealthListener.kt @@ -44,7 +44,7 @@ class RelayHealthListener( store.recordConnect(relay.url, TimeUtils.now()) } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/service/broadcast/BroadcastTracker.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/service/broadcast/BroadcastTracker.kt index e9f8166cc6..01f4c8a9fb 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/service/broadcast/BroadcastTracker.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/service/broadcast/BroadcastTracker.kt @@ -118,7 +118,7 @@ class BroadcastTracker { } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, @@ -294,7 +294,7 @@ class BroadcastTracker { } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/wot/OutboxDispatcher.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/wot/OutboxDispatcher.kt index 24b6401cb3..7374a54337 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/wot/OutboxDispatcher.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/wot/OutboxDispatcher.kt @@ -371,7 +371,7 @@ class OutboxDispatcher( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -415,7 +415,7 @@ class OutboxDispatcher( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessEventBroadcaster.kt b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessEventBroadcaster.kt index e8630a810a..47a66c3f6c 100644 --- a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessEventBroadcaster.kt +++ b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessEventBroadcaster.kt @@ -90,7 +90,7 @@ class ChessEventBroadcaster( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/relayClient/paging/WindowLoadTracker.kt b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/relayClient/paging/WindowLoadTracker.kt index 345fe58f18..80837de516 100644 --- a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/relayClient/paging/WindowLoadTracker.kt +++ b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/relayClient/paging/WindowLoadTracker.kt @@ -212,7 +212,7 @@ fun WindowLoadTracker.trackingListener(forward: (NormalizedRelayUrl, List filter.kinds?.forEach { kind -> script[kind to relay]?.forEach { event -> - listener?.onEvent(event, isLive = false, relay = relay, forFilters = null) + kotlinx.coroutines.runBlocking { listener?.onEvent(event, isLive = false, relay = relay, forFilters = null) } } } } diff --git a/commons/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/wot/OutboxDispatcherTest.kt b/commons/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/wot/OutboxDispatcherTest.kt index 9238b5ce1d..5fe6483199 100644 --- a/commons/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/wot/OutboxDispatcherTest.kt +++ b/commons/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/wot/OutboxDispatcherTest.kt @@ -171,7 +171,7 @@ class OutboxDispatcherTest { filterList.forEach { filter -> filter.kinds?.forEach { kind -> script[kind to relay]?.forEach { event -> - listener?.onEvent(event, isLive = false, relay = relay, forFilters = null) + kotlinx.coroutines.runBlocking { listener?.onEvent(event, isLive = false, relay = relay, forFilters = null) } } } } diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt index c9966e3442..3c5faabd88 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt @@ -1786,7 +1786,7 @@ fun MainContent( filters = listOf(filter), listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: com.vitorpamplona.quartz.nip01Core.core.Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -1845,7 +1845,7 @@ fun MainContent( relays = outbox, listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: com.vitorpamplona.quartz.nip01Core.core.Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManager.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManager.kt index 549847e8b0..6eb0354925 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManager.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManager.kt @@ -249,7 +249,7 @@ class AccountManager internal constructor( } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/FollowPacksState.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/FollowPacksState.kt index 80e88355c0..cb506f3282 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/FollowPacksState.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/FollowPacksState.kt @@ -164,7 +164,7 @@ class FollowPacksState( private fun subscribeToDiscovery() { val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: com.vitorpamplona.quartz.nip01Core.core.Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/MetadataPrefetch.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/MetadataPrefetch.kt index 240056ddf1..bdeb93104c 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/MetadataPrefetch.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/MetadataPrefetch.kt @@ -45,7 +45,7 @@ fun RelayConnectionManager.subscribeMetadataFor( val filter = Filter(kinds = listOf(MetadataEvent.KIND), authors = pubkeys) val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/ui/FromThePackFeed.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/ui/FromThePackFeed.kt index f9b1efc816..de661f4b36 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/ui/FromThePackFeed.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/ui/FromThePackFeed.kt @@ -92,7 +92,7 @@ fun FromThePackFeed( listOf(filter), listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/ui/RenderFollowPackCard.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/ui/RenderFollowPackCard.kt index ae82ca7876..3a1bc3f9b6 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/ui/RenderFollowPackCard.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/followpacks/ui/RenderFollowPackCard.kt @@ -102,7 +102,7 @@ fun RenderFollowPackCard( listOf(filter), listener = object : com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: com.vitorpamplona.quartz.nip01Core.core.Event, isLive: Boolean, relay: com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/network/RelayConnectionManager.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/network/RelayConnectionManager.kt index 9e07c9eb21..73057a1619 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/network/RelayConnectionManager.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/network/RelayConnectionManager.kt @@ -200,7 +200,7 @@ open class RelayConnectionManager( filters = filterMap, listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -264,7 +264,7 @@ open class RelayConnectionManager( } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/search/DesktopRelayUserSearchDelegate.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/search/DesktopRelayUserSearchDelegate.kt index a58d2bad74..5b74f8eccc 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/search/DesktopRelayUserSearchDelegate.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/search/DesktopRelayUserSearchDelegate.kt @@ -69,7 +69,7 @@ class DesktopRelayUserSearchDelegate( relays = relays, listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/ChessSubscription.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/ChessSubscription.kt index 0d0c645669..6b6602d57f 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/ChessSubscription.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/ChessSubscription.kt @@ -96,7 +96,7 @@ class DesktopChessSubscriptionController( relays = state.relays, listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/DesktopRelaySubscriptionsCoordinator.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/DesktopRelaySubscriptionsCoordinator.kt index ffa8f497ec..3a315d6507 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/DesktopRelaySubscriptionsCoordinator.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/DesktopRelaySubscriptionsCoordinator.kt @@ -303,7 +303,7 @@ class DesktopRelaySubscriptionsCoordinator( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -428,7 +428,7 @@ class DesktopRelaySubscriptionsCoordinator( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/SubscriptionUtils.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/SubscriptionUtils.kt index b9fa38e75b..7fe5bfb77e 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/SubscriptionUtils.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/subscriptions/SubscriptionUtils.kt @@ -81,7 +81,7 @@ fun rememberSubscription( relays = cfg.relays, listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ImportFollowListDialog.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ImportFollowListDialog.kt index 52d3983dfb..41b057c510 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ImportFollowListDialog.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ImportFollowListDialog.kt @@ -225,7 +225,7 @@ fun ImportFollowListDialog( relays = relays, listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -277,7 +277,7 @@ fun ImportFollowListDialog( ), listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/NoteActions.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/NoteActions.kt index 1aa9f3a1fe..66770814d0 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/NoteActions.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/NoteActions.kt @@ -858,7 +858,7 @@ private suspend fun fetchMetadataForUsers( relays = relays, listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -1666,7 +1666,7 @@ private suspend fun fetchUserLightningAddress( relays = relays, listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/ChatroomListState.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/ChatroomListState.kt index d636037723..2b18254d14 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/ChatroomListState.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/ChatroomListState.kt @@ -175,7 +175,7 @@ class ChatroomListState( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/benchmark/LaunchScenario.kt b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/benchmark/LaunchScenario.kt index 79fb062b0e..7edddfa185 100644 --- a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/benchmark/LaunchScenario.kt +++ b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/benchmark/LaunchScenario.kt @@ -139,7 +139,7 @@ object LaunchScenario { ), listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: com.vitorpamplona.quartz.nip01Core.core.Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/testrelay/LaunchFixtureRelayTest.kt b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/testrelay/LaunchFixtureRelayTest.kt index 618704a8ed..95d9c8a8d1 100644 --- a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/testrelay/LaunchFixtureRelayTest.kt +++ b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/testrelay/LaunchFixtureRelayTest.kt @@ -73,7 +73,7 @@ class LaunchFixtureRelayTest { ), listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/testrelay/SubscribeBeforeConnectTest.kt b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/testrelay/SubscribeBeforeConnectTest.kt index 2720941b42..b70fd89c9b 100644 --- a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/testrelay/SubscribeBeforeConnectTest.kt +++ b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/testrelay/SubscribeBeforeConnectTest.kt @@ -72,7 +72,7 @@ class SubscribeBeforeConnectTest { ), listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/geode/src/main/kotlin/com/vitorpamplona/geode/mirror/MirrorWorker.kt b/geode/src/main/kotlin/com/vitorpamplona/geode/mirror/MirrorWorker.kt index c98e050e37..0557f58afa 100644 --- a/geode/src/main/kotlin/com/vitorpamplona/geode/mirror/MirrorWorker.kt +++ b/geode/src/main/kotlin/com/vitorpamplona/geode/mirror/MirrorWorker.kt @@ -686,7 +686,7 @@ class MirrorWorker( val watermark = AtomicLong(initialSince) val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/geode/src/test/kotlin/com/vitorpamplona/geode/GracefulShutdownTest.kt b/geode/src/test/kotlin/com/vitorpamplona/geode/GracefulShutdownTest.kt index 7a55645b7f..3d568e2550 100644 --- a/geode/src/test/kotlin/com/vitorpamplona/geode/GracefulShutdownTest.kt +++ b/geode/src/test/kotlin/com/vitorpamplona/geode/GracefulShutdownTest.kt @@ -125,7 +125,7 @@ class GracefulShutdownTest { val gotEose = Channel(UNLIMITED) val listener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/geode/src/test/kotlin/com/vitorpamplona/geode/KtorRelayTest.kt b/geode/src/test/kotlin/com/vitorpamplona/geode/KtorRelayTest.kt index 1b8f84833a..b79f81bf51 100644 --- a/geode/src/test/kotlin/com/vitorpamplona/geode/KtorRelayTest.kt +++ b/geode/src/test/kotlin/com/vitorpamplona/geode/KtorRelayTest.kt @@ -389,7 +389,7 @@ class KtorRelayTest { "close-test", mapOf(server.url.normalizeRelayUrl() to listOf(Filter(kinds = listOf(1)))), object : com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: com.vitorpamplona.quartz.nip01Core.core.Event, isLive: Boolean, relay: com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl, diff --git a/geode/src/test/kotlin/com/vitorpamplona/geode/Nip01ComplianceTest.kt b/geode/src/test/kotlin/com/vitorpamplona/geode/Nip01ComplianceTest.kt index 4851956a13..7f69de4c89 100644 --- a/geode/src/test/kotlin/com/vitorpamplona/geode/Nip01ComplianceTest.kt +++ b/geode/src/test/kotlin/com/vitorpamplona/geode/Nip01ComplianceTest.kt @@ -276,7 +276,7 @@ class Nip01ComplianceTest : RelayClientTest() { "sub-A", mapOf(defaultRelayUrl to listOf(Filter(kinds = listOf(1)))), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -297,7 +297,7 @@ class Nip01ComplianceTest : RelayClientTest() { "sub-B", mapOf(defaultRelayUrl to listOf(Filter(kinds = listOf(4)))), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -385,7 +385,7 @@ class Nip01ComplianceTest : RelayClientTest() { "live-1", mapOf(defaultRelayUrl to listOf(Filter(kinds = listOf(1)))), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -424,7 +424,7 @@ class Nip01ComplianceTest : RelayClientTest() { "live-2", mapOf(defaultRelayUrl to listOf(Filter(kinds = listOf(1)))), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -465,7 +465,7 @@ class Nip01ComplianceTest : RelayClientTest() { "eph-1", mapOf(defaultRelayUrl to listOf(Filter(kinds = listOf(20_001)))), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -534,7 +534,7 @@ class Nip01ComplianceTest : RelayClientTest() { relayB to listOf(Filter(kinds = listOf(1))), ), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/geode/src/test/kotlin/com/vitorpamplona/geode/Nip09DeletionTest.kt b/geode/src/test/kotlin/com/vitorpamplona/geode/Nip09DeletionTest.kt index c4e801665a..914da8e385 100644 --- a/geode/src/test/kotlin/com/vitorpamplona/geode/Nip09DeletionTest.kt +++ b/geode/src/test/kotlin/com/vitorpamplona/geode/Nip09DeletionTest.kt @@ -80,7 +80,7 @@ class Nip09DeletionTest { subId, mapOf(relayUrl to listOf(filter)), object : com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/geode/src/test/kotlin/com/vitorpamplona/geode/Nip77NegentropyTest.kt b/geode/src/test/kotlin/com/vitorpamplona/geode/Nip77NegentropyTest.kt index edff7aeb69..1b156225ca 100644 --- a/geode/src/test/kotlin/com/vitorpamplona/geode/Nip77NegentropyTest.kt +++ b/geode/src/test/kotlin/com/vitorpamplona/geode/Nip77NegentropyTest.kt @@ -96,7 +96,7 @@ class Nip77NegentropyTest { compression: Boolean, ) {} - override fun onMessage(text: String) { + override suspend fun onMessage(text: String) { incoming.trySend(text) } diff --git a/geode/src/test/kotlin/com/vitorpamplona/geode/mirror/MirrorWorkerTrustOriginTest.kt b/geode/src/test/kotlin/com/vitorpamplona/geode/mirror/MirrorWorkerTrustOriginTest.kt index 28d7701ebc..634331fdf9 100644 --- a/geode/src/test/kotlin/com/vitorpamplona/geode/mirror/MirrorWorkerTrustOriginTest.kt +++ b/geode/src/test/kotlin/com/vitorpamplona/geode/mirror/MirrorWorkerTrustOriginTest.kt @@ -99,7 +99,7 @@ class MirrorWorkerTrustOriginTest { override fun connect() { connected = true out.onOpen(0, false) - out.onMessage(frame) + kotlinx.coroutines.runBlocking { out.onMessage(frame) } } override fun disconnect() { diff --git a/geode/src/test/kotlin/com/vitorpamplona/geode/perf/LoadBenchmark.kt b/geode/src/test/kotlin/com/vitorpamplona/geode/perf/LoadBenchmark.kt index 771a12784a..7c4acddd4b 100644 --- a/geode/src/test/kotlin/com/vitorpamplona/geode/perf/LoadBenchmark.kt +++ b/geode/src/test/kotlin/com/vitorpamplona/geode/perf/LoadBenchmark.kt @@ -258,7 +258,7 @@ class LoadBenchmark { "fanout-$i", mapOf(relayUrl to listOf(Filter(kinds = listOf(1)))), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: com.vitorpamplona.quartz.nip01Core.core.Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -436,7 +436,7 @@ class LoadBenchmark { "fanout-$i", mapOf(relayUrl to listOf(Filter(kinds = listOf(1)))), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: com.vitorpamplona.quartz.nip01Core.core.Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -568,7 +568,7 @@ class LoadBenchmark { ), ), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: com.vitorpamplona.quartz.nip01Core.core.Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/geode/src/testFixtures/kotlin/com/vitorpamplona/geode/testing/SubscriptionTesting.kt b/geode/src/testFixtures/kotlin/com/vitorpamplona/geode/testing/SubscriptionTesting.kt index d2c7ec2d04..fc50d6ef09 100644 --- a/geode/src/testFixtures/kotlin/com/vitorpamplona/geode/testing/SubscriptionTesting.kt +++ b/geode/src/testFixtures/kotlin/com/vitorpamplona/geode/testing/SubscriptionTesting.kt @@ -72,7 +72,7 @@ suspend fun NostrClient.collectUntilEoseMulti( subId, mapOf(relay to filters), object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/graperank/GrapeRankCrawler.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/graperank/GrapeRankCrawler.kt index 70ef709b72..4cba6e0c9f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/graperank/GrapeRankCrawler.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/graperank/GrapeRankCrawler.kt @@ -1489,7 +1489,7 @@ class GrapeRankCrawler( val lastEvt = AtomicLong(-1) val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NostrClient.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NostrClient.kt index 8378d8140a..08e39201ad 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NostrClient.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NostrClient.kt @@ -329,7 +329,7 @@ class NostrClient( listeners.forEach { it.onSent(relay, cmdStr, cmd, success) } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/AdaptiveRelayLimiter.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/AdaptiveRelayLimiter.kt index 0fcb87907b..be2547ea97 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/AdaptiveRelayLimiter.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/AdaptiveRelayLimiter.kt @@ -137,7 +137,7 @@ class AdaptiveRelayLimiter( if (wait > 0) delay(wait) } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/EventCollector.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/EventCollector.kt index 7c97ec3211..1964d465b5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/EventCollector.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/EventCollector.kt @@ -37,7 +37,7 @@ class EventCollector( ) { private val clientListener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientCountExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientCountExt.kt index 0f19d9d75c..66e502740c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientCountExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientCountExt.kt @@ -59,7 +59,7 @@ suspend fun INostrClient.count( val listener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, @@ -117,7 +117,7 @@ suspend fun INostrClient.count( val listener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchAllPagesExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchAllPagesExt.kt index f43aed278f..f7b4834515 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchAllPagesExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchAllPagesExt.kt @@ -94,7 +94,7 @@ suspend fun INostrClient.fetchAllPages( filters: List, idleTimeoutMs: Long = 30_000L, onNewPage: ((Long) -> Unit)? = null, - onEvent: (Event) -> Unit, + onEvent: suspend (Event) -> Unit, ): Int { var until: Long? = null var totalEvents = 0 @@ -172,7 +172,7 @@ suspend fun INostrClient.fetchAllPages( try { val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, @@ -320,7 +320,7 @@ suspend fun INostrClient.fetchAllPages( filters: List, idleTimeoutMs: Long = 30_000L, onNewPage: ((Long) -> Unit)? = null, - onEvent: (Event) -> Unit, + onEvent: suspend (Event) -> Unit, ): Int = fetchAllPages( relay = RelayUrlNormalizer.normalize(relay), diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchAllWithHooksExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchAllWithHooksExt.kt index f3726f5fe2..62d13ce5e9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchAllWithHooksExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchAllWithHooksExt.kt @@ -102,7 +102,7 @@ suspend fun INostrClient.fetchAllWithHooks( val doneReasons = HashMap() val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchFirstExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchFirstExt.kt index 2a80fcfa45..07a3f18e22 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchFirstExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientFetchFirstExt.kt @@ -96,7 +96,7 @@ suspend fun INostrClient.fetchFirst( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientNegentropyFanOutExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientNegentropyFanOutExt.kt index cce9d24bf1..7ac08647f5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientNegentropyFanOutExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientNegentropyFanOutExt.kt @@ -83,7 +83,7 @@ suspend fun negentropySyncFanOut( idleTimeoutMs: Long = 120_000L, reconcileConcurrency: Int = 2, onProgress: ((needSoFar: Int, downloaded: Int) -> Unit)? = null, - onEvent: (Event) -> Unit, + onEvent: suspend (Event) -> Unit, ): NegentropyFanOutResult { require(clients.isNotEmpty()) { "at least one client is required" } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientNegentropySyncExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientNegentropySyncExt.kt index 89360facbf..611720876a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientNegentropySyncExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientNegentropySyncExt.kt @@ -163,7 +163,7 @@ suspend fun INostrClient.negentropySync( idBufferBatches: Int = maxConcurrentReqs * 4, localEntries: List = emptyList(), onProgress: ((needSoFar: Int, downloaded: Int) -> Unit)? = null, - onEvent: (Event) -> Unit, + onEvent: suspend (Event) -> Unit, ): NegentropySyncResult { val need = AtomicInt(0) val windows = AtomicInt(0) @@ -242,7 +242,7 @@ suspend fun INostrClient.negentropySync( idBufferBatches: Int = maxConcurrentReqs * 4, localEntries: List = emptyList(), onProgress: ((needSoFar: Int, downloaded: Int) -> Unit)? = null, - onEvent: (Event) -> Unit, + onEvent: suspend (Event) -> Unit, ): NegentropySyncResult = negentropySync( relay = RelayUrlNormalizer.normalize(relay), @@ -309,14 +309,14 @@ suspend fun INostrClient.negentropySyncOrFetch( idBufferBatches: Int = maxConcurrentReqs * 4, localEntries: List = emptyList(), onProgress: ((needSoFar: Int, downloaded: Int) -> Unit)? = null, - onEvent: (Event) -> Unit, + onEvent: suspend (Event) -> Unit, ): NegentropyOrFetchResult { val seen = HashSet() var delivered = 0 // Shared dedup + cap across both phases. Returns true if the event was new and // delivered. Both phases run sequentially, so no concurrent access. - fun accept(event: Event): Boolean { + suspend fun accept(event: Event): Boolean { if ((maxEvents <= 0 || delivered < maxEvents) && seen.add(event.id)) { delivered++ onEvent(event) @@ -364,7 +364,7 @@ suspend fun INostrClient.negentropySyncOrFetch( idBufferBatches: Int = maxConcurrentReqs * 4, localEntries: List = emptyList(), onProgress: ((needSoFar: Int, downloaded: Int) -> Unit)? = null, - onEvent: (Event) -> Unit, + onEvent: suspend (Event) -> Unit, ): NegentropyOrFetchResult = negentropySyncOrFetch( relay = RelayUrlNormalizer.normalize(relay), @@ -876,7 +876,7 @@ private suspend fun INostrClient.reconcileStreaming( if (relay.url == targetUrl) clock.bump() } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, @@ -1103,7 +1103,7 @@ internal suspend fun INostrClient.fetchByIds( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientPublishExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientPublishExt.kt index c1aa8c14a2..fc725dbe84 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientPublishExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/NostrClientPublishExt.kt @@ -132,7 +132,7 @@ suspend fun INostrClient.publishAndCollectResults( } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayInsertConfirmationCollector.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayInsertConfirmationCollector.kt index 5014eada6f..6b536de30b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayInsertConfirmationCollector.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayInsertConfirmationCollector.kt @@ -37,7 +37,7 @@ class RelayInsertConfirmationCollector( ) { private val clientListener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayLogger.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayLogger.kt index 78b304edae..86313d9a48 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayLogger.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayLogger.kt @@ -50,7 +50,7 @@ class RelayLogger( private val clientListener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayNotifier.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayNotifier.kt index 65f2c6aae8..1853aec5e3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayNotifier.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/accessories/RelayNotifier.kt @@ -40,7 +40,7 @@ class RelayNotifier( private val clientListener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/auth/RelayAuthenticator.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/auth/RelayAuthenticator.kt index 1c5bc662de..b45e652421 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/auth/RelayAuthenticator.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/auth/RelayAuthenticator.kt @@ -102,7 +102,7 @@ class RelayAuthenticator( private val clientListener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/counts/RelayActiveCountStates.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/counts/RelayActiveCountStates.kt index dba6888dc7..d03077ba2e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/counts/RelayActiveCountStates.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/counts/RelayActiveCountStates.kt @@ -45,7 +45,7 @@ class RelayActiveCountStates( queryStates.put(relay.url, CountQueryState()) } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/limits/RelayLimitsTracker.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/limits/RelayLimitsTracker.kt index a8ffa37d63..65f61e8057 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/limits/RelayLimitsTracker.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/limits/RelayLimitsTracker.kt @@ -76,7 +76,7 @@ class RelayLimitsTracker( private val clientListener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/listeners/RedirectConnectionListener.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/listeners/RedirectConnectionListener.kt index 5d7fba5ffc..75e6ce6363 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/listeners/RedirectConnectionListener.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/listeners/RedirectConnectionListener.kt @@ -48,7 +48,7 @@ open class RedirectConnectionListener( listener.onSent(relay, cmdStr, cmd, success) } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/listeners/RelayConnectionListener.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/listeners/RelayConnectionListener.kt index feefbb532f..8f70a9cc11 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/listeners/RelayConnectionListener.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/listeners/RelayConnectionListener.kt @@ -53,7 +53,7 @@ interface RelayConnectionListener { /** * New error */ - fun onIncomingMessage( + suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolCounts.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolCounts.kt index 2d9a44ea31..97c48dc5fa 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolCounts.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolCounts.kt @@ -123,7 +123,7 @@ class PoolCounts { } } - fun onIncomingMessage( + suspend fun onIncomingMessage( relay: IRelayClient, msg: Message, ) { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolEventOutbox.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolEventOutbox.kt index c249d2aa3e..928cfd0bc2 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolEventOutbox.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolEventOutbox.kt @@ -178,7 +178,7 @@ class PoolEventOutbox { } } - fun onIncomingMessage( + suspend fun onIncomingMessage( relay: NormalizedRelayUrl, msg: Message, ) { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolRequests.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolRequests.kt index 7d4b08315b..7c87d14712 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolRequests.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolRequests.kt @@ -238,7 +238,7 @@ class PoolRequests( /** * When a new message is received by the relay, updates the sub */ - fun onIncomingMessage( + suspend fun onIncomingMessage( relay: IRelayClient, msg: Message, ) { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt index 22c2e0003b..62fe531d86 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt @@ -248,7 +248,7 @@ class RelayPool( listener.onDisconnected(relay) } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/DynamicSubscription.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/DynamicSubscription.kt index 1821f4ad86..f6eeb770dd 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/DynamicSubscription.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/DynamicSubscription.kt @@ -34,7 +34,7 @@ class DynamicSubscription( SubscriptionHandle { val subId = RandomInstance.randomChars(10) - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/NostrClientFetchAsFlowExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/NostrClientFetchAsFlowExt.kt index 1cda8b7e7c..6dd2ccaae5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/NostrClientFetchAsFlowExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/NostrClientFetchAsFlowExt.kt @@ -63,7 +63,7 @@ fun INostrClient.fetchAsFlow( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/NostrClientSubscribeAsFlowExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/NostrClientSubscribeAsFlowExt.kt index 50b6af68ab..4d7736ac71 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/NostrClientSubscribeAsFlowExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/NostrClientSubscribeAsFlowExt.kt @@ -69,7 +69,7 @@ fun INostrClient.subscribeAsFlow( val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/RelayActiveRequestStates.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/RelayActiveRequestStates.kt index a51d2f1df2..f75dfbe365 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/RelayActiveRequestStates.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/RelayActiveRequestStates.kt @@ -46,7 +46,7 @@ class RelayActiveRequestStates( subStates[relay.url] = RequestSubscriptionState() } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/StaticSubscription.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/StaticSubscription.kt index 1e87560adb..d33e9ff080 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/StaticSubscription.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/StaticSubscription.kt @@ -35,7 +35,7 @@ class StaticSubscription( SubscriptionHandle { val subId = RandomInstance.randomChars(10) - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/SubscriptionListener.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/SubscriptionListener.kt index 45f614237d..15486f55af 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/SubscriptionListener.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/SubscriptionListener.kt @@ -30,7 +30,7 @@ interface SubscriptionListener { forFilters: List?, ) {} - fun onEvent( + suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/stats/RelayReqStats.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/stats/RelayReqStats.kt index 2da8b3ca6d..0dcc1291df 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/stats/RelayReqStats.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/reqs/stats/RelayReqStats.kt @@ -37,7 +37,7 @@ class RelayReqStats( private val clientListener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt index 5005e63c9c..d0f1b7bc16 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt @@ -156,7 +156,7 @@ open class BasicRelayClient( listener.onConnected(this@BasicRelayClient, pingMillis, compression) } - override fun onMessage(text: String) { + override suspend fun onMessage(text: String) { try { val msg = decoder.decode(text) listener.onIncomingMessage(this@BasicRelayClient, text, msg) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/standalone/StandaloneRelayClient.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/standalone/StandaloneRelayClient.kt index 5063f03319..52f7947b2a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/standalone/StandaloneRelayClient.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/standalone/StandaloneRelayClient.kt @@ -66,7 +66,7 @@ class StandaloneRelayClient( syncFilters() } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/stats/RelayStats.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/stats/RelayStats.kt index b6548e1a2c..73b41bd000 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/stats/RelayStats.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/stats/RelayStats.kt @@ -83,7 +83,7 @@ class RelayStats( get(relay.url).addBytesSent(cmdStr.bytesUsedInMemory()) } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/sockets/WebSocketListener.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/sockets/WebSocketListener.kt index fef0f36a6b..4f4cdc522b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/sockets/WebSocketListener.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/sockets/WebSocketListener.kt @@ -30,7 +30,7 @@ interface WebSocketListener { compression: Boolean, ) - fun onMessage(text: String) + suspend fun onMessage(text: String) fun onClosed( code: Int, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/server/NostrConnectSignerService.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/server/NostrConnectSignerService.kt index 4be37a0b84..bc473bcaf1 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/server/NostrConnectSignerService.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/server/NostrConnectSignerService.kt @@ -183,7 +183,7 @@ class NostrConnectSignerService( val subId = newSubId() val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayObserver.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayObserver.kt index 1e293e3d05..d9d40ec0f5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayObserver.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayObserver.kt @@ -183,7 +183,7 @@ class RelayObserver : RelayConnectionListener { } } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayProber.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayProber.kt index 48d33d9185..711c38551a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayProber.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayProber.kt @@ -254,7 +254,7 @@ class RelayProber( val subId = newSubId() val subListener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip77Negentropy/NegentropyManager.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip77Negentropy/NegentropyManager.kt index 3984c1436d..83ad948534 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip77Negentropy/NegentropyManager.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip77Negentropy/NegentropyManager.kt @@ -94,7 +94,7 @@ class NegentropyManager( relay.sendIfConnected(session.close()) } - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBEBle/relay/BleMeshManager.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBEBle/relay/BleMeshManager.kt index 9e33fb9b91..504d0ff9aa 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBEBle/relay/BleMeshManager.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBEBle/relay/BleMeshManager.kt @@ -260,7 +260,7 @@ class BleMeshManager( private inner class ClientConnectionListener( val peerUuid: String, ) : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBEBle/relay/BleNostrClient.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBEBle/relay/BleNostrClient.kt index 1a0771d2e7..2f71344a25 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBEBle/relay/BleNostrClient.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBEBle/relay/BleNostrClient.kt @@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nipBEBle.relay import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayConnectionListener import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient +import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message import com.vitorpamplona.quartz.nip01Core.relay.commands.toRelay.Command import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nipBEBle.BleConfig @@ -31,8 +32,14 @@ import com.vitorpamplona.quartz.nipBEBle.protocol.BleChunkAssembler import com.vitorpamplona.quartz.nipBEBle.protocol.BleMessageChunker import com.vitorpamplona.quartz.nipBEBle.transport.BleTransport import com.vitorpamplona.quartz.utils.Log +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.launch import kotlin.concurrent.atomics.AtomicBoolean import kotlin.concurrent.atomics.ExperimentalAtomicApi @@ -72,6 +79,31 @@ class BleNostrClient( private val sendQueue = Channel>(Channel.UNLIMITED) private val isSending = AtomicBoolean(false) + /** Parsed messages waiting to reach the suspending listener — see [onChunkReceived]. */ + private val incoming = Channel>(Channel.UNLIMITED) + + private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob()) + + private val pump = + scope.launch { + for ((raw, msg) in incoming) { + try { + listener.onIncomingMessage(this@BleNostrClient, raw, msg) + } catch (e: CancellationException) { + throw e + } catch (e: Exception) { + // One peer's bad message must not end the pump for the rest. + Log.e("BleNostrClient", "Failure handling message from ${peer.deviceUuid}: $raw", e) + } + } + } + + /** Stops the [pump]; the client is unusable afterwards, like a closed socket. */ + fun release() { + incoming.close() + scope.cancel() + } + override fun isConnected(): Boolean = connected override fun needsToReconnect(): Boolean = !connected @@ -144,7 +176,13 @@ class BleNostrClient( try { val msg = OptimizedJsonMapper.fromJsonToMessage(message) - listener.onIncomingMessage(this, message, msg) + // The platform hands BLE notifications to a callback that cannot + // suspend, and the listener chain now does — so the message is + // handed off rather than delivered here. Same shape the websocket + // transport already uses: UNLIMITED so this callback never blocks + // the BLE stack, drained by ONE coroutine so message order survives + // the boundary. + incoming.trySend(message to msg) } catch (e: Exception) { Log.e("BleNostrClient", "Failed to parse message from ${peer.deviceUuid}: $message", e) } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/limits/RelayLimitsTrackerTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/limits/RelayLimitsTrackerTest.kt index 6547aeb9bb..39dae9ad12 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/limits/RelayLimitsTrackerTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/limits/RelayLimitsTrackerTest.kt @@ -70,67 +70,72 @@ class RelayLimitsTrackerTest { } @Test - fun cachesLimitsPerRelay() { - val (limits, listener) = setup() - val relay = FakeRelayClient(NormalizedRelayUrl("wss://relay.example/")) + fun cachesLimitsPerRelay() = + kotlinx.coroutines.test.runTest { + val (limits, listener) = setup() + val relay = FakeRelayClient(NormalizedRelayUrl("wss://relay.example/")) - assertNull(limits.get(relay.url), "No limits before any LIMITS message") + assertNull(limits.get(relay.url), "No limits before any LIMITS message") - listener.onIncomingMessage(relay, "", LimitsMessage(canWrite = true, maxLimit = 200)) + listener.onIncomingMessage(relay, "", LimitsMessage(canWrite = true, maxLimit = 200)) - assertEquals(true, limits.get(relay.url)?.canWrite) - assertEquals(200, limits.get(relay.url)?.maxLimit) - assertEquals(limits.get(relay.url), limits.limitsFlow.value[relay.url]) - } + assertEquals(true, limits.get(relay.url)?.canWrite) + assertEquals(200, limits.get(relay.url)?.maxLimit) + assertEquals(limits.get(relay.url), limits.limitsFlow.value[relay.url]) + } @Test - fun laterLimitsReplaceEarlierOnes() { - val (limits, listener) = setup() - val relay = FakeRelayClient(NormalizedRelayUrl("wss://relay.example/")) + fun laterLimitsReplaceEarlierOnes() = + kotlinx.coroutines.test.runTest { + val (limits, listener) = setup() + val relay = FakeRelayClient(NormalizedRelayUrl("wss://relay.example/")) - listener.onIncomingMessage(relay, "", LimitsMessage(canWrite = false, maxLimit = 200)) - listener.onIncomingMessage(relay, "", LimitsMessage(canWrite = true, maxLimit = 500)) + listener.onIncomingMessage(relay, "", LimitsMessage(canWrite = false, maxLimit = 200)) + listener.onIncomingMessage(relay, "", LimitsMessage(canWrite = true, maxLimit = 500)) - // A relay re-advertises LIMITS when rights change (e.g. after AUTH flips can_write). - assertEquals(true, limits.get(relay.url)?.canWrite) - assertEquals(500, limits.get(relay.url)?.maxLimit) - } + // A relay re-advertises LIMITS when rights change (e.g. after AUTH flips can_write). + assertEquals(true, limits.get(relay.url)?.canWrite) + assertEquals(500, limits.get(relay.url)?.maxLimit) + } @Test - fun tracksLimitsForDistinctRelaysIndependently() { - val (limits, listener) = setup() - val relayA = FakeRelayClient(NormalizedRelayUrl("wss://a.example/")) - val relayB = FakeRelayClient(NormalizedRelayUrl("wss://b.example/")) + fun tracksLimitsForDistinctRelaysIndependently() = + kotlinx.coroutines.test.runTest { + val (limits, listener) = setup() + val relayA = FakeRelayClient(NormalizedRelayUrl("wss://a.example/")) + val relayB = FakeRelayClient(NormalizedRelayUrl("wss://b.example/")) - listener.onIncomingMessage(relayA, "", LimitsMessage(maxLimit = 100)) - listener.onIncomingMessage(relayB, "", LimitsMessage(maxLimit = 999)) + listener.onIncomingMessage(relayA, "", LimitsMessage(maxLimit = 100)) + listener.onIncomingMessage(relayB, "", LimitsMessage(maxLimit = 999)) - assertEquals(100, limits.get(relayA.url)?.maxLimit) - assertEquals(999, limits.get(relayB.url)?.maxLimit) - assertEquals(2, limits.snapshot().size) - } + assertEquals(100, limits.get(relayA.url)?.maxLimit) + assertEquals(999, limits.get(relayB.url)?.maxLimit) + assertEquals(2, limits.snapshot().size) + } @Test - fun dropsCachedLimitsOnDisconnect() { - val (limits, listener) = setup() - val relay = FakeRelayClient(NormalizedRelayUrl("wss://relay.example/")) + fun dropsCachedLimitsOnDisconnect() = + kotlinx.coroutines.test.runTest { + val (limits, listener) = setup() + val relay = FakeRelayClient(NormalizedRelayUrl("wss://relay.example/")) - listener.onIncomingMessage(relay, "", LimitsMessage(canRead = true)) - assertTrue(limits.get(relay.url) != null) + listener.onIncomingMessage(relay, "", LimitsMessage(canRead = true)) + assertTrue(limits.get(relay.url) != null) - listener.onDisconnected(relay) - assertNull(limits.get(relay.url), "Limits are connection-scoped and cleared on disconnect") - assertTrue(limits.snapshot().isEmpty()) - } + listener.onDisconnected(relay) + assertNull(limits.get(relay.url), "Limits are connection-scoped and cleared on disconnect") + assertTrue(limits.snapshot().isEmpty()) + } @Test - fun ignoresNonLimitsMessages() { - val (limits, listener) = setup() - val relay = FakeRelayClient(NormalizedRelayUrl("wss://relay.example/")) + fun ignoresNonLimitsMessages() = + kotlinx.coroutines.test.runTest { + val (limits, listener) = setup() + val relay = FakeRelayClient(NormalizedRelayUrl("wss://relay.example/")) - listener.onIncomingMessage(relay, "", EoseMessage("sub1")) + listener.onIncomingMessage(relay, "", EoseMessage("sub1")) - assertNull(limits.get(relay.url)) - assertTrue(limits.snapshot().isEmpty()) - } + assertNull(limits.get(relay.url)) + assertTrue(limits.snapshot().isEmpty()) + } } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolEventOutboxAuthTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolEventOutboxAuthTest.kt index f8250eb9a1..8d0fa9b9df 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolEventOutboxAuthTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolEventOutboxAuthTest.kt @@ -62,13 +62,13 @@ class PoolEventOutboxAuthTest { relays.forEach { onSent(it, EventCmd(event)) } } - private fun PoolEventOutbox.nak( + private suspend fun PoolEventOutbox.nak( event: Event, relay: NormalizedRelayUrl, message: String, ) = onIncomingMessage(relay, OkMessage(event.id, false, message)) - private fun PoolEventOutbox.ok( + private suspend fun PoolEventOutbox.ok( event: Event, relay: NormalizedRelayUrl, ) = onIncomingMessage(relay, OkMessage(event.id, true, "")) @@ -104,67 +104,71 @@ class PoolEventOutboxAuthTest { } @Test - fun authRequiredResetsTheTriesBudgetAcrossManyResends() { - val outbox = PoolEventOutbox() - val ev = event("ff".repeat(32)) + fun authRequiredResetsTheTriesBudgetAcrossManyResends() = + kotlinx.coroutines.test.runTest { + val outbox = PoolEventOutbox() + val ev = event("ff".repeat(32)) - outbox.publish(ev, setOf(relay)) // first try + outbox.publish(ev, setOf(relay)) // first try - // A flapping relay / slow AUTH handshake re-pumps the still-pending event many more times - // than the 4-try cap, each NAK'd auth-required. newTry() (the send path) grows `tries` and - // is not auth-aware, so unless auth-required resets the retry budget these sends would trip - // Tries.isDone() and drop the event (with a spurious give-up) before AUTH ever lands. - repeat(8) { i -> - assertNull(outbox.onSent(relay, EventCmd(ev)), "must not give up on re-pump $i") - outbox.nak(ev, relay, "auth-required: authenticate first") + // A flapping relay / slow AUTH handshake re-pumps the still-pending event many more times + // than the 4-try cap, each NAK'd auth-required. newTry() (the send path) grows `tries` and + // is not auth-aware, so unless auth-required resets the retry budget these sends would trip + // Tries.isDone() and drop the event (with a spurious give-up) before AUTH ever lands. + repeat(8) { i -> + assertNull(outbox.onSent(relay, EventCmd(ev)), "must not give up on re-pump $i") + outbox.nak(ev, relay, "auth-required: authenticate first") + } + assertEquals(setOf(relay), outbox.pendingRelaysFor(ev.id)) + + // AUTH finally completes -> the event delivers. + outbox.ok(ev, relay) + assertNull(outbox.pendingRelaysFor(ev.id)) } - assertEquals(setOf(relay), outbox.pendingRelaysFor(ev.id)) - - // AUTH finally completes -> the event delivers. - outbox.ok(ev, relay) - assertNull(outbox.pendingRelaysFor(ev.id)) - } @Test - fun terminalRejectionStillDiscardsImmediately() { - val outbox = PoolEventOutbox() - val ev = event("cc".repeat(32)) + fun terminalRejectionStillDiscardsImmediately() = + kotlinx.coroutines.test.runTest { + val outbox = PoolEventOutbox() + val ev = event("cc".repeat(32)) - outbox.publish(ev, setOf(relay)) - outbox.nak(ev, relay, "invalid: bad signature") + outbox.publish(ev, setOf(relay)) + outbox.nak(ev, relay, "invalid: bad signature") - assertNull(outbox.pendingRelaysFor(ev.id)) - } + assertNull(outbox.pendingRelaysFor(ev.id)) + } @Test - fun givesUpAndSignalsAfterExhaustingTryBudget() { - val outbox = PoolEventOutbox() - val ev = event("ee".repeat(32)) + fun givesUpAndSignalsAfterExhaustingTryBudget() = + kotlinx.coroutines.test.runTest { + val outbox = PoolEventOutbox() + val ev = event("ee".repeat(32)) - // markAsSending + first onSent (1 try). Tries budget is >3 tries. - outbox.publish(ev, setOf(relay)) - // attempts 2, 3 stay under budget and signal nothing. - assertNull(outbox.onSent(relay, EventCmd(ev))) - assertNull(outbox.onSent(relay, EventCmd(ev))) - // the 4th attempt exhausts the budget -> event is returned (gave up) and dropped. - assertEquals(ev.id, outbox.onSent(relay, EventCmd(ev))?.id) - assertNull(outbox.pendingRelaysFor(ev.id)) - } + // markAsSending + first onSent (1 try). Tries budget is >3 tries. + outbox.publish(ev, setOf(relay)) + // attempts 2, 3 stay under budget and signal nothing. + assertNull(outbox.onSent(relay, EventCmd(ev))) + assertNull(outbox.onSent(relay, EventCmd(ev))) + // the 4th attempt exhausts the budget -> event is returned (gave up) and dropped. + assertEquals(ev.id, outbox.onSent(relay, EventCmd(ev))?.id) + assertNull(outbox.pendingRelaysFor(ev.id)) + } @Test - fun ordinaryTransientFailureStillBounded() { - val outbox = PoolEventOutbox() - val ev = event("dd".repeat(32)) + fun ordinaryTransientFailureStillBounded() = + kotlinx.coroutines.test.runTest { + val outbox = PoolEventOutbox() + val ev = event("dd".repeat(32)) - outbox.publish(ev, setOf(relay)) - // 3 non-auth error responses exhaust the retry budget. Responses only - // accumulate here; the drop happens on the next send attempt. - repeat(3) { outbox.nak(ev, relay, "error: rate-limited") } - assertEquals(setOf(relay), outbox.pendingRelaysFor(ev.id)) + outbox.publish(ev, setOf(relay)) + // 3 non-auth error responses exhaust the retry budget. Responses only + // accumulate here; the drop happens on the next send attempt. + repeat(3) { outbox.nak(ev, relay, "error: rate-limited") } + assertEquals(setOf(relay), outbox.pendingRelaysFor(ev.id)) - // The next resend attempt observes the exhausted budget and drops the event - // (unlike auth-required, which never poisons the budget). - outbox.onSent(relay, EventCmd(ev)) - assertNull(outbox.pendingRelaysFor(ev.id)) - } + // The next resend attempt observes the exhausted budget and drops the event + // (unlike auth-required, which never poisons the budget). + outbox.onSent(relay, EventCmd(ev)) + assertNull(outbox.pendingRelaysFor(ev.id)) + } } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolRequestsRefusalTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolRequestsRefusalTest.kt index 2e26da853a..91f5c03c4e 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolRequestsRefusalTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/PoolRequestsRefusalTest.kt @@ -75,123 +75,129 @@ class PoolRequestsRefusalTest { return sent } - private fun close( + private suspend fun close( pool: PoolRequests, subId: String, reason: String, ) = pool.onIncomingMessage(FakeRelayClient(relay), ClosedMessage(subId, reason)) @Test - fun stopsReplayingAThriceRefusedFilterAcrossReconnects() { - val pool = PoolRequests(maxRefusalsBeforeSuppress = 3) - pool.addOrUpdate("sub", mapOf(relay to plainFilter()), null) + fun stopsReplayingAThriceRefusedFilterAcrossReconnects() = + kotlinx.coroutines.test.runTest { + val pool = PoolRequests(maxRefusalsBeforeSuppress = 3) + pool.addOrUpdate("sub", mapOf(relay to plainFilter()), null) - // Under the threshold, each reconnect still replays the REQ (giving the relay a chance). - repeat(3) { attempt -> - val sent = reconnectAndSync(pool) - assertEquals(1, sent.filterIsInstance().size, "reconnect #$attempt should replay the REQ") - close(pool, "sub", "unsupported: too many filters") + // Under the threshold, each reconnect still replays the REQ (giving the relay a chance). + repeat(3) { attempt -> + val sent = reconnectAndSync(pool) + assertEquals(1, sent.filterIsInstance().size, "reconnect #$attempt should replay the REQ") + close(pool, "sub", "unsupported: too many filters") + } + + // Once the same filter has been refused [maxRefusalsBeforeSuppress] times, stop replaying it. + val suppressed = reconnectAndSync(pool) + assertTrue(suppressed.filterIsInstance().isEmpty(), "a thrice-refused filter must not be replayed again") } - // Once the same filter has been refused [maxRefusalsBeforeSuppress] times, stop replaying it. - val suppressed = reconnectAndSync(pool) - assertTrue(suppressed.filterIsInstance().isEmpty(), "a thrice-refused filter must not be replayed again") - } - @Test - fun aMeaningfulFilterChangeReEnablesTheReq() { - val pool = PoolRequests(maxRefusalsBeforeSuppress = 2) - pool.addOrUpdate("sub", mapOf(relay to plainFilter(1)), null) + fun aMeaningfulFilterChangeReEnablesTheReq() = + kotlinx.coroutines.test.runTest { + val pool = PoolRequests(maxRefusalsBeforeSuppress = 2) + pool.addOrUpdate("sub", mapOf(relay to plainFilter(1)), null) - repeat(2) { - reconnectAndSync(pool) - close(pool, "sub", "unsupported: too many filters") - } - assertTrue(reconnectAndSync(pool).filterIsInstance().isEmpty(), "refused filter is suppressed") + repeat(2) { + reconnectAndSync(pool) + close(pool, "sub", "unsupported: too many filters") + } + assertTrue(reconnectAndSync(pool).filterIsInstance().isEmpty(), "refused filter is suppressed") - // The app changes the subscription's filter (different kind) — the relay may now accept it. - pool.addOrUpdate("sub", mapOf(relay to plainFilter(30023)), null) - assertEquals(1, reconnectAndSync(pool).filterIsInstance().size, "a changed filter must be tried again") - } - - @Test - fun aSearchOnlyRelayStopsReceivingPlainReqsFromEveryNewSubOnOneConnection() { - // The search.nos.today case: 6 different subscriptions, one connection, each a - // distinct plain feed filter the relay CLOSES with `error: search filter is required`. - // Per-filter memory can't help (the filters differ); the relay-wide block must. - val pool = PoolRequests(relayRefusals = RelayReqRefusals(threshold = 2)) - - val sent = mutableListOf>() // subId -> did a REQ go out - - fun mountSub( - subId: String, - filter: List, - ) { - val affected = pool.addOrUpdate(subId, mapOf(relay to filter), null) - var reqSent = false - pool.sendToRelayIfChanged(subId, affected) { _, cmd -> if (cmd is ReqCmd) reqSent = true } - sent.add(subId to reqSent) - close(pool, subId, "error: search filter is required") + // The app changes the subscription's filter (different kind) — the relay may now accept it. + pool.addOrUpdate("sub", mapOf(relay to plainFilter(30023)), null) + assertEquals(1, reconnectAndSync(pool).filterIsInstance().size, "a changed filter must be tried again") } - mountSub("sub1", plainFilter(1)) - mountSub("sub2", plainFilter(2)) - mountSub("sub3", plainFilter(3)) - mountSub("sub4", plainFilter(4)) - - assertTrue(sent[0].second && sent[1].second, "the first two plain subs are sent (learning the relay is search-only)") - assertTrue(!sent[2].second && !sent[3].second, "after two refusals, further plain subs are not sent to a search-only relay") - } - @Test - fun aCapabilityBlockedRelayIsDroppedFromDesiredRelays() { - // The socket-closing half: once a relay is capability-blocked and no desired sub can - // use it, it leaves the desired-relay set so the pool disconnects it. - val pool = PoolRequests(relayRefusals = RelayReqRefusals(threshold = 2)) - pool.addOrUpdate("sub", mapOf(relay to plainFilter()), null) - assertTrue(relay in pool.desiredRelays.value, "the relay is wanted before it refuses anything") + fun aSearchOnlyRelayStopsReceivingPlainReqsFromEveryNewSubOnOneConnection() = + kotlinx.coroutines.test.runTest { + // The search.nos.today case: 6 different subscriptions, one connection, each a + // distinct plain feed filter the relay CLOSES with `error: search filter is required`. + // Per-filter memory can't help (the filters differ); the relay-wide block must. + val pool = PoolRequests(relayRefusals = RelayReqRefusals(threshold = 2)) - close(pool, "sub", "error: search filter is required") - assertTrue(relay in pool.desiredRelays.value, "one refusal doesn't drop it yet") + val sent = mutableListOf>() // subId -> did a REQ go out - close(pool, "sub", "error: search filter is required") - assertTrue(relay !in pool.desiredRelays.value, "a search-only relay with only plain subs is dropped (socket closes)") - } + suspend fun mountSub( + subId: String, + filter: List, + ) { + val affected = pool.addOrUpdate(subId, mapOf(relay to filter), null) + var reqSent = false + pool.sendToRelayIfChanged(subId, affected) { _, cmd -> if (cmd is ReqCmd) reqSent = true } + sent.add(subId to reqSent) + close(pool, subId, "error: search filter is required") + } - @Test - fun aSearchOnlyRelayStaysWantedWhileASearchSubNeedsIt() { - val pool = PoolRequests(relayRefusals = RelayReqRefusals(threshold = 2)) - pool.addOrUpdate("plain", mapOf(relay to plainFilter()), null) - pool.addOrUpdate("search", mapOf(relay to listOf(Filter(kinds = listOf(1), search = "nostr"))), null) + mountSub("sub1", plainFilter(1)) + mountSub("sub2", plainFilter(2)) + mountSub("sub3", plainFilter(3)) + mountSub("sub4", plainFilter(4)) - close(pool, "plain", "error: search filter is required") - close(pool, "plain", "error: search filter is required") - - assertTrue(relay in pool.desiredRelays.value, "the relay stays wanted: a search sub still has a usable filter for it") - } - - @Test - fun authRequiredAndRateLimitedAreNeverSuppressed() { - val pool = PoolRequests(maxRefusalsBeforeSuppress = 2) - pool.addOrUpdate("sub", mapOf(relay to plainFilter()), null) - - repeat(4) { - reconnectAndSync(pool) - close(pool, "sub", MachineReadablePrefix.AUTH_REQUIRED.format("authenticate first")) + assertTrue(sent[0].second && sent[1].second, "the first two plain subs are sent (learning the relay is search-only)") + assertTrue(!sent[2].second && !sent[3].second, "after two refusals, further plain subs are not sent to a search-only relay") } - assertEquals(1, reconnectAndSync(pool).filterIsInstance().size, "auth-required must keep replaying (auth resolves it)") - val pool2 = PoolRequests(maxRefusalsBeforeSuppress = 2) - pool2.addOrUpdate("sub", mapOf(relay to plainFilter()), null) - repeat(4) { + @Test + fun aCapabilityBlockedRelayIsDroppedFromDesiredRelays() = + kotlinx.coroutines.test.runTest { + // The socket-closing half: once a relay is capability-blocked and no desired sub can + // use it, it leaves the desired-relay set so the pool disconnects it. + val pool = PoolRequests(relayRefusals = RelayReqRefusals(threshold = 2)) + pool.addOrUpdate("sub", mapOf(relay to plainFilter()), null) + assertTrue(relay in pool.desiredRelays.value, "the relay is wanted before it refuses anything") + + close(pool, "sub", "error: search filter is required") + assertTrue(relay in pool.desiredRelays.value, "one refusal doesn't drop it yet") + + close(pool, "sub", "error: search filter is required") + assertTrue(relay !in pool.desiredRelays.value, "a search-only relay with only plain subs is dropped (socket closes)") + } + + @Test + fun aSearchOnlyRelayStaysWantedWhileASearchSubNeedsIt() = + kotlinx.coroutines.test.runTest { + val pool = PoolRequests(relayRefusals = RelayReqRefusals(threshold = 2)) + pool.addOrUpdate("plain", mapOf(relay to plainFilter()), null) + pool.addOrUpdate("search", mapOf(relay to listOf(Filter(kinds = listOf(1), search = "nostr"))), null) + + close(pool, "plain", "error: search filter is required") + close(pool, "plain", "error: search filter is required") + + assertTrue(relay in pool.desiredRelays.value, "the relay stays wanted: a search sub still has a usable filter for it") + } + + @Test + fun authRequiredAndRateLimitedAreNeverSuppressed() = + kotlinx.coroutines.test.runTest { + val pool = PoolRequests(maxRefusalsBeforeSuppress = 2) + pool.addOrUpdate("sub", mapOf(relay to plainFilter()), null) + + repeat(4) { + reconnectAndSync(pool) + close(pool, "sub", MachineReadablePrefix.AUTH_REQUIRED.format("authenticate first")) + } + assertEquals(1, reconnectAndSync(pool).filterIsInstance().size, "auth-required must keep replaying (auth resolves it)") + + val pool2 = PoolRequests(maxRefusalsBeforeSuppress = 2) + pool2.addOrUpdate("sub", mapOf(relay to plainFilter()), null) + repeat(4) { + pool2.onConnecting(relay) + val sent = mutableListOf() + pool2.syncState(relay) { sent.add(it) } + pool2.onIncomingMessage(FakeRelayClient(relay), ClosedMessage("sub", MachineReadablePrefix.RATE_LIMITED.format("slow down"))) + } pool2.onConnecting(relay) val sent = mutableListOf() pool2.syncState(relay) { sent.add(it) } - pool2.onIncomingMessage(FakeRelayClient(relay), ClosedMessage("sub", MachineReadablePrefix.RATE_LIMITED.format("slow down"))) + assertEquals(1, sent.filterIsInstance().size, "rate-limited must keep replaying (the limiter spaces it out)") } - pool2.onConnecting(relay) - val sent = mutableListOf() - pool2.syncState(relay) { sent.add(it) } - assertEquals(1, sent.filterIsInstance().size, "rate-limited must keep replaying (the limiter spaces it out)") - } } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/server/inprocess/InProcessWebSocketTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/server/inprocess/InProcessWebSocketTest.kt index 2b9cda14cd..4874586ebd 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/server/inprocess/InProcessWebSocketTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/server/inprocess/InProcessWebSocketTest.kt @@ -74,7 +74,7 @@ class InProcessWebSocketTest { callbacks.trySend("open") } - override fun onMessage(text: String) { + override suspend fun onMessage(text: String) { callbacks.trySend("message") } @@ -132,7 +132,7 @@ class InProcessWebSocketTest { ) { } - override fun onMessage(text: String) { + override suspend fun onMessage(text: String) { // Answer the AUTH challenge immediately, the way // RelayAuthenticator does. The socket must be fully // wired by the time any server frame is delivered, diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/server/NostrConnectSignerServiceTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/server/NostrConnectSignerServiceTest.kt index 12320fcfc5..3dcf86afd1 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/server/NostrConnectSignerServiceTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/server/NostrConnectSignerServiceTest.kt @@ -141,7 +141,7 @@ class NostrConnectSignerServiceTest { published.add(event) } - fun deliver(event: Event) { + suspend fun deliver(event: Event) { listener?.onEvent(event, isLive = true, relay = RelayUrlNormalizer.normalizeOrNull("wss://relay.example.com")!!, forFilters = null) } } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayObserverTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayObserverTest.kt index 6522dd5c64..efa6af497a 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayObserverTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayObserverTest.kt @@ -73,256 +73,276 @@ class RelayObserverTest { // ---- what we measured --------------------------------------------------- @Test - fun `rtt-open is the transport handshake rather than our own queueing`() { - // pingMillis is receivedResponseAtMillis - sentRequestAtMillis: it starts - // when the upgrade request goes out, so it excludes time the call spent - // queued in the client's dispatcher. Timing the enqueue instead published - // our own backlog as the relay's latency — a median of 33.5 SECONDS on a - // 16,507-relay fan-out, against a true minimum of 140ms — into the field - // aggregators rank relays by. - val o = RelayObserver() - o.onConnected(client(url), 140, false) - assertEquals(140L, o.only().rttOpenMs) - } + fun `rtt-open is the transport handshake rather than our own queueing`() = + kotlinx.coroutines.test.runTest { + // pingMillis is receivedResponseAtMillis - sentRequestAtMillis: it starts + // when the upgrade request goes out, so it excludes time the call spent + // queued in the client's dispatcher. Timing the enqueue instead published + // our own backlog as the relay's latency — a median of 33.5 SECONDS on a + // 16,507-relay fan-out, against a true minimum of 140ms — into the field + // aggregators rank relays by. + val o = RelayObserver() + o.onConnected(client(url), 140, false) + assertEquals(140L, o.only().rttOpenMs) + } @Test - fun `a handshake the transport could not time publishes no time`() { - val o = RelayObserver() - o.onConnected(client(url), 0, false) + fun `a handshake the transport could not time publishes no time`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.onConnected(client(url), 0, false) - val obs = o.only() - assertTrue(obs.reachable, "it opened, and that much is known") - assertNull(obs.rttOpenMs, "unmeasurable is not zero") - } + val obs = o.only() + assertTrue(obs.reachable, "it opened, and that much is known") + assertNull(obs.rttOpenMs, "unmeasurable is not zero") + } @Test - fun `an opened connection is timed rather than assumed`() { - val o = RelayObserver() - o.onConnecting(client(url)) - o.onConnected(client(url), 1, true) + fun `an opened connection is timed rather than assumed`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.onConnecting(client(url)) + o.onConnected(client(url), 1, true) - val obs = o.only() - assertTrue(obs.reachable) - assertNotNull(obs.rttOpenMs, "rtt-open must be measured — aggregators rank on it") - assertNull(obs.error) - } + val obs = o.only() + assertTrue(obs.reachable) + assertNotNull(obs.rttOpenMs, "rtt-open must be measured — aggregators rank on it") + assertNull(obs.error) + } @Test - fun `the read clock runs from the first REQ to the first EOSE`() { - val o = RelayObserver() - o.onConnecting(client(url)) - o.onConnected(client(url), 1, true) - o.onSent(client(url), "", ReqCmd("sub", emptyList()), true) - o.onIncomingMessage(client(url), "", EoseMessage("sub")) + fun `the read clock runs from the first REQ to the first EOSE`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.onConnecting(client(url)) + o.onConnected(client(url), 1, true) + o.onSent(client(url), "", ReqCmd("sub", emptyList()), true) + o.onIncomingMessage(client(url), "", EoseMessage("sub")) - assertNotNull(o.only().rttReadMs) - } + assertNotNull(o.only().rttReadMs) + } @Test - fun `the write clock runs from the first EVENT to its OK`() { - val o = RelayObserver() - o.onConnecting(client(url)) - o.onConnected(client(url), 1, true) - o.onIncomingMessage(client(url), "", OkMessage("id", true, "")) + fun `the write clock runs from the first EVENT to its OK`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.onConnecting(client(url)) + o.onConnected(client(url), 1, true) + o.onIncomingMessage(client(url), "", OkMessage("id", true, "")) - assertNull(o.collectUnreported().single().rttWriteMs, "an OK with nothing sent behind it times nothing") - } + assertNull(o.collectUnreported().single().rttWriteMs, "an OK with nothing sent behind it times nothing") + } @Test - fun `a non-REQ command does not start the read clock`() { - val o = RelayObserver() - o.onConnecting(client(url)) - o.onConnected(client(url), 1, true) - o.onSent(client(url), "", CloseCmd("sub"), true) - o.onIncomingMessage(client(url), "", EoseMessage("sub")) + fun `a non-REQ command does not start the read clock`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.onConnecting(client(url)) + o.onConnected(client(url), 1, true) + o.onSent(client(url), "", CloseCmd("sub"), true) + o.onIncomingMessage(client(url), "", EoseMessage("sub")) - assertNull(o.only().rttReadMs) - } + assertNull(o.only().rttReadMs) + } // ---- what we refuse to claim -------------------------------------------- @Test - fun `a connection that never opened records the reason and no latency`() { - val o = RelayObserver() - o.onConnecting(client(url)) - o.onCannotConnect(client(url), "Expected HTTP 101 response but was '503 Service Unavailable'") + fun `a connection that never opened records the reason and no latency`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.onConnecting(client(url)) + o.onCannotConnect(client(url), "Expected HTTP 101 response but was '503 Service Unavailable'") - val obs = o.only() - assertFalse(obs.reachable) - assertNull(obs.rttOpenMs, "nothing opened, so there is nothing to time") - assertTrue(obs.error!!.contains("503")) - } + val obs = o.only() + assertFalse(obs.reachable) + assertNull(obs.rttOpenMs, "nothing opened, so there is nothing to time") + assertTrue(obs.error!!.contains("503")) + } @Test - fun `a relay that answered stays answered through a later failure`() { - // A relay that worked a minute ago and blipped now is not the same thing - // as one that never answered, and only the writer decides which record - // that becomes. A single failure must not erase the success under it. - val o = RelayObserver() - o.onConnecting(client(url)) - o.onConnected(client(url), 1, true) - o.onCannotConnect(client(url), "connection reset") + fun `a relay that answered stays answered through a later failure`() = + kotlinx.coroutines.test.runTest { + // A relay that worked a minute ago and blipped now is not the same thing + // as one that never answered, and only the writer decides which record + // that becomes. A single failure must not erase the success under it. + val o = RelayObserver() + o.onConnecting(client(url)) + o.onConnected(client(url), 1, true) + o.onCannotConnect(client(url), "connection reset") - assertTrue(o.only().reachable, "one bad minute must not bury a relay that answered") - } + assertTrue(o.only().reachable, "one bad minute must not bury a relay that answered") + } @Test - fun `a reconnect clears the previous attempt's error`() { - val o = RelayObserver() - o.onConnecting(client(url)) - o.onCannotConnect(client(url), "timeout") - o.onConnecting(client(url)) + fun `a reconnect clears the previous attempt's error`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.onConnecting(client(url)) + o.onCannotConnect(client(url), "timeout") + o.onConnecting(client(url)) - assertNull(o.only().error, "a stale error would report a live relay as broken forever") - } + assertNull(o.only().error, "a stale error would report a live relay as broken forever") + } // ---- AUTH, which is why an anonymous crawl finds a relay empty ------------ @Test - fun `a demand for AUTH is recorded from either shape`() { - val challenged = RelayObserver() - challenged.onIncomingMessage(client(url), "", AuthMessage("challenge")) - assertTrue(challenged.only().authRequired) + fun `a demand for AUTH is recorded from either shape`() = + kotlinx.coroutines.test.runTest { + val challenged = RelayObserver() + challenged.onIncomingMessage(client(url), "", AuthMessage("challenge")) + assertTrue(challenged.only().authRequired) - val closed = RelayObserver() - closed.onIncomingMessage(client(url), "", ClosedMessage("sub", "auth-required: subscribers only")) - val obs = closed.only() - assertTrue(obs.authRequired) - assertEquals("auth-required", obs.closedReason) - } + val closed = RelayObserver() + closed.onIncomingMessage(client(url), "", ClosedMessage("sub", "auth-required: subscribers only")) + val obs = closed.only() + assertTrue(obs.authRequired) + assertEquals("auth-required", obs.closedReason) + } @Test - fun `a CLOSED that is not about auth is categorised rather than misread`() { - val o = RelayObserver() - o.onIncomingMessage(client(url), "", ClosedMessage("sub", "rate-limited: slow down")) + fun `a CLOSED that is not about auth is categorised rather than misread`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.onIncomingMessage(client(url), "", ClosedMessage("sub", "rate-limited: slow down")) - val obs = o.only() - assertEquals("rate-limited", obs.closedReason) - assertFalse(obs.authRequired, "only an auth refusal means auth is required") - } + val obs = o.only() + assertEquals("rate-limited", obs.closedReason) + assertFalse(obs.authRequired, "only an auth refusal means auth is required") + } // ---- publishing bookkeeping --------------------------------------------- @Test - fun `an unchanged relay is not re-reported but its measurement survives`() { - // Re-writing a record refreshes its freshness window, so a relay nobody - // re-measured must be left out. But the measurement itself has to stay: - // a long-lived socket fires onConnected once, and if publishing erased - // it, the relays we know best would be the ones we could never describe - // again. - val o = RelayObserver() - o.onConnecting(client(url)) - o.onConnected(client(url), 1, true) + fun `an unchanged relay is not re-reported but its measurement survives`() = + kotlinx.coroutines.test.runTest { + // Re-writing a record refreshes its freshness window, so a relay nobody + // re-measured must be left out. But the measurement itself has to stay: + // a long-lived socket fires onConnected once, and if publishing erased + // it, the relays we know best would be the ones we could never describe + // again. + val o = RelayObserver() + o.onConnecting(client(url)) + o.onConnected(client(url), 1, true) - val first = o.collectUnreported().single() - assertNotNull(first.rttOpenMs) - assertEquals(0, o.collectUnreported().size, "nothing new to say") + val first = o.collectUnreported().single() + assertNotNull(first.rttOpenMs) + assertEquals(0, o.collectUnreported().size, "nothing new to say") - o.onIncomingMessage(client(url), "", NoticeMessage("slow down")) - val second = o.collectUnreported().single() - assertEquals(first.rttOpenMs, second.rttOpenMs, "the last real measurement still stands") - } + o.onIncomingMessage(client(url), "", NoticeMessage("slow down")) + val second = o.collectUnreported().single() + assertEquals(first.rttOpenMs, second.rttOpenMs, "the last real measurement still stands") + } // ---- findings from outside the websocket client ------------------------ @Test - fun `a probe failure is published even though nothing was dialled`() { - // The cheap checks that decide NOT to open a websocket are exactly the - // ones that learn a relay is gone. Without a way in, a listener-only - // observer reports on the small minority it happened to connect to — - // 104 records out of a 16,507-relay list — which is not a census. - val o = RelayObserver() - o.record(url, reachable = false, error = "nodename nor servname provided") + fun `a probe failure is published even though nothing was dialled`() = + kotlinx.coroutines.test.runTest { + // The cheap checks that decide NOT to open a websocket are exactly the + // ones that learn a relay is gone. Without a way in, a listener-only + // observer reports on the small minority it happened to connect to — + // 104 records out of a 16,507-relay list — which is not a census. + val o = RelayObserver() + o.record(url, reachable = false, error = "nodename nor servname provided") - val obs = o.only() - assertFalse(obs.reachable) - assertEquals("nodename nor servname provided", obs.error) - assertNull(obs.rttOpenMs, "a failed probe times nothing") - } + val obs = o.only() + assertFalse(obs.reachable) + assertEquals("nodename nor servname provided", obs.error) + assertNull(obs.rttOpenMs, "a failed probe times nothing") + } @Test - fun `a probe that connected reports its measured time or none at all`() { - val timed = RelayObserver() - timed.record(url, reachable = true, rttOpenMs = 42) - assertEquals(42L, timed.only().rttOpenMs) + fun `a probe that connected reports its measured time or none at all`() = + kotlinx.coroutines.test.runTest { + val timed = RelayObserver() + timed.record(url, reachable = true, rttOpenMs = 42) + assertEquals(42L, timed.only().rttOpenMs) - val untimed = RelayObserver() - untimed.record(url, reachable = true) - val obs = untimed.only() - assertTrue(obs.reachable) - assertNull(obs.rttOpenMs, "reachable without a timing must not invent one") - } + val untimed = RelayObserver() + untimed.record(url, reachable = true) + val obs = untimed.only() + assertTrue(obs.reachable) + assertNull(obs.rttOpenMs, "reachable without a timing must not invent one") + } @Test - fun `a failed probe does not demote a relay that already answered`() { - // Same rule the connection path follows: one bad probe is not death, and - // only the writer decides what record a mixed history becomes. - val o = RelayObserver() - o.onConnecting(client(url)) - o.onConnected(client(url), 1, true) - o.record(url, reachable = false, error = "connect timeout") + fun `a failed probe does not demote a relay that already answered`() = + kotlinx.coroutines.test.runTest { + // Same rule the connection path follows: one bad probe is not death, and + // only the writer decides what record a mixed history becomes. + val o = RelayObserver() + o.onConnecting(client(url)) + o.onConnected(client(url), 1, true) + o.record(url, reachable = false, error = "connect timeout") - assertTrue(o.only().reachable, "it answered; a later probe failure does not erase that") - } + assertTrue(o.only().reachable, "it answered; a later probe failure does not erase that") + } @Test - fun `an out-of-band finding is reported once like any other`() { - val o = RelayObserver() - o.record(url, reachable = false, error = "refused") - assertEquals(1, o.collectUnreported().size) - assertEquals(0, o.collectUnreported().size, "nothing new to say") - } + fun `an out-of-band finding is reported once like any other`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.record(url, reachable = false, error = "refused") + assertEquals(1, o.collectUnreported().size) + assertEquals(0, o.collectUnreported().size, "nothing new to say") + } @Test - fun `each relay is observed on its own`() { - val o = RelayObserver() - o.onConnecting(client(url)) - o.onConnected(client(url), 1, true) - o.onConnecting(client(other)) - o.onCannotConnect(client(other), "nodename nor servname provided") + fun `each relay is observed on its own`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + o.onConnecting(client(url)) + o.onConnected(client(url), 1, true) + o.onConnecting(client(other)) + o.onCannotConnect(client(other), "nodename nor servname provided") - val byUrl = o.collectUnreported().associateBy { it.url } - assertTrue(byUrl.getValue(url).reachable) - assertFalse(byUrl.getValue(other).reachable) - } + val byUrl = o.collectUnreported().associateBy { it.url } + assertTrue(byUrl.getValue(url).reachable) + assertFalse(byUrl.getValue(other).reachable) + } // ---- the run-level summary (what RelayDiagnostics used to give) ----------- @Test - fun `the summary tallies feedback across every relay`() { - val o = RelayObserver() - assertFalse(o.hadFeedback()) + fun `the summary tallies feedback across every relay`() = + kotlinx.coroutines.test.runTest { + val o = RelayObserver() + assertFalse(o.hadFeedback()) - o.onIncomingMessage(client(url), "", AuthMessage("c1")) - o.onIncomingMessage(client(other), "", AuthMessage("c2")) - o.onIncomingMessage(client(url), "", ClosedMessage("s", "rate-limited: slow")) - o.onIncomingMessage(client(other), "", ClosedMessage("s", "rate-limited: slow")) - o.onIncomingMessage(client(url), "", NoticeMessage("too many REQs")) + o.onIncomingMessage(client(url), "", AuthMessage("c1")) + o.onIncomingMessage(client(other), "", AuthMessage("c2")) + o.onIncomingMessage(client(url), "", ClosedMessage("s", "rate-limited: slow")) + o.onIncomingMessage(client(other), "", ClosedMessage("s", "rate-limited: slow")) + o.onIncomingMessage(client(url), "", NoticeMessage("too many REQs")) - assertTrue(o.hadFeedback()) - val s = o.summary() - assertEquals(2L, s["auth_challenges"]) - assertEquals(2, s["auth_required_relays"]) - assertEquals(mapOf("rate-limited" to 2L), s["closed_by_reason"]) - assertEquals(1L, s["notices"]) - } + assertTrue(o.hadFeedback()) + val s = o.summary() + assertEquals(2L, s["auth_challenges"]) + assertEquals(2, s["auth_required_relays"]) + assertEquals(mapOf("rate-limited" to 2L), s["closed_by_reason"]) + assertEquals(1L, s["notices"]) + } @Test - fun `the summary outlives publishing`() { - // It answers "how did this run go", which must not be reset by the - // unrelated act of writing records out. - val o = RelayObserver() - o.onIncomingMessage(client(url), "", AuthMessage("c")) - o.collectUnreported() + fun `the summary outlives publishing`() = + kotlinx.coroutines.test.runTest { + // It answers "how did this run go", which must not be reset by the + // unrelated act of writing records out. + val o = RelayObserver() + o.onIncomingMessage(client(url), "", AuthMessage("c")) + o.collectUnreported() - assertTrue(o.hadFeedback(), "a flush must not erase the run's tally") - assertEquals(1L, o.summary()["auth_challenges"]) - } + assertTrue(o.hadFeedback(), "a flush must not erase the run's tally") + assertEquals(1L, o.summary()["auth_challenges"]) + } @Test - fun `a machine-readable prefix is extracted or falls back to other`() { - assertEquals("auth-required", RelayObserver.prefixOf("auth-required: come back signed")) - assertEquals("other", RelayObserver.prefixOf("just some prose")) - assertEquals("other", RelayObserver.prefixOf("")) - } + fun `a machine-readable prefix is extracted or falls back to other`() = + kotlinx.coroutines.test.runTest { + assertEquals("auth-required", RelayObserver.prefixOf("auth-required: come back signed")) + assertEquals("other", RelayObserver.prefixOf("just some prose")) + assertEquals("other", RelayObserver.prefixOf("")) + } } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayProberFlowTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayProberFlowTest.kt index 8593489ab2..1cfdfcea00 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayProberFlowTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/reachability/RelayProberFlowTest.kt @@ -85,7 +85,7 @@ class RelayProberFlowTest { } /** Plays a relay's OK answer for the published event to every armed listener. */ - fun answerOk( + suspend fun answerOk( relay: NormalizedRelayUrl, success: Boolean, message: String, @@ -235,13 +235,14 @@ class RelayProberFlowTest { } @Test - fun writeTestEventIsEphemeralAndSelfExpiring() { - val template = RelayProbeWriteTest.build(createdAt = 5000) + fun writeTestEventIsEphemeralAndSelfExpiring() = + kotlinx.coroutines.test.runTest { + val template = RelayProbeWriteTest.build(createdAt = 5000) - assertEquals(20166, template.kind) - assertTrue(template.kind in 20000..29999, "the write probe must be an ephemeral kind") - assertTrue(listOf("expiration", "5060") in template.tags.map { it.toList() }) - } + assertEquals(20166, template.kind) + assertTrue(template.kind in 20000..29999, "the write probe must be an ephemeral kind") + assertTrue(listOf("expiration", "5060") in template.tags.map { it.toList() }) + } // ------------------------------------------------------------------ // readWriteCheck — honest read + write measurements, nothing claimed @@ -358,108 +359,117 @@ class RelayProberFlowTest { private fun tagsOf(template: EventTemplate<*>) = template.tags.map { it.toList() } @Test - fun reachableVerdictTemplateCarriesLivenessAndNetwork() { - val template = - RelayProber - .Verdict(fast, reachable = true, rttOpenMs = 150, rttEoseMs = 480, error = null) - .toDiscoveryEventTemplate(createdAt = 1000) + fun reachableVerdictTemplateCarriesLivenessAndNetwork() = + kotlinx.coroutines.test.runTest { + val template = + RelayProber + .Verdict(fast, reachable = true, rttOpenMs = 150, rttEoseMs = 480, error = null) + .toDiscoveryEventTemplate(createdAt = 1000) - val tags = tagsOf(template) - assertEquals(30166, template.kind) - assertEquals(1000, template.createdAt) - assertTrue(listOf("d", fast.url) in tags) - assertTrue(listOf("n", "clearnet") in tags) - assertTrue(listOf("rtt-open", "150") in tags) - // rtt-eose is wave-relative (dial + queue + read) — never published as rtt-read. - assertNull(tags.firstOrNull { it[0] == "rtt-read" }) - } + val tags = tagsOf(template) + assertEquals(30166, template.kind) + assertEquals(1000, template.createdAt) + assertTrue(listOf("d", fast.url) in tags) + assertTrue(listOf("n", "clearnet") in tags) + assertTrue(listOf("rtt-open", "150") in tags) + // rtt-eose is wave-relative (dial + queue + read) — never published as rtt-read. + assertNull(tags.firstOrNull { it[0] == "rtt-read" }) + } @Test - fun deadVerdictTemplateHasNoRttOpen() { - val template = - RelayProber - .Verdict(silent, reachable = false, rttOpenMs = -1, rttEoseMs = -1, error = "cannot:timeout") - .toDiscoveryEventTemplate() + fun deadVerdictTemplateHasNoRttOpen() = + kotlinx.coroutines.test.runTest { + val template = + RelayProber + .Verdict(silent, reachable = false, rttOpenMs = -1, rttEoseMs = -1, error = "cannot:timeout") + .toDiscoveryEventTemplate() - val tags = tagsOf(template) - assertTrue(listOf("d", silent.url) in tags) - // Liveness is the PRESENCE of rtt-open; a dead record must not carry one. - assertNull(tags.firstOrNull { it[0] == "rtt-open" }) - } + val tags = tagsOf(template) + assertTrue(listOf("d", silent.url) in tags) + // Liveness is the PRESENCE of rtt-open; a dead record must not carry one. + assertNull(tags.firstOrNull { it[0] == "rtt-open" }) + } @Test - fun reachableWithoutMeasuredLatencyWritesZeroFlag() { - val template = - RelayProber - .Verdict(fast, reachable = true, rttOpenMs = -1, rttEoseMs = 300, error = null) - .toDiscoveryEventTemplate() + fun reachableWithoutMeasuredLatencyWritesZeroFlag() = + kotlinx.coroutines.test.runTest { + val template = + RelayProber + .Verdict(fast, reachable = true, rttOpenMs = -1, rttEoseMs = 300, error = null) + .toDiscoveryEventTemplate() - // 0 = "reachable, latency not observed": the flag form, never an invented number. - assertTrue(listOf("rtt-open", "0") in tagsOf(template)) - } + // 0 = "reachable, latency not observed": the flag form, never an invented number. + assertTrue(listOf("rtt-open", "0") in tagsOf(template)) + } @Test - fun observedAuthWallBecomesARequirementTag() { - val template = - RelayProber - .Verdict(walled, reachable = true, rttOpenMs = 90, rttEoseMs = -1, error = "closed:auth-required: sign in") - .toDiscoveryEventTemplate() + fun observedAuthWallBecomesARequirementTag() = + kotlinx.coroutines.test.runTest { + val template = + RelayProber + .Verdict(walled, reachable = true, rttOpenMs = 90, rttEoseMs = -1, error = "closed:auth-required: sign in") + .toDiscoveryEventTemplate() - assertTrue(listOf("R", "auth") in tagsOf(template)) - } + assertTrue(listOf("R", "auth") in tagsOf(template)) + } @Test - fun policyClosedIsNotAnAuthRequirement() { - val template = - RelayProber - .Verdict(walled, reachable = true, rttOpenMs = 90, rttEoseMs = -1, error = "closed:blocked: not welcome") - .toDiscoveryEventTemplate() + fun policyClosedIsNotAnAuthRequirement() = + kotlinx.coroutines.test.runTest { + val template = + RelayProber + .Verdict(walled, reachable = true, rttOpenMs = 90, rttEoseMs = -1, error = "closed:blocked: not welcome") + .toDiscoveryEventTemplate() - assertNull(tagsOf(template).firstOrNull { it[0] == "R" }) - } + assertNull(tagsOf(template).firstOrNull { it[0] == "R" }) + } @Test - fun readWriteResultsBecomeRttTags() { - val verdict = RelayProber.Verdict(fast, reachable = true, rttOpenMs = 100, rttEoseMs = 300, error = null) - val readWrite = RelayProber.ReadWriteVerdict(fast, rttReadMs = 40, rttWriteMs = 55, writeAccepted = true, writeMessage = "") + fun readWriteResultsBecomeRttTags() = + kotlinx.coroutines.test.runTest { + val verdict = RelayProber.Verdict(fast, reachable = true, rttOpenMs = 100, rttEoseMs = 300, error = null) + val readWrite = RelayProber.ReadWriteVerdict(fast, rttReadMs = 40, rttWriteMs = 55, writeAccepted = true, writeMessage = "") - val tags = tagsOf(verdict.toDiscoveryEventTemplate(readWrite = readWrite)) - assertTrue(listOf("rtt-read", "40") in tags) - assertTrue(listOf("rtt-write", "55") in tags) - } + val tags = tagsOf(verdict.toDiscoveryEventTemplate(readWrite = readWrite)) + assertTrue(listOf("rtt-read", "40") in tags) + assertTrue(listOf("rtt-write", "55") in tags) + } @Test - fun unobservedReadWriteSidesStayUntagged() { - val verdict = RelayProber.Verdict(fast, reachable = true, rttOpenMs = 100, rttEoseMs = -1, error = null) - val readWrite = RelayProber.ReadWriteVerdict(fast, rttReadMs = -1, rttWriteMs = -1, writeAccepted = null, writeMessage = null) + fun unobservedReadWriteSidesStayUntagged() = + kotlinx.coroutines.test.runTest { + val verdict = RelayProber.Verdict(fast, reachable = true, rttOpenMs = 100, rttEoseMs = -1, error = null) + val readWrite = RelayProber.ReadWriteVerdict(fast, rttReadMs = -1, rttWriteMs = -1, writeAccepted = null, writeMessage = null) - val tags = tagsOf(verdict.toDiscoveryEventTemplate(readWrite = readWrite)) - assertNull(tags.firstOrNull { it[0] == "rtt-read" }) - assertNull(tags.firstOrNull { it[0] == "rtt-write" }) - } + val tags = tagsOf(verdict.toDiscoveryEventTemplate(readWrite = readWrite)) + assertNull(tags.firstOrNull { it[0] == "rtt-read" }) + assertNull(tags.firstOrNull { it[0] == "rtt-write" }) + } @Test - fun writeRejectionReasonsBecomeRequirementTags() { - val verdict = RelayProber.Verdict(walled, reachable = true, rttOpenMs = 100, rttEoseMs = -1, error = null) + fun writeRejectionReasonsBecomeRequirementTags() = + kotlinx.coroutines.test.runTest { + val verdict = RelayProber.Verdict(walled, reachable = true, rttOpenMs = 100, rttEoseMs = -1, error = null) - val pow = RelayProber.ReadWriteVerdict(walled, -1, 30, writeAccepted = false, writeMessage = "pow: 28 bits needed") - assertTrue(listOf("R", "pow") in tagsOf(verdict.toDiscoveryEventTemplate(readWrite = pow))) + val pow = RelayProber.ReadWriteVerdict(walled, -1, 30, writeAccepted = false, writeMessage = "pow: 28 bits needed") + assertTrue(listOf("R", "pow") in tagsOf(verdict.toDiscoveryEventTemplate(readWrite = pow))) - val auth = RelayProber.ReadWriteVerdict(walled, -1, 30, writeAccepted = false, writeMessage = "auth-required: sign in") - assertTrue(listOf("R", "auth") in tagsOf(verdict.toDiscoveryEventTemplate(readWrite = auth))) + val auth = RelayProber.ReadWriteVerdict(walled, -1, 30, writeAccepted = false, writeMessage = "auth-required: sign in") + assertTrue(listOf("R", "auth") in tagsOf(verdict.toDiscoveryEventTemplate(readWrite = auth))) - val blocked = RelayProber.ReadWriteVerdict(walled, -1, 30, writeAccepted = false, writeMessage = "blocked: not welcome") - assertNull(tagsOf(verdict.toDiscoveryEventTemplate(readWrite = blocked)).firstOrNull { it[0] == "R" }) - } + val blocked = RelayProber.ReadWriteVerdict(walled, -1, 30, writeAccepted = false, writeMessage = "blocked: not welcome") + assertNull(tagsOf(verdict.toDiscoveryEventTemplate(readWrite = blocked)).firstOrNull { it[0] == "R" }) + } @Test - fun onionRelayIsTaggedTor() { - val onion = RelayUrlNormalizer.normalize("ws://someonionaddressabcdefghijklmnop.onion") - val template = - RelayProber - .Verdict(onion, reachable = true, rttOpenMs = 900, rttEoseMs = -1, error = null) - .toDiscoveryEventTemplate() + fun onionRelayIsTaggedTor() = + kotlinx.coroutines.test.runTest { + val onion = RelayUrlNormalizer.normalize("ws://someonionaddressabcdefghijklmnop.onion") + val template = + RelayProber + .Verdict(onion, reachable = true, rttOpenMs = 900, rttEoseMs = -1, error = null) + .toDiscoveryEventTemplate() - assertTrue(listOf("n", "tor") in tagsOf(template)) - } + assertTrue(listOf("n", "tor") in tagsOf(template)) + } } diff --git a/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/NostrClientManualSubTest.kt b/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/NostrClientManualSubTest.kt index 06354f98d2..50dfac2519 100644 --- a/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/NostrClientManualSubTest.kt +++ b/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/NostrClientManualSubTest.kt @@ -47,7 +47,7 @@ class NostrClientManualSubTest : RelayClientTest() { val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/NostrClientRepeatSubTest.kt b/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/NostrClientRepeatSubTest.kt index 0c283d4314..7531b70068 100644 --- a/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/NostrClientRepeatSubTest.kt +++ b/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/NostrClientRepeatSubTest.kt @@ -71,7 +71,7 @@ class NostrClientRepeatSubTest : RelayClientTest() { val listener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/PoolRequestsConcurrencyTest.kt b/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/PoolRequestsConcurrencyTest.kt index 6d21d526e3..4add1aea15 100644 --- a/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/PoolRequestsConcurrencyTest.kt +++ b/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/PoolRequestsConcurrencyTest.kt @@ -78,69 +78,70 @@ class PoolRequestsConcurrencyTest { } @Test - fun concurrentEoseResendAndSubscribeSendExactlyOneReq() { - val url = RelayUrlNormalizer.normalize("ws://race/") - val subId = "shared-sub" - val filtersA = listOf(Filter(kinds = listOf(1))) - val filtersB = listOf(Filter(kinds = listOf(2))) - val listener = object : SubscriptionListener {} + fun concurrentEoseResendAndSubscribeSendExactlyOneReq() = + kotlinx.coroutines.test.runTest { + val url = RelayUrlNormalizer.normalize("ws://race/") + val subId = "shared-sub" + val filtersA = listOf(Filter(kinds = listOf(1))) + val filtersB = listOf(Filter(kinds = listOf(2))) + val listener = object : SubscriptionListener {} - // Many episodes so a regression that only sometimes doubles still trips. - repeat(300) { episode -> - val pool = PoolRequests() - val reqBCount = AtomicInteger(0) + // Many episodes so a regression that only sometimes doubles still trips. + repeat(300) { episode -> + val pool = PoolRequests() + val reqBCount = AtomicInteger(0) - fun countReqB(cmd: Command) { - if (cmd is ReqCmd && cmd.filters == filtersB) reqBCount.incrementAndGet() - } - - val fakeRelay = - FakeRelay(url) { cmd -> - // relay-reader auto-resend send path - countReqB(cmd) - pool.onSent(url, cmd) + fun countReqB(cmd: Command) { + if (cmd is ReqCmd && cmd.filters == filtersB) reqBCount.incrementAndGet() } - // Bring the sub to LIVE with filters A. - val setupRelays = pool.addOrUpdate(subId, mapOf(url to filtersA), listener) - pool.sendToRelayIfChanged(subId, setupRelays) { _, cmd -> pool.onSent(url, cmd) } - pool.onIncomingMessage(fakeRelay, EoseMessage(subId)) - - // The desired filters change to B (e.g. the next page of a paged download). - pool.addOrUpdate(subId, mapOf(url to filtersB), listener) - - val appProducedReq = CountDownLatch(1) - val readerDone = CountDownLatch(1) - - val appThread = - thread { - pool.sendToRelayIfChanged(subId, setOf(url)) { _, cmd -> + val fakeRelay = + FakeRelay(url) { cmd -> + // relay-reader auto-resend send path countReqB(cmd) - // App has produced its REQ(B); park before onSent so the - // subscription state is not yet advanced — the exact window - // the race needs. - appProducedReq.countDown() - readerDone.await() pool.onSent(url, cmd) } - } - val readerThread = - thread { - appProducedReq.await() - pool.onIncomingMessage(fakeRelay, EoseMessage(subId)) - readerDone.countDown() - } + // Bring the sub to LIVE with filters A. + val setupRelays = pool.addOrUpdate(subId, mapOf(url to filtersA), listener) + pool.sendToRelayIfChanged(subId, setupRelays) { _, cmd -> pool.onSent(url, cmd) } + pool.onIncomingMessage(fakeRelay, EoseMessage(subId)) - appThread.join() - readerThread.join() + // The desired filters change to B (e.g. the next page of a paged download). + pool.addOrUpdate(subId, mapOf(url to filtersB), listener) - assertEquals( - 1, - reqBCount.get(), - "episode $episode: exactly one REQ must be sent for the changed filters, " + - "never a duplicate from the app + reader race", - ) + val appProducedReq = CountDownLatch(1) + val readerDone = CountDownLatch(1) + + val appThread = + thread { + pool.sendToRelayIfChanged(subId, setOf(url)) { _, cmd -> + countReqB(cmd) + // App has produced its REQ(B); park before onSent so the + // subscription state is not yet advanced — the exact window + // the race needs. + appProducedReq.countDown() + readerDone.await() + pool.onSent(url, cmd) + } + } + + val readerThread = + thread { + appProducedReq.await() + kotlinx.coroutines.runBlocking { pool.onIncomingMessage(fakeRelay, EoseMessage(subId)) } + readerDone.countDown() + } + + appThread.join() + readerThread.join() + + assertEquals( + 1, + reqBCount.get(), + "episode $episode: exactly one REQ must be sent for the changed filters, " + + "never a duplicate from the app + reader race", + ) + } } - } } diff --git a/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/auth/RelayAuthenticatorReauthOnClosedTest.kt b/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/auth/RelayAuthenticatorReauthOnClosedTest.kt index e10a5a7c32..e8ae39933b 100644 --- a/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/auth/RelayAuthenticatorReauthOnClosedTest.kt +++ b/quartz/src/jvmAndroidTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/auth/RelayAuthenticatorReauthOnClosedTest.kt @@ -100,7 +100,7 @@ class RelayAuthenticatorReauthOnClosedTest { .filterIsInstance() .last() .event - listener.onIncomingMessage(relay, "", OkMessage.accepted(newest.id)) + kotlinx.coroutines.runBlocking { listener.onIncomingMessage(relay, "", OkMessage.accepted(newest.id)) } } @Test diff --git a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NegentropyRejectionFallbackTest.kt b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NegentropyRejectionFallbackTest.kt index 230674d4d0..006b8ffe16 100644 --- a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NegentropyRejectionFallbackTest.kt +++ b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NegentropyRejectionFallbackTest.kt @@ -91,11 +91,11 @@ class NegentropyRejectionFallbackTest { when { // The keep-alive REQ and any paging REQ: answer EOSE so the // subscription settles (paging then completes with 0 events). - msg.startsWith("[\"REQ\"") -> subIdOf(msg)?.let { out.onMessage("[\"EOSE\",\"$it\"]") } + msg.startsWith("[\"REQ\"") -> subIdOf(msg)?.let { kotlinx.coroutines.runBlocking { out.onMessage("[\"EOSE\",\"$it\"]") } } // The negentropy handshake: the relay refuses. msg.startsWith("[\"NEG-OPEN\"") -> { negOpens.incrementAndGet() - subIdOf(msg)?.let { out.onMessage(replyToNegOpen(it)) } + subIdOf(msg)?.let { kotlinx.coroutines.runBlocking { out.onMessage(replyToNegOpen(it)) } } } else -> Unit } @@ -140,25 +140,28 @@ class NegentropyRejectionFallbackTest { } @Test - fun strfryNegentropyDisabledFallsBackToPaging() { - negOpenRejectedBy { "[\"NOTICE\",\"ERROR: bad msg: negentropy disabled\"]" } - } + fun strfryNegentropyDisabledFallsBackToPaging() = + kotlinx.coroutines.test.runTest { + negOpenRejectedBy { "[\"NOTICE\",\"ERROR: bad msg: negentropy disabled\"]" } + } @Test - fun purplePagesUnknownEnvelopeFallsBackToPaging() { - negOpenRejectedBy { "[\"NOTICE\",\"failed to parse envelope: unknown envelope label\"]" } - } + fun purplePagesUnknownEnvelopeFallsBackToPaging() = + kotlinx.coroutines.test.runTest { + negOpenRejectedBy { "[\"NOTICE\",\"failed to parse envelope: unknown envelope label\"]" } + } @Test - fun rateLimitNegErrPagesWithoutSplitStorm() { - // A NEG-ERR that does NOT shrink with the window ("too many requests") must not - // be mistaken for a set-too-large overflow: doing so would binary-split the - // created_at range forever. Assert we page after exactly ONE NEG-OPEN. - val relay = negOpenRejectedBy { subId -> "[\"NEG-ERR\",\"$subId\",\"rate-limited: too many requests\"]" } - assertEquals( - 2, - relay.negOpens.get(), - "one NEG-OPEN per phase (sync + syncOrFetch), i.e. no window-split storm; got ${relay.negOpens.get()}", - ) - } + fun rateLimitNegErrPagesWithoutSplitStorm() = + kotlinx.coroutines.test.runTest { + // A NEG-ERR that does NOT shrink with the window ("too many requests") must not + // be mistaken for a set-too-large overflow: doing so would binary-split the + // created_at range forever. Assert we page after exactly ONE NEG-OPEN. + val relay = negOpenRejectedBy { subId -> "[\"NEG-ERR\",\"$subId\",\"rate-limited: too many requests\"]" } + assertEquals( + 2, + relay.negOpens.get(), + "one NEG-OPEN per phase (sync + syncOrFetch), i.e. no window-split storm; got ${relay.negOpens.get()}", + ) + } } diff --git a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/ByIdFetchBenchmark.kt b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/ByIdFetchBenchmark.kt index 6dd57131e0..9775a20308 100644 --- a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/ByIdFetchBenchmark.kt +++ b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/ByIdFetchBenchmark.kt @@ -136,7 +136,7 @@ class ByIdFetchBenchmark { val done = Channel(Channel.CONFLATED) val listener = object : SubscriptionListener { - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl, diff --git a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/DispatchStageBenchmark.kt b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/DispatchStageBenchmark.kt index 8a64c4a0e5..ed0909257e 100644 --- a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/DispatchStageBenchmark.kt +++ b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/DispatchStageBenchmark.kt @@ -197,7 +197,7 @@ class DispatchStageBenchmark { continue } for (subId in subIds) { - client.onIncomingMessage(relayClient, "", EventMessage(subId, event)) + kotlinx.coroutines.runBlocking { client.onIncomingMessage(relayClient, "", EventMessage(subId, event)) } } } } @@ -259,7 +259,7 @@ class DispatchStageBenchmark { Thread { for (event in events) { for (subId in subIds) { - pool.onIncomingMessage(relayClient, EventMessage(subId, event)) + kotlinx.coroutines.runBlocking { pool.onIncomingMessage(relayClient, EventMessage(subId, event)) } } } } @@ -299,12 +299,13 @@ class DispatchStageBenchmark { } @Test - fun dispatchStageBenchmark() { - println("=== DISPATCH STAGE BENCHMARK (post-parse, pre-verify) ===") - println("cores=${Runtime.getRuntime().availableProcessors()} uniqueEvents=$UNIQUE_EVENTS subsPerRelay=$SUBS_PER_RELAY") + fun dispatchStageBenchmark() = + kotlinx.coroutines.test.runTest { + println("=== DISPATCH STAGE BENCHMARK (post-parse, pre-verify) ===") + println("cores=${Runtime.getRuntime().availableProcessors()} uniqueEvents=$UNIQUE_EVENTS subsPerRelay=$SUBS_PER_RELAY") - // warmup pass (JIT), then the measured pass - runAllVariants(print = false) - runAllVariants(print = true) - } + // warmup pass (JIT), then the measured pass + runAllVariants(print = false) + runAllVariants(print = true) + } } diff --git a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/NegentropyMultiRelayLiveTest.kt b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/NegentropyMultiRelayLiveTest.kt index 1c72b53690..8d95420c6b 100644 --- a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/NegentropyMultiRelayLiveTest.kt +++ b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/NegentropyMultiRelayLiveTest.kt @@ -177,7 +177,7 @@ class NegentropyMultiRelayLiveTest { val listener = object : RelayConnectionListener { - override fun onIncomingMessage( + override suspend fun onIncomingMessage( relay: IRelayClient, msgStr: String, msg: Message, diff --git a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/NegentropyStallRepro.kt b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/NegentropyStallRepro.kt index 04d6338582..c85e4fb80a 100644 --- a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/NegentropyStallRepro.kt +++ b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/NegentropyStallRepro.kt @@ -109,7 +109,7 @@ class NegentropyStallRepro { out.onOpen(pingMillis, usingCompression) } - override fun onMessage(text: String) { + override suspend fun onMessage(text: String) { val t = tagger(text) recvCounts.getOrPut(t) { AtomicInteger() }.incrementAndGet() if (t == "NEG-MSG") negMsgBytesIn.addAndGet(text.length.toLong()) diff --git a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/ProductionReceiverBenchmark.kt b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/ProductionReceiverBenchmark.kt index b226af0641..eca181e106 100644 --- a/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/ProductionReceiverBenchmark.kt +++ b/quartz/src/jvmTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/prodbench/ProductionReceiverBenchmark.kt @@ -370,7 +370,7 @@ class ProductionReceiverBenchmark { reqSentAt.putIfAbsent(relay, System.nanoTime() - startNanos) } - override fun onEvent( + override suspend fun onEvent( event: Event, isLive: Boolean, relay: NormalizedRelayUrl,