mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 00:59:49 +01:00
Remove cases where all jobs were expected to be in memory.
This commit is contained in:
committed by
Nicholas Tinsley
parent
973dc72cfa
commit
86cf8200b5
@@ -8,8 +8,10 @@ import androidx.core.content.contentValuesOf
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase
|
||||
import net.zetetic.database.sqlcipher.SQLiteOpenHelper
|
||||
import org.signal.core.util.CursorUtil
|
||||
import org.signal.core.util.SqlUtil
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.signal.core.util.delete
|
||||
import org.signal.core.util.forEach
|
||||
import org.signal.core.util.insertInto
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.readToList
|
||||
@@ -31,6 +33,7 @@ import org.thoughtcrime.securesms.jobmanager.persistence.DependencySpec
|
||||
import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec
|
||||
import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec
|
||||
import org.thoughtcrime.securesms.jobs.MinimalJobSpec
|
||||
import java.util.function.Predicate
|
||||
|
||||
class JobDatabase(
|
||||
application: Application,
|
||||
@@ -184,28 +187,32 @@ class JobDatabase(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun getAllJobSpecs(): List<JobSpec> {
|
||||
return readableDatabase
|
||||
.select()
|
||||
.from(Jobs.TABLE_NAME)
|
||||
.orderBy("${Jobs.CREATE_TIME}, ${Jobs.ID} ASC")
|
||||
.run()
|
||||
.readToList { cursor ->
|
||||
jobSpecFromCursor(cursor)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun getOldestJobSpecs(limit: Int): List<JobSpec> {
|
||||
fun getJobSpecs(limit: Int): List<JobSpec> {
|
||||
return readableDatabase
|
||||
.select()
|
||||
.from(Jobs.TABLE_NAME)
|
||||
.orderBy("${Jobs.CREATE_TIME}, ${Jobs.ID} ASC")
|
||||
.limit(limit)
|
||||
.run()
|
||||
.readToList { it.toJobSpec() }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun getAllMatchingFilter(predicate: Predicate<JobSpec>): List<JobSpec> {
|
||||
val output: MutableList<JobSpec> = mutableListOf()
|
||||
|
||||
readableDatabase
|
||||
.select()
|
||||
.from(Jobs.TABLE_NAME)
|
||||
.run()
|
||||
.readToList { cursor ->
|
||||
jobSpecFromCursor(cursor)
|
||||
val jobSpec = cursor.toJobSpec()
|
||||
if (predicate.test(jobSpec)) {
|
||||
output += jobSpec
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -215,9 +222,7 @@ class JobDatabase(
|
||||
.from(Jobs.TABLE_NAME)
|
||||
.where("${Jobs.JOB_SPEC_ID} = ?", id)
|
||||
.run()
|
||||
.readToSingleObject {
|
||||
jobSpecFromCursor(it)
|
||||
}
|
||||
.readToSingleObject { it.toJobSpec() }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -296,26 +301,41 @@ class JobDatabase(
|
||||
.filterNot { it.isMemoryOnly }
|
||||
.forEach { job ->
|
||||
db.update(Jobs.TABLE_NAME)
|
||||
.values(
|
||||
Jobs.JOB_SPEC_ID to job.id,
|
||||
Jobs.FACTORY_KEY to job.factoryKey,
|
||||
Jobs.QUEUE_KEY to job.queueKey,
|
||||
Jobs.CREATE_TIME to job.createTime,
|
||||
Jobs.LAST_RUN_ATTEMPT_TIME to job.lastRunAttemptTime,
|
||||
Jobs.NEXT_BACKOFF_INTERVAL to job.nextBackoffInterval,
|
||||
Jobs.RUN_ATTEMPT to job.runAttempt,
|
||||
Jobs.MAX_ATTEMPTS to job.maxAttempts,
|
||||
Jobs.LIFESPAN to job.lifespan,
|
||||
Jobs.SERIALIZED_DATA to job.serializedData,
|
||||
Jobs.SERIALIZED_INPUT_DATA to job.serializedInputData,
|
||||
Jobs.IS_RUNNING to if (job.isRunning) 1 else 0
|
||||
)
|
||||
.values(job.toContentValues())
|
||||
.where("${Jobs.JOB_SPEC_ID} = ?", job.id)
|
||||
.run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun transformJobs(transformer: (JobSpec) -> JobSpec): List<JobSpec> {
|
||||
val transformed: MutableList<JobSpec> = mutableListOf()
|
||||
|
||||
writableDatabase.withinTransaction { db ->
|
||||
readableDatabase
|
||||
.select()
|
||||
.from(Jobs.TABLE_NAME)
|
||||
.run()
|
||||
.forEach { cursor ->
|
||||
val jobSpec = cursor.toJobSpec()
|
||||
val updated = transformer(jobSpec)
|
||||
if (updated != jobSpec) {
|
||||
transformed += updated
|
||||
}
|
||||
}
|
||||
|
||||
for (job in transformed) {
|
||||
db.update(Jobs.TABLE_NAME)
|
||||
.values(job.toContentValues())
|
||||
.where("${Jobs.JOB_SPEC_ID} = ?", job.id)
|
||||
.run()
|
||||
}
|
||||
}
|
||||
|
||||
return transformed
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun deleteJobs(jobIds: List<String>) {
|
||||
writableDatabase.withinTransaction { db ->
|
||||
@@ -340,14 +360,30 @@ class JobDatabase(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun getAllConstraintSpecs(): List<ConstraintSpec> {
|
||||
fun getConstraintSpecs(limit: Int): List<ConstraintSpec> {
|
||||
return readableDatabase
|
||||
.select()
|
||||
.from(Constraints.TABLE_NAME)
|
||||
.limit(limit)
|
||||
.run()
|
||||
.readToList { cursor ->
|
||||
constraintSpecFromCursor(cursor)
|
||||
}
|
||||
.readToList { it.toConstraintSpec() }
|
||||
}
|
||||
|
||||
fun getConstraintSpecsForJobs(jobIds: Collection<String>): List<ConstraintSpec> {
|
||||
val output: MutableList<ConstraintSpec> = mutableListOf()
|
||||
|
||||
for (query in SqlUtil.buildCollectionQuery(Constraints.JOB_SPEC_ID, jobIds)) {
|
||||
readableDatabase
|
||||
.select()
|
||||
.from(Constraints.TABLE_NAME)
|
||||
.where(query.where, query.whereArgs)
|
||||
.run()
|
||||
.forEach {
|
||||
output += it.toConstraintSpec()
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -356,9 +392,7 @@ class JobDatabase(
|
||||
.select()
|
||||
.from(Dependencies.TABLE_NAME)
|
||||
.run()
|
||||
.readToList { cursor ->
|
||||
dependencySpecFromCursor(cursor)
|
||||
}
|
||||
.readToList { it.toDependencySpec() }
|
||||
}
|
||||
|
||||
private fun insertJobSpec(db: SQLiteDatabase, job: JobSpec) {
|
||||
@@ -369,21 +403,7 @@ class JobDatabase(
|
||||
check(db.inTransaction())
|
||||
|
||||
db.insertInto(Jobs.TABLE_NAME)
|
||||
.values(
|
||||
Jobs.JOB_SPEC_ID to job.id,
|
||||
Jobs.FACTORY_KEY to job.factoryKey,
|
||||
Jobs.QUEUE_KEY to job.queueKey,
|
||||
Jobs.CREATE_TIME to job.createTime,
|
||||
Jobs.LAST_RUN_ATTEMPT_TIME to job.lastRunAttemptTime,
|
||||
Jobs.NEXT_BACKOFF_INTERVAL to job.nextBackoffInterval,
|
||||
Jobs.RUN_ATTEMPT to job.runAttempt,
|
||||
Jobs.MAX_ATTEMPTS to job.maxAttempts,
|
||||
Jobs.LIFESPAN to job.lifespan,
|
||||
Jobs.SERIALIZED_DATA to job.serializedData,
|
||||
Jobs.SERIALIZED_INPUT_DATA to job.serializedInputData,
|
||||
Jobs.IS_RUNNING to if (job.isRunning) 1 else 0,
|
||||
Jobs.PRIORITY to job.priority
|
||||
)
|
||||
.values(job.toContentValues())
|
||||
.run(SQLiteDatabase.CONFLICT_IGNORE)
|
||||
}
|
||||
|
||||
@@ -417,37 +437,37 @@ class JobDatabase(
|
||||
}
|
||||
}
|
||||
|
||||
private fun jobSpecFromCursor(cursor: Cursor): JobSpec {
|
||||
private fun Cursor.toJobSpec(): JobSpec {
|
||||
return JobSpec(
|
||||
id = cursor.requireNonNullString(Jobs.JOB_SPEC_ID),
|
||||
factoryKey = cursor.requireNonNullString(Jobs.FACTORY_KEY),
|
||||
queueKey = cursor.requireString(Jobs.QUEUE_KEY),
|
||||
createTime = cursor.requireLong(Jobs.CREATE_TIME),
|
||||
lastRunAttemptTime = cursor.requireLong(Jobs.LAST_RUN_ATTEMPT_TIME),
|
||||
nextBackoffInterval = cursor.requireLong(Jobs.NEXT_BACKOFF_INTERVAL),
|
||||
runAttempt = cursor.requireInt(Jobs.RUN_ATTEMPT),
|
||||
maxAttempts = cursor.requireInt(Jobs.MAX_ATTEMPTS),
|
||||
lifespan = cursor.requireLong(Jobs.LIFESPAN),
|
||||
serializedData = cursor.requireBlob(Jobs.SERIALIZED_DATA),
|
||||
serializedInputData = cursor.requireBlob(Jobs.SERIALIZED_INPUT_DATA),
|
||||
isRunning = cursor.requireBoolean(Jobs.IS_RUNNING),
|
||||
id = this.requireNonNullString(Jobs.JOB_SPEC_ID),
|
||||
factoryKey = this.requireNonNullString(Jobs.FACTORY_KEY),
|
||||
queueKey = this.requireString(Jobs.QUEUE_KEY),
|
||||
createTime = this.requireLong(Jobs.CREATE_TIME),
|
||||
lastRunAttemptTime = this.requireLong(Jobs.LAST_RUN_ATTEMPT_TIME),
|
||||
nextBackoffInterval = this.requireLong(Jobs.NEXT_BACKOFF_INTERVAL),
|
||||
runAttempt = this.requireInt(Jobs.RUN_ATTEMPT),
|
||||
maxAttempts = this.requireInt(Jobs.MAX_ATTEMPTS),
|
||||
lifespan = this.requireLong(Jobs.LIFESPAN),
|
||||
serializedData = this.requireBlob(Jobs.SERIALIZED_DATA),
|
||||
serializedInputData = this.requireBlob(Jobs.SERIALIZED_INPUT_DATA),
|
||||
isRunning = this.requireBoolean(Jobs.IS_RUNNING),
|
||||
isMemoryOnly = false,
|
||||
priority = cursor.requireInt(Jobs.PRIORITY)
|
||||
priority = this.requireInt(Jobs.PRIORITY)
|
||||
)
|
||||
}
|
||||
|
||||
private fun constraintSpecFromCursor(cursor: Cursor): ConstraintSpec {
|
||||
private fun Cursor.toConstraintSpec(): ConstraintSpec {
|
||||
return ConstraintSpec(
|
||||
jobSpecId = cursor.requireNonNullString(Constraints.JOB_SPEC_ID),
|
||||
factoryKey = cursor.requireNonNullString(Constraints.FACTORY_KEY),
|
||||
jobSpecId = this.requireNonNullString(Constraints.JOB_SPEC_ID),
|
||||
factoryKey = this.requireNonNullString(Constraints.FACTORY_KEY),
|
||||
isMemoryOnly = false
|
||||
)
|
||||
}
|
||||
|
||||
private fun dependencySpecFromCursor(cursor: Cursor): DependencySpec {
|
||||
private fun Cursor.toDependencySpec(): DependencySpec {
|
||||
return DependencySpec(
|
||||
jobId = cursor.requireNonNullString(Dependencies.JOB_SPEC_ID),
|
||||
dependsOnJobId = cursor.requireNonNullString(Dependencies.DEPENDS_ON_JOB_SPEC_ID),
|
||||
jobId = this.requireNonNullString(Dependencies.JOB_SPEC_ID),
|
||||
dependsOnJobId = this.requireNonNullString(Dependencies.DEPENDS_ON_JOB_SPEC_ID),
|
||||
isMemoryOnly = false
|
||||
)
|
||||
}
|
||||
@@ -468,6 +488,24 @@ class JobDatabase(
|
||||
writableDatabase.update(Jobs.TABLE_NAME, contentValuesOf(Jobs.NEXT_BACKOFF_INTERVAL to 0), null, null)
|
||||
}
|
||||
|
||||
private fun JobSpec.toContentValues(): ContentValues {
|
||||
return contentValuesOf(
|
||||
Jobs.JOB_SPEC_ID to this.id,
|
||||
Jobs.FACTORY_KEY to this.factoryKey,
|
||||
Jobs.QUEUE_KEY to this.queueKey,
|
||||
Jobs.CREATE_TIME to this.createTime,
|
||||
Jobs.LAST_RUN_ATTEMPT_TIME to this.lastRunAttemptTime,
|
||||
Jobs.NEXT_BACKOFF_INTERVAL to this.nextBackoffInterval,
|
||||
Jobs.RUN_ATTEMPT to this.runAttempt,
|
||||
Jobs.MAX_ATTEMPTS to this.maxAttempts,
|
||||
Jobs.LIFESPAN to this.lifespan,
|
||||
Jobs.SERIALIZED_DATA to this.serializedData,
|
||||
Jobs.SERIALIZED_INPUT_DATA to this.serializedInputData,
|
||||
Jobs.IS_RUNNING to if (this.isRunning) 1 else 0,
|
||||
Jobs.PRIORITY to this.priority
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(JobDatabase::class.java)
|
||||
private const val DATABASE_VERSION = 3
|
||||
|
||||
Reference in New Issue
Block a user