Restart notification service on new connection or on error

If a relay is reconnected, restart the notification service to make sure all events are correctly processed.

If there's an error sending an event to a relay, log the error and reconnect to the relay.
This commit is contained in:
greenart7c3
2025-08-01 07:26:56 -03:00
parent 742c6020e1
commit 976bdba20e
2 changed files with 40 additions and 7 deletions
@@ -262,9 +262,6 @@ class Amber : Application(), LifecycleObserver {
newRelays: Set<RelaySetupInfo> = emptySet(),
) {
val savedRelays = getSavedRelays() + newRelays
val savedUrls = savedRelays.map { it.url }.toSet()
val allClientRelays = client.getAll()
val hasNewRelays = allClientRelays.any { it.url !in savedUrls }
val hasAccount = LocalPreferences.allSavedAccounts(this).isNotEmpty()
if (savedRelays.isEmpty() || !hasAccount) {
@@ -283,10 +280,9 @@ class Amber : Application(), LifecycleObserver {
savedRelays.map { RelaySetupInfoToConnect(it.url, if (isPrivateIp(it.url)) false else settings.useProxy, it.read, it.write, it.feedTypes) }.toTypedArray(),
true,
)
if (hasNewRelays) {
NotificationDataSource.stop()
delay(1000)
}
NotificationDataSource.stop()
delay(1000)
NotificationDataSource.start()
applicationIOScope.launch {
delay(1000)
@@ -41,6 +41,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
object NotificationDataSource : NostrDataSource(Amber.instance.client) {
@@ -81,6 +82,13 @@ object NotificationDataSource : NostrDataSource(Amber.instance.client) {
)
}
}
if (type == RelayState.CONNECTED) {
Amber.instance.applicationIOScope.launch {
stop()
delay(1000)
start()
}
}
}
override fun onError(error: Error, subscriptionId: String, relay: Relay) {
@@ -140,6 +148,35 @@ object NotificationDataSource : NostrDataSource(Amber.instance.client) {
notify(relay, description)
}
override fun onSend(relay: Relay, msg: String, success: Boolean) {
if (!success) {
scope.launch {
LocalPreferences.currentAccount(Amber.instance)?.let { account ->
Amber.instance.getDatabase(account).applicationDao().insertLog(
LogEntity(
id = 0,
url = relay.url,
type = "onSend",
message = "Failed to send message: $msg",
time = System.currentTimeMillis(),
),
)
}
}
if (relay.isConnected()) {
Amber.instance.applicationIOScope.launch {
relay.disconnect()
delay(1000)
relay.connect()
delay(2000)
relay.renewFilters()
}
}
}
super.onSend(relay, msg, success)
}
override fun onSendResponse(eventId: String, success: Boolean, message: String, relay: Relay) {
if (success) {
AmberRelayStats.addSent(relay.url)