mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 10:20:25 +01:00
Add the concept of queuePriority to jobs.
This commit is contained in:
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.jobmanager;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
@@ -10,12 +11,15 @@ import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.BackoffUtil;
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
/**
|
||||
* A durable unit of work.
|
||||
*
|
||||
@@ -263,6 +267,9 @@ public abstract class Job {
|
||||
public static final long IMMORTAL = -1;
|
||||
public static final int UNLIMITED = -1;
|
||||
|
||||
@Retention(SOURCE)
|
||||
@IntDef({ PRIORITY_DEFAULT, PRIORITY_LOW, PRIORITY_HIGH})
|
||||
public @interface Priority{}
|
||||
public static final int PRIORITY_DEFAULT = 0;
|
||||
public static final int PRIORITY_HIGH = 1;
|
||||
public static final int PRIORITY_LOW = -1;
|
||||
@@ -277,7 +284,8 @@ public abstract class Job {
|
||||
private final List<String> constraintKeys;
|
||||
private final byte[] inputData;
|
||||
private final boolean memoryOnly;
|
||||
private final int priority;
|
||||
private final int globalPriority;
|
||||
private final int queuePriority;
|
||||
|
||||
private Parameters(@NonNull String id,
|
||||
long createTime,
|
||||
@@ -289,7 +297,8 @@ public abstract class Job {
|
||||
@NonNull List<String> constraintKeys,
|
||||
@Nullable byte[] inputData,
|
||||
boolean memoryOnly,
|
||||
int priority)
|
||||
int globalPriority,
|
||||
int queuePriority)
|
||||
{
|
||||
this.id = id;
|
||||
this.createTime = createTime;
|
||||
@@ -301,7 +310,8 @@ public abstract class Job {
|
||||
this.constraintKeys = constraintKeys;
|
||||
this.inputData = inputData;
|
||||
this.memoryOnly = memoryOnly;
|
||||
this.priority = priority;
|
||||
this.globalPriority = globalPriority;
|
||||
this.queuePriority = queuePriority;
|
||||
}
|
||||
|
||||
@NonNull String getId() {
|
||||
@@ -344,12 +354,16 @@ public abstract class Job {
|
||||
return memoryOnly;
|
||||
}
|
||||
|
||||
int getPriority() {
|
||||
return priority;
|
||||
int getGlobalPriority() {
|
||||
return globalPriority;
|
||||
}
|
||||
|
||||
int getQueuePriority() {
|
||||
return queuePriority;
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder(id, createTime, lifespan, maxAttempts, maxInstancesForFactory, maxInstancesForQueue, queue, constraintKeys, inputData, memoryOnly, priority);
|
||||
return new Builder(id, createTime, lifespan, maxAttempts, maxInstancesForFactory, maxInstancesForQueue, queue, constraintKeys, inputData, memoryOnly, globalPriority, queuePriority);
|
||||
}
|
||||
|
||||
|
||||
@@ -364,14 +378,15 @@ public abstract class Job {
|
||||
private List<String> constraintKeys;
|
||||
private byte[] inputData;
|
||||
private boolean memoryOnly;
|
||||
private int priority;
|
||||
private int globalPriority;
|
||||
private int queuePriority;
|
||||
|
||||
public Builder() {
|
||||
this(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
Builder(@NonNull String id) {
|
||||
this(id, System.currentTimeMillis(), IMMORTAL, 1, UNLIMITED, UNLIMITED, null, new LinkedList<>(), null, false, Parameters.PRIORITY_DEFAULT);
|
||||
this(id, System.currentTimeMillis(), IMMORTAL, 1, UNLIMITED, UNLIMITED, null, new LinkedList<>(), null, false, Parameters.PRIORITY_DEFAULT, Parameters.PRIORITY_DEFAULT);
|
||||
}
|
||||
|
||||
private Builder(@NonNull String id,
|
||||
@@ -384,7 +399,8 @@ public abstract class Job {
|
||||
@NonNull List<String> constraintKeys,
|
||||
@Nullable byte[] inputData,
|
||||
boolean memoryOnly,
|
||||
int priority)
|
||||
int globalPriority,
|
||||
int queuePriority)
|
||||
{
|
||||
this.id = id;
|
||||
this.createTime = createTime;
|
||||
@@ -396,7 +412,8 @@ public abstract class Job {
|
||||
this.constraintKeys = constraintKeys;
|
||||
this.inputData = inputData;
|
||||
this.memoryOnly = memoryOnly;
|
||||
this.priority = priority;
|
||||
this.globalPriority = globalPriority;
|
||||
this.queuePriority = queuePriority;
|
||||
}
|
||||
|
||||
/** Should only be invoked by {@link JobController} */
|
||||
@@ -491,7 +508,7 @@ public abstract class Job {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the job's priority. Higher numbers are higher priority. Use the constants {@link Parameters#PRIORITY_HIGH}, {@link Parameters#PRIORITY_LOW},
|
||||
* Sets the job's global priority. Higher numbers are higher priority. Use the constants {@link Parameters#PRIORITY_HIGH}, {@link Parameters#PRIORITY_LOW},
|
||||
* and {@link Parameters#PRIORITY_DEFAULT}. Defaults to {@link Parameters#PRIORITY_DEFAULT}.
|
||||
*
|
||||
* Priority determines the order jobs are run. In general, higher priority jobs run first. When deciding which job to run within a queue, we will always
|
||||
@@ -505,8 +522,25 @@ public abstract class Job {
|
||||
* of this, as it provides the potential for lower-priority jobs to be extremely delayed if higher-priority jobs are being consistently enqueued at the
|
||||
* same time.
|
||||
*/
|
||||
public @NonNull Builder setPriority(int priority) {
|
||||
this.priority = priority;
|
||||
public @NonNull Builder setGlobalPriority(@Priority int priority) {
|
||||
this.globalPriority = priority;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the job's queue priority. Higher numbers are higher priority. Use the constants {@link Parameters#PRIORITY_HIGH}, {@link Parameters#PRIORITY_LOW},
|
||||
* and {@link Parameters#PRIORITY_DEFAULT}. Defaults to {@link Parameters#PRIORITY_DEFAULT}.
|
||||
*
|
||||
* Queue priority determines the order jobs are run within a queue. It's a secondary attribute to {@link #setGlobalPriority(int)}. When deciding which job
|
||||
* to run within a queue, if two jobs have equal global priorities, we will always run the oldest job that has the highest queue priority. For example,
|
||||
* if the highest queue priority in the queue is {@link Parameters#PRIORITY_DEFAULT} (and all global priorities are equal), then we'll run the oldest job
|
||||
* with that queue priority, ignoring lower-priority jobs.
|
||||
*
|
||||
* Outside of picking the "most eligible job" within a queue, the queue priority is not used. It is ignored when choosing which job to run amongst
|
||||
* multiple queues. If you'd like to influence that, see {@link #setGlobalPriority(int)}.
|
||||
*/
|
||||
public @NonNull Builder setQueuePriority(@Priority int priority) {
|
||||
this.queuePriority = priority;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -520,7 +554,7 @@ public abstract class Job {
|
||||
}
|
||||
|
||||
public @NonNull Parameters build() {
|
||||
return new Parameters(id, createTime, lifespan, maxAttempts, maxInstancesForFactory, maxInstancesForQueue, queue, constraintKeys, inputData, memoryOnly, priority);
|
||||
return new Parameters(id, createTime, lifespan, maxAttempts, maxInstancesForFactory, maxInstancesForQueue, queue, constraintKeys, inputData, memoryOnly, globalPriority, queuePriority);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,7 +448,8 @@ class JobController {
|
||||
null,
|
||||
false,
|
||||
job.getParameters().isMemoryOnly(),
|
||||
job.getParameters().getPriority());
|
||||
job.getParameters().getGlobalPriority(),
|
||||
job.getParameters().getQueuePriority());
|
||||
|
||||
List<ConstraintSpec> constraintSpecs = Stream.of(job.getParameters().getConstraintKeys())
|
||||
.map(key -> new ConstraintSpec(jobSpec.getId(), key, jobSpec.isMemoryOnly()))
|
||||
@@ -556,7 +557,8 @@ class JobController {
|
||||
inputData,
|
||||
jobSpec.isRunning(),
|
||||
jobSpec.isMemoryOnly(),
|
||||
jobSpec.getPriority());
|
||||
jobSpec.getGlobalPriority(),
|
||||
jobSpec.getQueuePriority());
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
|
||||
@@ -72,7 +72,8 @@ public class JobMigrator {
|
||||
jobSpec.getSerializedInputData(),
|
||||
jobSpec.isRunning(),
|
||||
jobSpec.isMemoryOnly(),
|
||||
jobSpec.getPriority());
|
||||
jobSpec.getGlobalPriority(),
|
||||
jobSpec.getQueuePriority());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@ data class JobSpec(
|
||||
val serializedInputData: ByteArray?,
|
||||
val isRunning: Boolean,
|
||||
val isMemoryOnly: Boolean,
|
||||
val priority: Int
|
||||
val globalPriority: Int,
|
||||
val queuePriority: Int
|
||||
) {
|
||||
|
||||
fun withNextBackoffInterval(updated: Long): JobSpec {
|
||||
@@ -26,7 +27,7 @@ data class JobSpec(
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "id: JOB::$id | factoryKey: $factoryKey | queueKey: $queueKey | createTime: $createTime | lastRunAttemptTime: $lastRunAttemptTime | nextBackoffInterval: $nextBackoffInterval | runAttempt: $runAttempt | maxAttempts: $maxAttempts | lifespan: $lifespan | isRunning: $isRunning | memoryOnly: $isMemoryOnly"
|
||||
return "id: JOB::$id | factoryKey: $factoryKey | queueKey: $queueKey | createTime: $createTime | lastRunAttemptTime: $lastRunAttemptTime | nextBackoffInterval: $nextBackoffInterval | runAttempt: $runAttempt | maxAttempts: $maxAttempts | lifespan: $lifespan | isRunning: $isRunning | memoryOnly: $isMemoryOnly | globalPriority: $globalPriority | queuePriorty: $queuePriority"
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user