Skip to content

Commit

Permalink
Merge pull request #1467 from WalletConnect/feat/link_mode_success_rate
Browse files Browse the repository at this point in the history
feat: Link Mode Success Rate
  • Loading branch information
jakubuid authored Aug 23, 2024
2 parents f419d8f + 0264060 commit 97c9c07
Show file tree
Hide file tree
Showing 49 changed files with 1,003 additions and 170 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.walletconnect.android

import android.app.Application
import android.content.SharedPreferences
import com.walletconnect.android.di.coreStorageModule
import com.walletconnect.android.internal.common.di.AndroidCommonDITags
import com.walletconnect.android.internal.common.di.KEY_CLIENT_ID
import com.walletconnect.android.internal.common.di.coreAndroidNetworkModule
import com.walletconnect.android.internal.common.di.coreCommonModule
import com.walletconnect.android.internal.common.di.coreCryptoModule
Expand Down Expand Up @@ -155,6 +157,7 @@ class CoreProtocol(private val koinApp: KoinApplication = wcKoinApp) : CoreInter

modules(
coreStorageModule(bundleId = bundleId),
module { single(named(AndroidCommonDITags.CLIENT_ID)) { requireNotNull(get<SharedPreferences>().getString(KEY_CLIENT_ID, null)) } },
pushModule(),
module { single { relay ?: Relay } },
module {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit

private const val INIT_BACKOFF_MILLIS = 1L
private const val MAX_BACKOFF_SEC = 20L
internal const val KEY_CLIENT_ID = "clientId"

@Suppress("LocalVariableName")
@JvmSynthetic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.squareup.moshi.Moshi
import com.walletconnect.android.internal.common.model.TelemetryEnabled
import com.walletconnect.android.pulse.data.PulseService
import com.walletconnect.android.pulse.domain.InsertEventUseCase
import com.walletconnect.android.pulse.domain.InsertTelemetryEventUseCase
import com.walletconnect.android.pulse.domain.SendBatchEventUseCase
import com.walletconnect.android.pulse.domain.SendEventInterface
import com.walletconnect.android.pulse.domain.SendEventUseCase
Expand Down Expand Up @@ -45,6 +46,13 @@ fun pulseModule(bundleId: String) = module {
)
}

single {
InsertTelemetryEventUseCase(
logger = get(named(AndroidCommonDITags.LOGGER)),
eventsRepository = get(),
)
}

single {
InsertEventUseCase(
logger = get(named(AndroidCommonDITags.LOGGER)),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.walletconnect.android.internal.common.di

import android.content.SharedPreferences
import com.walletconnect.android.push.PushInterface
import com.walletconnect.android.push.network.PushService
import com.walletconnect.android.push.notifications.DecryptMessageUseCaseInterface
import org.koin.core.qualifier.named
Expand All @@ -26,9 +24,5 @@ internal fun pushModule() = module {
get<Retrofit>(named(AndroidCommonDITags.PUSH_RETROFIT)).create(PushService::class.java)
}

single(named(AndroidCommonDITags.CLIENT_ID)) {
requireNotNull(get<SharedPreferences>().getString(PushInterface.KEY_CLIENT_ID, null))
}

single<MutableMap<String, DecryptMessageUseCaseInterface>>(named(AndroidCommonDITags.DECRYPT_USE_CASES)) { mutableMapOf() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package com.walletconnect.android.internal.common.jwt.clientid

import android.content.SharedPreferences
import androidx.core.content.edit
import com.walletconnect.android.push.PushInterface
import com.walletconnect.android.internal.common.di.KEY_CLIENT_ID
import com.walletconnect.android.utils.strippedUrl
import com.walletconnect.foundation.crypto.data.repository.ClientIdJwtRepository

Expand All @@ -13,7 +13,7 @@ internal class GenerateJwtStoreClientIdUseCase(private val clientIdJwtRepository
operator fun invoke(relayUrl: String): String =
clientIdJwtRepository.generateJWT(relayUrl.strippedUrl()) { clientId ->
sharedPreferences.edit {
putString(PushInterface.KEY_CLIENT_ID, clientId)
putString(KEY_CLIENT_ID, clientId)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ enum class Tags(val id: Int) {
SESSION_AUTHENTICATE_RESPONSE_REJECT(1118),
SESSION_AUTHENTICATE_RESPONSE_AUTO_REJECT(1119),

SESSION_AUTHENTICATE_LINK_MODE(1122),
SESSION_AUTHENTICATE_LINK_MODE_RESPONSE_APPROVE(1123),
SESSION_AUTHENTICATE_LINK_MODE_RESPONSE_REJECT(1124),

SESSION_REQUEST_LINK_MODE(1125),
SESSION_REQUEST_LINK_MODE_RESPONSE(1126),

CHAT_INVITE(2000),
CHAT_INVITE_RESPONSE(2001),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.walletconnect.android.internal.common.model.TelemetryEnabled
import com.walletconnect.android.pulse.model.Event
import com.walletconnect.android.pulse.model.properties.Properties
import com.walletconnect.android.pulse.model.properties.Props
import com.walletconnect.android.sdk.storage.data.dao.EventDao
import com.walletconnect.android.sdk.storage.data.dao.EventQueries
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
Expand All @@ -18,47 +19,49 @@ class EventsRepository(
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) {
@Throws(SQLiteException::class)
suspend fun insertOrAbort(props: Props) = withContext(dispatcher) {
suspend fun insertOrAbortTelemetry(props: Props) = withContext(dispatcher) {
if (telemetryEnabled.value) {
with(Event(bundleId = bundleId, props = props)) {
eventQueries.insertOrAbort(
eventId,
bundleId,
timestamp,
this.props.event,
this.props.type,
this.props.properties?.topic,
this.props.properties?.trace
)
}
insertOrAbort(props)
}
}

@Throws(SQLiteException::class)
suspend fun insertOrAbort(props: Props) = withContext(dispatcher) {
with(Event(bundleId = bundleId, props = props)) {
eventQueries.insertOrAbort(
eventId,
bundleId,
timestamp,
this.props.event,
this.props.type,
this.props.properties?.topic,
this.props.properties?.trace,
this.props.properties?.correlationId,
this.props.properties?.clientId,
this.props.properties?.direction
)
}
}

@Throws(SQLiteException::class)
suspend fun getAllWithLimitAndOffset(limit: Int, offset: Int): List<Event> {
return eventQueries.getAllWithLimitAndOffset(limit.toLong(), offset.toLong())
suspend fun getAllEventsWithLimitAndOffset(limit: Int, offset: Int): List<Event> {
return eventQueries.getAllEventsWithLimitAndOffset(limit.toLong(), offset.toLong())
.awaitAsList()
.map {
Event(
eventId = it.event_id,
bundleId = it.bundle_id,
timestamp = it.timestamp,
props = Props(
event = it.event_name,
type = it.type,
properties = Properties(
topic = it.topic,
trace = it.trace
)
)
)
}
.map { dao -> dao.toEvent() }
}

@Throws(SQLiteException::class)
suspend fun deleteAll() {
suspend fun getAllNonTelemetryEventsWithLimitAndOffset(limit: Int, offset: Int): List<Event> {
return eventQueries.getAllEventsWithLimitAndOffset(limit.toLong(), offset.toLong())
.awaitAsList()
.filter { dao -> dao.correlation_id != null }
.map { dao -> dao.toEvent() }
}

@Throws(SQLiteException::class)
suspend fun deleteAllTelemetry() {
return withContext(dispatcher) {
eventQueries.deleteAll()
eventQueries.deleteAllTelemetry()
}
}

Expand All @@ -68,4 +71,22 @@ class EventsRepository(
eventQueries.deleteByIds(eventIds)
}
}

private fun EventDao.toEvent(): Event =
Event(
eventId = event_id,
bundleId = bundle_id,
timestamp = timestamp,
props = Props(
event = event_name,
type = type,
properties = Properties(
topic = topic,
trace = trace,
clientId = client_id,
correlationId = correlation_id,
direction = direction
)
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.walletconnect.android.internal.common.wcKoinApp
import com.walletconnect.android.pairing.engine.domain.PairingEngine
import com.walletconnect.android.pairing.engine.model.EngineDO
import com.walletconnect.android.pairing.model.mapper.toCore
import com.walletconnect.android.pulse.domain.InsertEventUseCase
import com.walletconnect.android.pulse.domain.InsertTelemetryEventUseCase
import com.walletconnect.android.pulse.model.EventType
import com.walletconnect.android.pulse.model.properties.Props
import com.walletconnect.android.relay.RelayConnectionInterface
Expand All @@ -26,7 +26,7 @@ internal class PairingProtocol(private val koinApp: KoinApplication = wcKoinApp)
private lateinit var pairingEngine: PairingEngine
private val logger: Logger by lazy { koinApp.koin.get() }
private val relayClient: RelayConnectionInterface by lazy { koinApp.koin.get() }
private val insertEventUseCase: InsertEventUseCase by lazy { koinApp.koin.get() }
private val insertEventUseCase: InsertTelemetryEventUseCase by lazy { koinApp.koin.get() }

override fun initialize() {
pairingEngine = koinApp.koin.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import com.walletconnect.android.pairing.model.PairingParams
import com.walletconnect.android.pairing.model.PairingRpc
import com.walletconnect.android.pairing.model.mapper.toCore
import com.walletconnect.android.pairing.model.pairingExpiry
import com.walletconnect.android.pulse.domain.InsertEventUseCase
import com.walletconnect.android.pulse.domain.InsertTelemetryEventUseCase
import com.walletconnect.android.pulse.domain.SendBatchEventUseCase
import com.walletconnect.android.pulse.model.EventType
import com.walletconnect.android.pulse.model.Trace
Expand Down Expand Up @@ -84,7 +84,7 @@ internal class PairingEngine(
private val crypto: KeyManagementRepository,
private val jsonRpcInteractor: RelayJsonRpcInteractorInterface,
private val pairingRepository: PairingStorageRepositoryInterface,
private val insertEventUseCase: InsertEventUseCase,
private val insertEventUseCase: InsertTelemetryEventUseCase,
private val sendBatchEventUseCase: SendBatchEventUseCase
) {
private var jsonRpcRequestsJob: Job? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,30 @@ import com.walletconnect.foundation.util.Logger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

interface InsertEventUseCaseInterface {
suspend operator fun invoke(props: Props)
}

class InsertTelemetryEventUseCase(
private val eventsRepository: EventsRepository,
private val logger: Logger
) : InsertEventUseCaseInterface {
override suspend operator fun invoke(props: Props) {
withContext(Dispatchers.IO) {
try {
eventsRepository.insertOrAbortTelemetry(props)
} catch (e: Exception) {
logger.error("Inserting event ${props.type} error: $e")
}
}
}
}

class InsertEventUseCase(
private val eventsRepository: EventsRepository,
private val logger: Logger
) {
suspend operator fun invoke(props: Props) {
) : InsertEventUseCaseInterface {
override suspend operator fun invoke(props: Props) {
withContext(Dispatchers.IO) {
try {
eventsRepository.insertOrAbort(props)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.walletconnect.android.pulse.domain
import com.walletconnect.android.internal.common.model.TelemetryEnabled
import com.walletconnect.android.internal.common.storage.events.EventsRepository
import com.walletconnect.android.pulse.data.PulseService
import com.walletconnect.android.pulse.model.Event
import com.walletconnect.android.pulse.model.SDKType
import com.walletconnect.foundation.util.Logger
import kotlinx.coroutines.Dispatchers
Expand All @@ -16,33 +17,39 @@ class SendBatchEventUseCase(
) {
suspend operator fun invoke() = withContext(Dispatchers.IO) {
if (telemetryEnabled.value) {
var continueProcessing = true
while (continueProcessing) {
val events = eventsRepository.getAllWithLimitAndOffset(LIMIT, 0)
if (events.isNotEmpty()) {
try {
logger.log("Sending batch events: ${events.size}")
val response = pulseService.sendEventBatch(body = events, sdkType = SDKType.EVENTS.type)
if (response.isSuccessful) {
eventsRepository.deleteByIds(events.map { it.eventId })
} else {
logger.log("Failed to send events: ${events.size}")
continueProcessing = false
}
} catch (e: Exception) {
logger.error("Error sending batch events: ${e.message}")
continueProcessing = false
}
} else {
continueProcessing = false
}
}
sendEventsInBatches { eventsRepository.getAllEventsWithLimitAndOffset(LIMIT, 0) }
} else {
try {
eventsRepository.deleteAll()
eventsRepository.deleteAllTelemetry()
} catch (e: Exception) {
logger.error("Failed to delete events, error: $e")
}

sendEventsInBatches { eventsRepository.getAllNonTelemetryEventsWithLimitAndOffset(LIMIT, 0) }
}
}

private suspend fun sendEventsInBatches(getEvents: suspend () -> List<Event>) {
var continueProcessing = true
while (continueProcessing) {
val events = getEvents()
if (events.isNotEmpty()) {
try {
logger.log("Sending batch events: ${events.size}")
val response = pulseService.sendEventBatch(body = events, sdkType = SDKType.EVENTS.type)
if (response.isSuccessful) {
eventsRepository.deleteByIds(events.map { it.eventId })
} else {
logger.log("Failed to send events: ${events.size}")
continueProcessing = false
}
} catch (e: Exception) {
logger.error("Error sending batch events: ${e.message}")
continueProcessing = false
}
} else {
continueProcessing = false
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.walletconnect.android.pulse.model

enum class Direction(val state: String) {
SENT("sent"),
RECEIVED("received")
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.walletconnect.android.pulse.model
object EventType {
@get:JvmSynthetic
const val ERROR: String = "ERROR"
@get:JvmSynthetic
const val SUCCESS: String = "SUCCESS"

@get:JvmSynthetic
const val TRACK: String = "TRACE"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ data class Properties(
val trace: List<String>? = null,
@Json(name = "topic")
val topic: String? = null,
)
@Json(name = "correlation_id")
val correlationId: Long? = null,
@Json(name = "client_id")
val clientId: String? = null,
@Json(name = "direction")
val direction: String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,4 @@ interface PushInterface {
fun register(firebaseAccessToken: String, enableEncrypted: Boolean = false, onSuccess: () -> Unit, onError: (Throwable) -> Unit)

fun unregister(onSuccess: () -> Unit, onError: (Throwable) -> Unit)

companion object {

@JvmSynthetic
internal const val KEY_CLIENT_ID = "clientId"
}
}
Loading

0 comments on commit 97c9c07

Please sign in to comment.