- Removed unused code from Worker.
- Used Mutex lock as synchronized doesnt work well with suspend
This commit is contained in:
@@ -25,7 +25,6 @@ import com.naviapp.payment.razorpay.RazorpayPayment
|
||||
import com.naviapp.registration.SplashActivity
|
||||
import com.naviapp.utils.USER_EXTERNAL_ID
|
||||
import com.naviapp.utils.getAppName
|
||||
import java.lang.Exception
|
||||
|
||||
/**
|
||||
* Helper class to initialize and set user data in SDKs
|
||||
@@ -47,7 +46,9 @@ object NaviSDKHelper {
|
||||
BuildConfig.VERSION_NAME,
|
||||
BuildConfig.VERSION_CODE.toString()
|
||||
),
|
||||
appsFlyerKey = BuildConfig.APPSFLYER_KEY),
|
||||
appsFlyerKey = BuildConfig.APPSFLYER_KEY,
|
||||
flavor = BuildConfig.FLAVOR
|
||||
),
|
||||
inAppOptOutScreens
|
||||
)
|
||||
HyperSnapSDK.init(
|
||||
|
||||
@@ -3,7 +3,8 @@ package com.navi.analytics.model
|
||||
data class AnalyticsConfiguration(
|
||||
val appsFlyerKey: String,
|
||||
val moengageData: MoengageData,
|
||||
val appInfo: AppInfo
|
||||
val appInfo: AppInfo,
|
||||
val flavor:String
|
||||
)
|
||||
|
||||
data class MoengageData(
|
||||
|
||||
@@ -40,9 +40,11 @@ object NaviTrackEvent {
|
||||
.setAppName(analyticsConfiguration.appInfo.appName)
|
||||
.setAppVersion(analyticsConfiguration.appInfo.appVersionCode)
|
||||
.setAppVersionName(analyticsConfiguration.appInfo.appVersionName)
|
||||
.setFlavor(analyticsConfiguration.flavor)
|
||||
.build()
|
||||
PulseHelper.init(pulseConfig, appContext)
|
||||
FirebaseCrashlytics.getInstance().setCustomKey(FIELD_DEVICE_ID, PulseSDKConfig.getDeviceId())
|
||||
FirebaseCrashlytics.getInstance()
|
||||
.setCustomKey(FIELD_DEVICE_ID, PulseSDKConfig.getDeviceId())
|
||||
}
|
||||
|
||||
fun startScreen(screenName: String?, isNeededForAppsflyer: Boolean = true) {
|
||||
|
||||
@@ -12,8 +12,8 @@ object PulseHelper {
|
||||
|
||||
fun init(sdkConfig: PulseSDKConfig.Configuration, context: Context) {
|
||||
applicationContext = context
|
||||
PulseRetrofitProvider.init(applicationContext)
|
||||
PulseSDKConfig.init(context, sdkConfig)
|
||||
PulseRetrofitProvider.init(applicationContext)
|
||||
PulseEventManager.startSyncEvents(context)
|
||||
trackEvent("pulse_sdk_init")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.navi.pulse
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.text.TextUtils
|
||||
import com.navi.pulse.util.PulseConstants
|
||||
import com.navi.pulse.util.PulseConstants.OS_ANDROID
|
||||
import com.navi.pulse.util.PulseDeviceUtils
|
||||
@@ -26,7 +27,8 @@ object PulseSDKConfig {
|
||||
val appVersion: String,
|
||||
val appVersionName: String,
|
||||
val eventBatchSize: Int,
|
||||
val eventDelayInSeconds: Int
|
||||
val eventDelayInSeconds: Int,
|
||||
val flavor: String,
|
||||
) {
|
||||
class Builder {
|
||||
private var appName: String = ""
|
||||
@@ -34,11 +36,15 @@ object PulseSDKConfig {
|
||||
private var appVersionName: String = ""
|
||||
private var eventBatchSize: Int = PulseConstants.DEFAULT_EVENT_BATCH_SIZE
|
||||
private var eventDelayInSeconds: Int = PulseConstants.DEFAULT_EVENT_DELAY_IN_SECONDS
|
||||
private var flavor: String = PulseConstants.PROD
|
||||
fun setAppName(appName: String) = apply { this.appName = appName }
|
||||
fun setAppVersion(appVersion: String) = apply { this.appVersion = appVersion }
|
||||
fun setAppVersionName(appVersionName: String) =
|
||||
apply { this.appVersionName = appVersionName }
|
||||
|
||||
fun setFlavor(flavor: String) =
|
||||
apply { this.flavor = flavor }
|
||||
|
||||
fun setEventBatchSize(eventBatchSize: Int) =
|
||||
apply { this.eventBatchSize = eventBatchSize }
|
||||
|
||||
@@ -53,7 +59,8 @@ object PulseSDKConfig {
|
||||
appVersion,
|
||||
appVersionName,
|
||||
eventBatchSize,
|
||||
eventDelayInSeconds
|
||||
eventDelayInSeconds,
|
||||
flavor
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -146,4 +153,8 @@ object PulseSDKConfig {
|
||||
fun getAppVersionName(): String {
|
||||
return configuration.appVersionName
|
||||
}
|
||||
|
||||
fun isProd(): Boolean {
|
||||
return TextUtils.equals(configuration.flavor, PulseConstants.PROD)
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@ import com.navi.pulse.util.PulseUtils
|
||||
import com.navi.pulse.worker.SyncEventsWorker
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import java.lang.reflect.Type
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
@@ -31,6 +33,8 @@ import kotlin.concurrent.fixedRateTimer
|
||||
object PulseEventManager {
|
||||
private val coroutineDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
private var timer: Timer? = null
|
||||
private val pulseNetworkRepository = PulseNetworkRepository()
|
||||
private val mutex = Mutex()
|
||||
|
||||
fun trackEvent(
|
||||
eventName: String,
|
||||
@@ -53,69 +57,67 @@ object PulseEventManager {
|
||||
PulseSDKConfig.getEventsDelayInMilliseconds()
|
||||
) {
|
||||
runBlocking {
|
||||
AddEventTask.resetEventCount()
|
||||
sendEventsToServer(applicationContext, TIMER_THREAD_NAME)
|
||||
}
|
||||
}
|
||||
startPeriodicSyncTask(applicationContext)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
suspend fun sendEventsToServer(applicationContext: Context, source:String?): Boolean {
|
||||
PulseLogger.log(
|
||||
LOG_TAG,
|
||||
"Sync started !"
|
||||
)
|
||||
PulseLogger.log(
|
||||
LOG_TAG,
|
||||
"in sendEventsToServer Thread Name " + Thread.currentThread().name
|
||||
)
|
||||
val db = PulseDatabaseHelper.getPulseDatabase(applicationContext)
|
||||
val pulseDAO = db.pulseDao()
|
||||
val pulseEvents = pulseDAO.fetchEvents(PulseSDKConfig.getEventBatchSize())
|
||||
if (!pulseEvents.isNullOrEmpty()) {
|
||||
try {
|
||||
val detailsList = pulseEvents.map { it.details }
|
||||
val listType: Type = object : TypeToken<ArrayList<EventData?>?>() {}.type
|
||||
val events: ArrayList<EventData> =
|
||||
Gson().fromJson(detailsList.toString(), listType)
|
||||
val pulseRequest =
|
||||
PulseRequest(
|
||||
events = events,
|
||||
batchTimeStamp = System.currentTimeMillis().toString(),
|
||||
source = source
|
||||
suspend fun sendEventsToServer(applicationContext: Context, source: String?): Boolean {
|
||||
mutex.withLock {
|
||||
PulseLogger.log(
|
||||
LOG_TAG,
|
||||
"Sync started !"
|
||||
)
|
||||
PulseLogger.log(
|
||||
LOG_TAG,
|
||||
"in sendEventsToServer Thread Name " + Thread.currentThread().name
|
||||
)
|
||||
val db = PulseDatabaseHelper.getPulseDatabase(applicationContext)
|
||||
val pulseDAO = db.pulseDao()
|
||||
val pulseEvents = pulseDAO.fetchEvents(PulseSDKConfig.getEventBatchSize())
|
||||
if (!pulseEvents.isNullOrEmpty()) {
|
||||
try {
|
||||
val detailsList = pulseEvents.map { it.details }
|
||||
val listType: Type = object : TypeToken<ArrayList<EventData?>?>() {}.type
|
||||
val events: ArrayList<EventData> =
|
||||
Gson().fromJson(detailsList.toString(), listType)
|
||||
val pulseRequest =
|
||||
PulseRequest(
|
||||
events = events,
|
||||
batchTimeStamp = System.currentTimeMillis().toString(),
|
||||
source = source
|
||||
)
|
||||
PulseLogger.log(LOG_TAG, "Event payload ready")
|
||||
val response = pulseNetworkRepository.sendEvents(
|
||||
PulseSDKConfig.getPostUrl(),
|
||||
pulseRequest
|
||||
)
|
||||
PulseLogger.log(LOG_TAG, "Event payload ready")
|
||||
val response = PulseNetworkRepository().sendEvents(
|
||||
PulseSDKConfig.getPostUrl(),
|
||||
pulseRequest
|
||||
)
|
||||
PulseLogger.log(LOG_TAG, pulseRequest.toString())
|
||||
PulseLogger.log(LOG_TAG, "Event Batch Size -> " + pulseEvents.size)
|
||||
return if (response.isSuccessful && response.body()?.code == CODE_API_SUCCESS) {
|
||||
pulseDAO.deleteEvents(pulseEvents.map { it.eventId })
|
||||
PulseLogger.log(LOG_TAG, "Events Batch Sent and Deleted from DB")
|
||||
true
|
||||
} else {
|
||||
PulseLogger.log(
|
||||
LOG_TAG,
|
||||
"Events Batch Failed ! Reason - " + response.body()?.message
|
||||
)
|
||||
false
|
||||
PulseLogger.log(LOG_TAG, pulseRequest.toString())
|
||||
PulseLogger.log(LOG_TAG, "Event Batch Size -> " + pulseEvents.size)
|
||||
return if (response.isSuccessful && response.body()?.code == CODE_API_SUCCESS) {
|
||||
pulseDAO.deleteEvents(pulseEvents.map { it.eventId })
|
||||
PulseLogger.log(LOG_TAG, "Events Batch Sent and Deleted from DB")
|
||||
true
|
||||
} else {
|
||||
PulseLogger.log(
|
||||
LOG_TAG,
|
||||
"Events Batch Failed ! Reason - " + response.body()?.message
|
||||
)
|
||||
false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
PulseLogger.log(LOG_TAG, "Error in Sending Data" + e.message)
|
||||
return false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
PulseLogger.log(LOG_TAG, "Error in Sending Data" + e.message)
|
||||
} else {
|
||||
PulseLogger.log(LOG_TAG, "No More Events to Send !")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
PulseLogger.log(LOG_TAG, "No More Events to Send !")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
fun isSyncTimerRunning(): Boolean {
|
||||
return timer != null
|
||||
}
|
||||
|
||||
private fun startPeriodicSyncTask(
|
||||
applicationContext: Context
|
||||
) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.navi.pulse.network
|
||||
|
||||
import android.content.Context
|
||||
import com.navi.pulse.BuildConfig
|
||||
import com.navi.pulse.PulseSDKConfig
|
||||
import com.readystatesoftware.chuck.ChuckInterceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
@@ -29,7 +29,7 @@ object PulseRetrofitProvider {
|
||||
}
|
||||
|
||||
private fun getRetrofit(): Retrofit {
|
||||
val baseUrl = if (BuildConfig.DEBUG) BASE_URL_DEBUG else BASE_URL_PROD
|
||||
val baseUrl = if (PulseSDKConfig.isProd()) BASE_URL_PROD else BASE_URL_DEBUG
|
||||
return Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
|
||||
@@ -16,11 +16,14 @@ class AddEventTask(
|
||||
) : PulseTask {
|
||||
companion object {
|
||||
private var eventCount: AtomicInteger = AtomicInteger(0)
|
||||
fun resetEventCount() {
|
||||
eventCount = AtomicInteger(0)
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun execute(): Boolean {
|
||||
val db = PulseDatabaseHelper.getPulseDatabase(context)
|
||||
val db = PulseDatabaseHelper.getPulseDatabase(context)
|
||||
val pulseDAO = db.pulseDao()
|
||||
return try {
|
||||
pulseDAO.insertEvent(event)
|
||||
@@ -37,7 +40,11 @@ class AddEventTask(
|
||||
|
||||
private fun checkIfSyncIsNeeded() {
|
||||
if (eventCount.get() >= PulseSDKConfig.getEventBatchSize()) {
|
||||
eventCount = AtomicInteger(0)
|
||||
PulseLogger.log(
|
||||
PulseConstants.LOG_TAG,
|
||||
"Event Count greater than Threshold - " + eventCount.get()
|
||||
)
|
||||
resetEventCount()
|
||||
PulseLogger.log(
|
||||
PulseConstants.LOG_TAG,
|
||||
"Inside checkIfSyncIsNeeded - ".plus(Thread.currentThread().name)
|
||||
|
||||
@@ -23,6 +23,6 @@ class SyncEventTask(private val context: Context) : PulseTask {
|
||||
}
|
||||
|
||||
override fun getTaskName(): String {
|
||||
return PulseConstants.SYNC_EVENT_TASK
|
||||
return SYNC_EVENT_TASK
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,4 +16,5 @@ object PulseConstants {
|
||||
const val REPEAT_INTERVAL_WORKER = 6L
|
||||
const val EVENT_DB_NAME = "navi-pulse"
|
||||
const val FIELD_DEVICE_ID = "device_id"
|
||||
const val PROD = "prod"
|
||||
}
|
||||
@@ -4,25 +4,16 @@ import android.content.Context
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.navi.pulse.event.PulseEventManager
|
||||
import com.navi.pulse.util.PulseConstants
|
||||
import com.navi.pulse.util.PulseConstants.SYNC_EVENTS_WORKER
|
||||
import com.navi.pulse.util.PulseLogger
|
||||
|
||||
/**
|
||||
* This Worker's only job is to wake up the app,
|
||||
* which in turn wakes up the sync process @see PulseEventManager.startSyncEvents
|
||||
*/
|
||||
class SyncEventsWorker(val context: Context, workerParameters: WorkerParameters) :
|
||||
CoroutineWorker(context, workerParameters) {
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
PulseEventManager.trackEvent("heartbeat", null, context)
|
||||
if (PulseEventManager.isSyncTimerRunning()) {
|
||||
PulseLogger.log(PulseConstants.LOG_TAG, "Cancelling Worker as Timer is already running")
|
||||
return Result.failure()
|
||||
}
|
||||
// This code doesn't work as Worker starts the Sync Timer and above check returns from worker.
|
||||
PulseEventManager.trackEvent("worker_worked", null, context)
|
||||
PulseLogger.log(PulseConstants.LOG_TAG, "In doWork() of SyncEventsWorker")
|
||||
PulseLogger.log(PulseConstants.LOG_TAG, Thread.currentThread().name)
|
||||
val eventsSent = PulseEventManager.sendEventsToServer(context, SYNC_EVENTS_WORKER)
|
||||
return if (eventsSent) Result.success()
|
||||
else Result.failure()
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user