Add support for adding jobs with existing dependencies.

This commit is contained in:
Greyson Parrelli 2020-01-07 21:00:32 -05:00
parent 38597aea00
commit 06757153b3
2 changed files with 40 additions and 7 deletions

View File

@ -16,13 +16,12 @@ import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.Debouncer; import org.thoughtcrime.securesms.util.Debouncer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* Manages the queue of jobs. This is the only class that should write to {@link JobStorage} to * Manages the queue of jobs. This is the only class that should write to {@link JobStorage} to
@ -97,6 +96,28 @@ class JobController {
notifyAll(); notifyAll();
} }
@WorkerThread
synchronized void submitJobWithExistingDependencies(@NonNull Job job, @NonNull Collection<String> dependsOn) {
List<List<Job>> chain = Collections.singletonList(Collections.singletonList(job));
if (chainExceedsMaximumInstances(chain)) {
jobTracker.onStateChange(job.getId(), JobTracker.JobState.IGNORED);
Log.w(TAG, JobLogger.format(job, "Already at the max instance count of " + job.getParameters().getMaxInstances() + ". Skipping."));
return;
}
dependsOn = Stream.of(dependsOn)
.filter(id -> jobStorage.getJobSpec(id) != null)
.toList();
FullSpec fullSpec = buildFullSpec(job, dependsOn);
jobStorage.insertJobs(Collections.singletonList(fullSpec));
scheduleJobs(Collections.singletonList(job));
triggerOnSubmit(chain);
notifyAll();
}
@WorkerThread @WorkerThread
synchronized void cancelJob(@NonNull String id) { synchronized void cancelJob(@NonNull String id) {
Job runningJob = runningJobs.get(id); Job runningJob = runningJobs.get(id);
@ -272,20 +293,20 @@ class JobController {
@WorkerThread @WorkerThread
private void insertJobChain(@NonNull List<List<Job>> chain) { private void insertJobChain(@NonNull List<List<Job>> chain) {
List<FullSpec> fullSpecs = new LinkedList<>(); List<FullSpec> fullSpecs = new LinkedList<>();
List<Job> dependsOn = Collections.emptyList(); List<String> dependsOn = Collections.emptyList();
for (List<Job> jobList : chain) { for (List<Job> jobList : chain) {
for (Job job : jobList) { for (Job job : jobList) {
fullSpecs.add(buildFullSpec(job, dependsOn)); fullSpecs.add(buildFullSpec(job, dependsOn));
} }
dependsOn = jobList; dependsOn = Stream.of(jobList).map(Job::getId).toList();
} }
jobStorage.insertJobs(fullSpecs); jobStorage.insertJobs(fullSpecs);
} }
@WorkerThread @WorkerThread
private @NonNull FullSpec buildFullSpec(@NonNull Job job, @NonNull List<Job> dependsOn) { private @NonNull FullSpec buildFullSpec(@NonNull Job job, @NonNull Collection<String> dependsOn) {
job.setRunAttempt(0); job.setRunAttempt(0);
JobSpec jobSpec = new JobSpec(job.getId(), JobSpec jobSpec = new JobSpec(job.getId(),
@ -306,7 +327,7 @@ class JobController {
.toList(); .toList();
List<DependencySpec> dependencySpecs = Stream.of(dependsOn) List<DependencySpec> dependencySpecs = Stream.of(dependsOn)
.map(depends -> new DependencySpec(job.getId(), depends.getId())) .map(depends -> new DependencySpec(job.getId(), depends))
.toList(); .toList();
return new FullSpec(jobSpec, constraintSpecs, dependencySpecs); return new FullSpec(jobSpec, constraintSpecs, dependencySpecs);

View File

@ -5,7 +5,6 @@ import android.content.Intent;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread; import androidx.annotation.WorkerThread;
import androidx.lifecycle.LiveData;
import org.thoughtcrime.securesms.jobmanager.impl.DefaultExecutorFactory; import org.thoughtcrime.securesms.jobmanager.impl.DefaultExecutorFactory;
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer; import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
@ -16,6 +15,7 @@ import org.thoughtcrime.securesms.util.Debouncer;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
@ -119,6 +119,18 @@ public class JobManager implements ConstraintObserver.Notifier {
new Chain(this, Collections.singletonList(job)).enqueue(); new Chain(this, Collections.singletonList(job)).enqueue();
} }
/**
* Enqueues a single job that depends on a collection of job ID's.
*/
public void add(@NonNull Job job, @NonNull Collection<String> dependsOn) {
jobTracker.onStateChange(job.getId(), JobTracker.JobState.PENDING);
executor.execute(() -> {
jobController.submitJobWithExistingDependencies(job, dependsOn);
wakeUp();
});
}
/** /**
* Begins the creation of a job chain with a single job. * Begins the creation of a job chain with a single job.
* @see Chain * @see Chain