[API/Mobidziennik] Fix too much clearing grades from DB. Add performance debugging to Data and ApiService.

This commit is contained in:
Kuba Szczodrzyński 2020-02-19 16:38:11 +01:00
parent 626bbfa7a4
commit f0447dc455
5 changed files with 50 additions and 21 deletions

View File

@ -54,6 +54,7 @@ class ApiService : Service() {
private var taskIsRunning = false
private var taskRunning: IApiTask? = null // for debug purposes
private var taskRunningId = -1
private var taskStartTime = 0L
private var taskMaximumId = 0
private var taskProfileId = -1
@ -74,7 +75,7 @@ class ApiService : Service() {
private val taskCallback = object : EdziennikCallback {
override fun onCompleted() {
lastEventTime = System.currentTimeMillis()
d(TAG, "Task $taskRunningId (profile $taskProfileId) - $taskProgressText - finished")
d(TAG, "Task $taskRunningId (profile $taskProfileId) finished in ${System.currentTimeMillis()-taskStartTime}")
EventBus.getDefault().postSticky(ApiTaskFinishedEvent(taskProfileId))
clearTask()
@ -162,7 +163,7 @@ class ApiService : Service() {
taskProgress = -1f
taskProgressText = task.taskName
d(TAG, "Executing task $taskRunningId ($taskProgressText) - $task")
d(TAG, "Executing task $taskRunningId - ${task::class.java.name}")
// update the notification
notification.setCurrentTask(taskRunningId, taskProgressText).post()
@ -172,6 +173,7 @@ class ApiService : Service() {
task.profile?.let { syncingProfiles.add(it) }
taskStartTime = System.currentTimeMillis()
try {
when (task) {
is EdziennikTask -> task.run(app, taskCallback)

View File

@ -74,17 +74,6 @@ class MobidziennikApiGrades(val data: DataMobidziennik, rows: List<String>) {
subjectId)
gradeObject.type = type
data.toRemove.addAll(listOf(
TYPE_NORMAL,
TYPE_SEMESTER1_FINAL,
TYPE_SEMESTER2_FINAL,
TYPE_SEMESTER1_PROPOSED,
TYPE_SEMESTER2_PROPOSED,
TYPE_YEAR_FINAL,
TYPE_YEAR_PROPOSED
).map {
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
})
data.gradeList.add(gradeObject)
data.metadataList.add(
Metadata(
@ -97,5 +86,16 @@ class MobidziennikApiGrades(val data: DataMobidziennik, rows: List<String>) {
))
addedDate++
}
data.toRemove.addAll(listOf(
TYPE_NORMAL,
TYPE_SEMESTER1_FINAL,
TYPE_SEMESTER2_FINAL,
TYPE_SEMESTER1_PROPOSED,
TYPE_SEMESTER2_PROPOSED,
TYPE_YEAR_FINAL,
TYPE_YEAR_PROPOSED
).map {
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
})
}}}
}

View File

@ -10,7 +10,6 @@ import pl.szczodrzynski.edziennik.data.api.Regexes
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_GRADES
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Grade
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
@ -148,7 +147,6 @@ class MobidziennikWebGrades(override val data: DataMobidziennik,
}
}
data.toRemove.add(DataRemoveModel.Grades.semesterWithType(currentSemester, Grade.TYPE_NORMAL))
data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_GRADES)
}

View File

@ -11,12 +11,13 @@ import pl.szczodrzynski.edziennik.data.api.ERROR_REQUEST_FAILURE
import pl.szczodrzynski.edziennik.data.api.interfaces.EndpointCallback
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.*
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date
abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) {
companion object {
private const val TAG = "Data"
private val DEBUG = true && BuildConfig.DEBUG
}
var fakeLogin = false
@ -148,6 +149,11 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
}
}
private fun d(message: String) {
if (DEBUG)
Utils.d(TAG, message)
}
fun clear() {
loginMethods.clear()
@ -185,13 +191,16 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
open fun saveData() {
if (profile == null)
return // return on first login
val totalStart = System.currentTimeMillis()
var startTime = System.currentTimeMillis()
d("Saving data to DB")
profile.userCode = generateUserCode()
db.profileDao().add(profile)
db.loginStoreDao().add(loginStore)
if (profile.id == app.profile?.id) {
if (profile.id == app.profile.id) {
app.profile.apply {
name = profile.name
subname = profile.subname
@ -209,6 +218,9 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
}
}
d("Profiles saved in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis()
// always present and not empty, during every sync
db.endpointTimerDao().addAll(endpointTimers)
if (teacherOnConflictStrategy == OnConflictStrategy.IGNORE)
@ -223,6 +235,9 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
db.gradeCategoryDao().clear(profileId)
db.gradeCategoryDao().addAll(gradeCategories.values())
d("Maps saved in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis()
// may be empty - extracted from DB on demand, by an endpoint
if (classrooms.size > 0)
db.classroomDao().addAll(classrooms.values())
@ -237,8 +252,12 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
if (librusLessons.size > 0)
db.librusLessonDao().addAll(librusLessons.values())
d("On-demand maps saved in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis()
// clear DB with DataRemoveModels added by endpoints
for (model in toRemove) {
d("Clearing DB with $model")
when (model) {
is DataRemoveModel.Timetable -> model.commit(profileId, db.timetableDao())
is DataRemoveModel.Grades -> model.commit(profileId, db.gradeDao())
@ -246,11 +265,17 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
}
}
d("DB cleared in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis()
if (metadataList.isNotEmpty())
db.metadataDao().addAllIgnore(metadataList)
if (setSeenMetadataList.isNotEmpty())
db.metadataDao().setSeen(setSeenMetadataList)
d("Metadata saved in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis()
if (lessonList.isNotEmpty()) {
db.timetableDao() += lessonList
}
@ -283,6 +308,10 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
db.messageRecipientDao().addAll(messageRecipientList)
if (messageRecipientIgnoreList.isNotEmpty())
db.messageRecipientDao().addAllIgnore(messageRecipientIgnoreList)
d("Other data saved in ${System.currentTimeMillis()-startTime} ms")
d("Total save time: ${System.currentTimeMillis()-totalStart} ms")
}
fun setSyncNext(endpointId: Int, syncIn: Long? = null, viewId: Int? = null, syncAt: Long? = null) {
@ -309,7 +338,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
abstract fun generateUserCode(): String
fun cancel() {
d("Data", "Cancelled")
d("Cancelled")
cancelled = true
saveData()
}

View File

@ -10,7 +10,7 @@ import pl.szczodrzynski.edziennik.data.db.dao.TimetableDao
import pl.szczodrzynski.edziennik.utils.models.Date
open class DataRemoveModel {
class Timetable(private val dateFrom: Date?, private val dateTo: Date?) : DataRemoveModel() {
data class Timetable(private val dateFrom: Date?, private val dateTo: Date?) : DataRemoveModel() {
companion object {
fun from(dateFrom: Date) = Timetable(dateFrom, null)
fun to(dateTo: Date) = Timetable(null, dateTo)
@ -27,7 +27,7 @@ open class DataRemoveModel {
}
}
class Grades(private val all: Boolean, private val semester: Int?, private val type: Int?) : DataRemoveModel() {
data class Grades(private val all: Boolean, private val semester: Int?, private val type: Int?) : DataRemoveModel() {
companion object {
fun all() = Grades(true, null, null)
fun allWithType(type: Int) = Grades(true, null, type)
@ -47,7 +47,7 @@ open class DataRemoveModel {
}
}
class Events(private val type: Long?, private val exceptType: Long?, private val exceptTypes: List<Long>?) : DataRemoveModel() {
data class Events(private val type: Long?, private val exceptType: Long?, private val exceptTypes: List<Long>?) : DataRemoveModel() {
companion object {
fun futureExceptType(exceptType: Long) = Events(null, exceptType, null)
fun futureExceptTypes(exceptTypes: List<Long>) = Events(null, null, exceptTypes)