Add support for memory-only jobs.

fork-5.53.8
Greyson Parrelli 2020-06-25 05:32:36 -07:00
rodzic 2001fa86cf
commit 87a59b6a9b
13 zmienionych plików z 314 dodań i 133 usunięć

Wyświetl plik

@ -5,6 +5,8 @@ import android.content.Context;
import android.database.Cursor;
import androidx.annotation.NonNull;
import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
@ -89,6 +91,10 @@ public class JobDatabase extends Database {
}
public synchronized void insertJobs(@NonNull List<FullSpec> fullSpecs) {
if (Stream.of(fullSpecs).map(FullSpec::getJobSpec).allMatch(JobSpec::isMemoryOnly)) {
return;
}
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.beginTransaction();
@ -149,32 +155,38 @@ public class JobDatabase extends Database {
}
public synchronized void updateJobs(@NonNull List<JobSpec> jobs) {
if (Stream.of(jobs).allMatch(JobSpec::isMemoryOnly)) {
return;
}
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.beginTransaction();
try {
for (JobSpec job : jobs) {
ContentValues values = new ContentValues();
values.put(Jobs.JOB_SPEC_ID, job.getId());
values.put(Jobs.FACTORY_KEY, job.getFactoryKey());
values.put(Jobs.QUEUE_KEY, job.getQueueKey());
values.put(Jobs.CREATE_TIME, job.getCreateTime());
values.put(Jobs.NEXT_RUN_ATTEMPT_TIME, job.getNextRunAttemptTime());
values.put(Jobs.RUN_ATTEMPT, job.getRunAttempt());
values.put(Jobs.MAX_ATTEMPTS, job.getMaxAttempts());
values.put(Jobs.MAX_BACKOFF, job.getMaxBackoff());
values.put(Jobs.MAX_INSTANCES, job.getMaxInstances());
values.put(Jobs.LIFESPAN, job.getLifespan());
values.put(Jobs.SERIALIZED_DATA, job.getSerializedData());
values.put(Jobs.SERIALIZED_INPUT_DATA, job.getSerializedInputData());
values.put(Jobs.IS_RUNNING, job.isRunning() ? 1 : 0);
Stream.of(jobs)
.filterNot(JobSpec::isMemoryOnly)
.forEach(job -> {
ContentValues values = new ContentValues();
values.put(Jobs.JOB_SPEC_ID, job.getId());
values.put(Jobs.FACTORY_KEY, job.getFactoryKey());
values.put(Jobs.QUEUE_KEY, job.getQueueKey());
values.put(Jobs.CREATE_TIME, job.getCreateTime());
values.put(Jobs.NEXT_RUN_ATTEMPT_TIME, job.getNextRunAttemptTime());
values.put(Jobs.RUN_ATTEMPT, job.getRunAttempt());
values.put(Jobs.MAX_ATTEMPTS, job.getMaxAttempts());
values.put(Jobs.MAX_BACKOFF, job.getMaxBackoff());
values.put(Jobs.MAX_INSTANCES, job.getMaxInstances());
values.put(Jobs.LIFESPAN, job.getLifespan());
values.put(Jobs.SERIALIZED_DATA, job.getSerializedData());
values.put(Jobs.SERIALIZED_INPUT_DATA, job.getSerializedInputData());
values.put(Jobs.IS_RUNNING, job.isRunning() ? 1 : 0);
String query = Jobs.JOB_SPEC_ID + " = ?";
String[] args = new String[]{ job.getId() };
String query = Jobs.JOB_SPEC_ID + " = ?";
String[] args = new String[]{ job.getId() };
db.update(Jobs.TABLE_NAME, values, query, args);
}
db.update(Jobs.TABLE_NAME, values, query, args);
});
db.setTransactionSuccessful();
} finally {
@ -228,6 +240,10 @@ public class JobDatabase extends Database {
}
private void insertJobSpec(@NonNull SQLiteDatabase db, @NonNull JobSpec job) {
if (job.isMemoryOnly()) {
return;
}
ContentValues contentValues = new ContentValues();
contentValues.put(Jobs.JOB_SPEC_ID, job.getId());
contentValues.put(Jobs.FACTORY_KEY, job.getFactoryKey());
@ -247,21 +263,25 @@ public class JobDatabase extends Database {
}
private void insertConstraintSpecs(@NonNull SQLiteDatabase db, @NonNull List<ConstraintSpec> constraints) {
for (ConstraintSpec constraintSpec : constraints) {
ContentValues contentValues = new ContentValues();
contentValues.put(Constraints.JOB_SPEC_ID, constraintSpec.getJobSpecId());
contentValues.put(Constraints.FACTORY_KEY, constraintSpec.getFactoryKey());
db.insertWithOnConflict(Constraints.TABLE_NAME, null ,contentValues, SQLiteDatabase.CONFLICT_IGNORE);
}
Stream.of(constraints)
.filterNot(ConstraintSpec::isMemoryOnly)
.forEach(constraintSpec -> {
ContentValues contentValues = new ContentValues();
contentValues.put(Constraints.JOB_SPEC_ID, constraintSpec.getJobSpecId());
contentValues.put(Constraints.FACTORY_KEY, constraintSpec.getFactoryKey());
db.insertWithOnConflict(Constraints.TABLE_NAME, null ,contentValues, SQLiteDatabase.CONFLICT_IGNORE);
});
}
private void insertDependencySpecs(@NonNull SQLiteDatabase db, @NonNull List<DependencySpec> dependencies) {
for (DependencySpec dependencySpec : dependencies) {
ContentValues contentValues = new ContentValues();
contentValues.put(Dependencies.JOB_SPEC_ID, dependencySpec.getJobId());
contentValues.put(Dependencies.DEPENDS_ON_JOB_SPEC_ID, dependencySpec.getDependsOnJobId());
db.insertWithOnConflict(Dependencies.TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_IGNORE);
}
Stream.of(dependencies)
.filterNot(DependencySpec::isMemoryOnly)
.forEach(dependencySpec -> {
ContentValues contentValues = new ContentValues();
contentValues.put(Dependencies.JOB_SPEC_ID, dependencySpec.getJobId());
contentValues.put(Dependencies.DEPENDS_ON_JOB_SPEC_ID, dependencySpec.getDependsOnJobId());
db.insertWithOnConflict(Dependencies.TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_IGNORE);
});
}
private @NonNull JobSpec jobSpecFromCursor(@NonNull Cursor cursor) {
@ -277,16 +297,19 @@ public class JobDatabase extends Database {
cursor.getInt(cursor.getColumnIndexOrThrow(Jobs.MAX_INSTANCES)),
cursor.getString(cursor.getColumnIndexOrThrow(Jobs.SERIALIZED_DATA)),
cursor.getString(cursor.getColumnIndexOrThrow(Jobs.SERIALIZED_INPUT_DATA)),
cursor.getInt(cursor.getColumnIndexOrThrow(Jobs.IS_RUNNING)) == 1);
cursor.getInt(cursor.getColumnIndexOrThrow(Jobs.IS_RUNNING)) == 1,
false);
}
private @NonNull ConstraintSpec constraintSpecFromCursor(@NonNull Cursor cursor) {
return new ConstraintSpec(cursor.getString(cursor.getColumnIndexOrThrow(Constraints.JOB_SPEC_ID)),
cursor.getString(cursor.getColumnIndexOrThrow(Constraints.FACTORY_KEY)));
cursor.getString(cursor.getColumnIndexOrThrow(Constraints.FACTORY_KEY)),
false);
}
private @NonNull DependencySpec dependencySpecFromCursor(@NonNull Cursor cursor) {
return new DependencySpec(cursor.getString(cursor.getColumnIndexOrThrow(Dependencies.JOB_SPEC_ID)),
cursor.getString(cursor.getColumnIndexOrThrow(Dependencies.DEPENDS_ON_JOB_SPEC_ID)));
cursor.getString(cursor.getColumnIndexOrThrow(Dependencies.DEPENDS_ON_JOB_SPEC_ID)),
false);
}
}

Wyświetl plik

@ -245,6 +245,7 @@ public abstract class Job {
private final String queue;
private final List<String> constraintKeys;
private final Data inputData;
private final boolean memoryOnly;
private Parameters(@NonNull String id,
long createTime,
@ -254,7 +255,8 @@ public abstract class Job {
int maxInstances,
@Nullable String queue,
@NonNull List<String> constraintKeys,
@Nullable Data inputData)
@Nullable Data inputData,
boolean memoryOnly)
{
this.id = id;
this.createTime = createTime;
@ -265,6 +267,7 @@ public abstract class Job {
this.queue = queue;
this.constraintKeys = constraintKeys;
this.inputData = inputData;
this.memoryOnly = memoryOnly;
}
@NonNull String getId() {
@ -303,8 +306,12 @@ public abstract class Job {
return inputData;
}
boolean isMemoryOnly() {
return memoryOnly;
}
public Builder toBuilder() {
return new Builder(id, createTime, maxBackoff, lifespan, maxAttempts, maxInstances, queue, constraintKeys, inputData);
return new Builder(id, createTime, maxBackoff, lifespan, maxAttempts, maxInstances, queue, constraintKeys, inputData, memoryOnly);
}
@ -319,13 +326,14 @@ public abstract class Job {
private String queue;
private List<String> constraintKeys;
private Data inputData;
private boolean memoryOnly;
public Builder() {
this(UUID.randomUUID().toString());
}
Builder(@NonNull String id) {
this(id, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(30), IMMORTAL, 1, UNLIMITED, null, new LinkedList<>(), null);
this(id, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(30), IMMORTAL, 1, UNLIMITED, null, new LinkedList<>(), null, false);
}
private Builder(@NonNull String id,
@ -336,7 +344,8 @@ public abstract class Job {
int maxInstances,
@Nullable String queue,
@NonNull List<String> constraintKeys,
@Nullable Data inputData)
@Nullable Data inputData,
boolean memoryOnly)
{
this.id = id;
this.createTime = createTime;
@ -347,6 +356,7 @@ public abstract class Job {
this.queue = queue;
this.constraintKeys = constraintKeys;
this.inputData = inputData;
this.memoryOnly = memoryOnly;
}
/** Should only be invoked by {@link JobController} */
@ -424,6 +434,17 @@ public abstract class Job {
return this;
}
/**
* Specify whether or not you want this job to only live in memory. If true, this job will
* *not* survive application death. This defaults to false, and should be used with care.
*
* Defaults to false.
*/
public @NonNull Builder setMemoryOnly(boolean memoryOnly) {
this.memoryOnly = memoryOnly;
return this;
}
/**
* Sets the input data that will be made availabe to the job when it is run.
* Should only be set by {@link JobController}.
@ -434,7 +455,7 @@ public abstract class Job {
}
public @NonNull Parameters build() {
return new Parameters(id, createTime, lifespan, maxAttempts, maxBackoff, maxInstances, queue, constraintKeys, inputData);
return new Parameters(id, createTime, lifespan, maxAttempts, maxBackoff, maxInstances, queue, constraintKeys, inputData, memoryOnly);
}
}
}

Wyświetl plik

@ -354,14 +354,20 @@ class JobController {
job.getParameters().getMaxInstances(),
dataSerializer.serialize(job.serialize()),
null,
false);
false,
job.getParameters().isMemoryOnly());
List<ConstraintSpec> constraintSpecs = Stream.of(job.getParameters().getConstraintKeys())
.map(key -> new ConstraintSpec(jobSpec.getId(), key))
.map(key -> new ConstraintSpec(jobSpec.getId(), key, jobSpec.isMemoryOnly()))
.toList();
List<DependencySpec> dependencySpecs = Stream.of(dependsOn)
.map(depends -> new DependencySpec(job.getId(), depends))
.map(depends -> {
JobSpec dependsOnJobSpec = jobStorage.getJobSpec(depends);
boolean memoryOnly = job.getParameters().isMemoryOnly() || (dependsOnJobSpec != null && dependsOnJobSpec.isMemoryOnly());
return new DependencySpec(job.getId(), depends, memoryOnly);
})
.toList();
return new FullSpec(jobSpec, constraintSpecs, dependencySpecs);
@ -371,7 +377,7 @@ class JobController {
private void scheduleJobs(@NonNull List<Job> jobs) {
for (Job job : jobs) {
List<Constraint> constraints = Stream.of(job.getParameters().getConstraintKeys())
.map(key -> new ConstraintSpec(job.getId(), key))
.map(key -> new ConstraintSpec(job.getId(), key, job.getParameters().isMemoryOnly()))
.map(ConstraintSpec::getFactoryKey)
.map(constraintInstantiator::instantiate)
.toList();
@ -460,7 +466,8 @@ class JobController {
jobSpec.getMaxInstances(),
jobSpec.getSerializedData(),
dataSerializer.serialize(inputData),
jobSpec.isRunning());
jobSpec.isRunning(),
jobSpec.isMemoryOnly());
}
interface Callback {

Wyświetl plik

@ -76,7 +76,8 @@ public class JobMigrator {
jobSpec.getMaxInstances(),
dataSerializer.serialize(updatedJobData.getData()),
jobSpec.getSerializedInputData(),
jobSpec.isRunning());
jobSpec.isRunning(),
jobSpec.isMemoryOnly());
iter.set(updatedJobSpec);
}

Wyświetl plik

@ -6,12 +6,14 @@ import java.util.Objects;
public final class ConstraintSpec {
private final String jobSpecId;
private final String factoryKey;
private final String jobSpecId;
private final String factoryKey;
private final boolean memoryOnly;
public ConstraintSpec(@NonNull String jobSpecId, @NonNull String factoryKey) {
public ConstraintSpec(@NonNull String jobSpecId, @NonNull String factoryKey, boolean memoryOnly) {
this.jobSpecId = jobSpecId;
this.factoryKey = factoryKey;
this.memoryOnly = memoryOnly;
}
public String getJobSpecId() {
@ -22,22 +24,27 @@ public final class ConstraintSpec {
return factoryKey;
}
public boolean isMemoryOnly() {
return memoryOnly;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ConstraintSpec that = (ConstraintSpec) o;
return Objects.equals(jobSpecId, that.jobSpecId) &&
Objects.equals(factoryKey, that.factoryKey);
return Objects.equals(jobSpecId, that.jobSpecId) &&
Objects.equals(factoryKey, that.factoryKey) &&
memoryOnly == that.memoryOnly;
}
@Override
public int hashCode() {
return Objects.hash(jobSpecId, factoryKey);
return Objects.hash(jobSpecId, factoryKey, memoryOnly);
}
@Override
public @NonNull String toString() {
return String.format("jobSpecId: JOB::%s | factoryKey: %s", jobSpecId, factoryKey);
return String.format("jobSpecId: JOB::%s | factoryKey: %s | memoryOnly: %b", jobSpecId, factoryKey, memoryOnly);
}
}

Wyświetl plik

@ -6,12 +6,14 @@ import java.util.Objects;
public final class DependencySpec {
private final String jobId;
private final String dependsOnJobId;
private final String jobId;
private final String dependsOnJobId;
private final boolean memoryOnly;
public DependencySpec(@NonNull String jobId, @NonNull String dependsOnJobId) {
public DependencySpec(@NonNull String jobId, @NonNull String dependsOnJobId, boolean memoryOnly) {
this.jobId = jobId;
this.dependsOnJobId = dependsOnJobId;
this.memoryOnly = memoryOnly;
}
public @NonNull String getJobId() {
@ -22,22 +24,27 @@ public final class DependencySpec {
return dependsOnJobId;
}
public boolean isMemoryOnly() {
return memoryOnly;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DependencySpec that = (DependencySpec) o;
return Objects.equals(jobId, that.jobId) &&
Objects.equals(dependsOnJobId, that.dependsOnJobId);
return Objects.equals(jobId, that.jobId) &&
Objects.equals(dependsOnJobId, that.dependsOnJobId) &&
memoryOnly == that.memoryOnly;
}
@Override
public int hashCode() {
return Objects.hash(jobId, dependsOnJobId);
return Objects.hash(jobId, dependsOnJobId, memoryOnly);
}
@Override
public @NonNull String toString() {
return String.format("jobSpecId: JOB::%s | dependsOnJobSpecId: JOB::%s", jobId, dependsOnJobId);
return String.format("jobSpecId: JOB::%s | dependsOnJobSpecId: JOB::%s | memoryOnly: %b", jobId, dependsOnJobId, memoryOnly);
}
}

Wyświetl plik

@ -32,6 +32,9 @@ public final class FullSpec {
return dependencySpecs;
}
public boolean isMemoryOnly() {
return jobSpec.isMemoryOnly();
}
@Override
public boolean equals(Object o) {

Wyświetl plik

@ -21,6 +21,7 @@ public final class JobSpec {
private final String serializedData;
private final String serializedInputData;
private final boolean isRunning;
private final boolean memoryOnly;
public JobSpec(@NonNull String id,
@NonNull String factoryKey,
@ -34,7 +35,8 @@ public final class JobSpec {
int maxInstances,
@NonNull String serializedData,
@Nullable String serializedInputData,
boolean isRunning)
boolean isRunning,
boolean memoryOnly)
{
this.id = id;
this.factoryKey = factoryKey;
@ -49,6 +51,7 @@ public final class JobSpec {
this.serializedData = serializedData;
this.serializedInputData = serializedInputData;
this.isRunning = isRunning;
this.memoryOnly = memoryOnly;
}
public @NonNull String getId() {
@ -103,6 +106,10 @@ public final class JobSpec {
return isRunning;
}
public boolean isMemoryOnly() {
return memoryOnly;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -116,6 +123,7 @@ public final class JobSpec {
lifespan == jobSpec.lifespan &&
maxInstances == jobSpec.maxInstances &&
isRunning == jobSpec.isRunning &&
memoryOnly == jobSpec.memoryOnly &&
Objects.equals(id, jobSpec.id) &&
Objects.equals(factoryKey, jobSpec.factoryKey) &&
Objects.equals(queueKey, jobSpec.queueKey) &&
@ -125,13 +133,13 @@ public final class JobSpec {
@Override
public int hashCode() {
return Objects.hash(id, factoryKey, queueKey, createTime, nextRunAttemptTime, runAttempt, maxAttempts, maxBackoff, lifespan, maxInstances, serializedData, serializedInputData, isRunning);
return Objects.hash(id, factoryKey, queueKey, createTime, nextRunAttemptTime, runAttempt, maxAttempts, maxBackoff, lifespan, maxInstances, serializedData, serializedInputData, isRunning, memoryOnly);
}
@SuppressLint("DefaultLocale")
@Override
public @NonNull String toString() {
return String.format("id: JOB::%s | factoryKey: %s | queueKey: %s | createTime: %d | nextRunAttemptTime: %d | runAttempt: %d | maxAttempts: %d | maxBackoff: %d | maxInstances: %d | lifespan: %d | isRunning: %b",
id, factoryKey, queueKey, createTime, nextRunAttemptTime, runAttempt, maxAttempts, maxBackoff, maxInstances, lifespan, isRunning);
return String.format("id: JOB::%s | factoryKey: %s | queueKey: %s | createTime: %d | nextRunAttemptTime: %d | runAttempt: %d | maxAttempts: %d | maxBackoff: %d | maxInstances: %d | lifespan: %d | isRunning: %b | memoryOnly: %b",
id, factoryKey, queueKey, createTime, nextRunAttemptTime, runAttempt, maxAttempts, maxBackoff, maxInstances, lifespan, isRunning, memoryOnly);
}
}

Wyświetl plik

@ -69,12 +69,13 @@ final class WorkManagerDatabase extends SQLiteOpenHelper {
Job.Parameters.UNLIMITED,
dataSerializer.serialize(DataMigrator.convert(data)),
null,
false,
false);
if (cursor.getInt(cursor.getColumnIndexOrThrow("required_network_type")) != 0) {
constraints.add(new ConstraintSpec(id, NetworkConstraint.KEY));
constraints.add(new ConstraintSpec(id, NetworkConstraint.KEY, false));
}
fullSpecs.add(new FullSpec(jobSpec, constraints, Collections.emptyList()));

Wyświetl plik

@ -85,9 +85,12 @@ public class FastJobStorage implements JobStorage {
@Override
public synchronized void insertJobs(@NonNull List<FullSpec> fullSpecs) {
serialExecutor.execute(() -> {
jobDatabase.insertJobs(fullSpecs);
});
List<FullSpec> durable = Stream.of(fullSpecs).filterNot(FullSpec::isMemoryOnly).toList();
if (durable.size() > 0) {
serialExecutor.execute(() -> {
jobDatabase.insertJobs(durable);
});
}
for (FullSpec fullSpec : fullSpecs) {
jobs.add(fullSpec.getJobSpec());
@ -168,9 +171,12 @@ public class FastJobStorage implements JobStorage {
@Override
public synchronized void updateJobRunningState(@NonNull String id, boolean isRunning) {
serialExecutor.execute(() -> {
jobDatabase.updateJobRunningState(id, isRunning);
});
JobSpec job = getJobById(id);
if (job == null || !job.isMemoryOnly()) {
serialExecutor.execute(() -> {
jobDatabase.updateJobRunningState(id, isRunning);
});
}
ListIterator<JobSpec> iter = jobs.listIterator();
@ -189,7 +195,8 @@ public class FastJobStorage implements JobStorage {
existing.getMaxInstances(),
existing.getSerializedData(),
existing.getSerializedInputData(),
isRunning);
isRunning,
existing.isMemoryOnly());
iter.set(updated);
}
}
@ -197,9 +204,12 @@ public class FastJobStorage implements JobStorage {
@Override
public synchronized void updateJobAfterRetry(@NonNull String id, boolean isRunning, int runAttempt, long nextRunAttemptTime, @NonNull String serializedData) {
serialExecutor.execute(() -> {
jobDatabase.updateJobAfterRetry(id, isRunning, runAttempt, nextRunAttemptTime, serializedData);
});
JobSpec job = getJobById(id);
if (job == null || !job.isMemoryOnly()) {
serialExecutor.execute(() -> {
jobDatabase.updateJobAfterRetry(id, isRunning, runAttempt, nextRunAttemptTime, serializedData);
});
}
ListIterator<JobSpec> iter = jobs.listIterator();
@ -218,7 +228,8 @@ public class FastJobStorage implements JobStorage {
existing.getMaxInstances(),
serializedData,
existing.getSerializedInputData(),
isRunning);
isRunning,
existing.isMemoryOnly());
iter.set(updated);
}
}
@ -245,16 +256,27 @@ public class FastJobStorage implements JobStorage {
existing.getMaxInstances(),
existing.getSerializedData(),
existing.getSerializedInputData(),
false);
false,
existing.isMemoryOnly());
iter.set(updated);
}
}
@Override
public void updateJobs(@NonNull List<JobSpec> jobSpecs) {
serialExecutor.execute(() -> {
jobDatabase.updateJobs(jobSpecs);
});
List<JobSpec> durable = new ArrayList<>(jobSpecs.size());
for (JobSpec update : jobSpecs) {
JobSpec found = getJobById(update.getId());
if (found == null || !found.isMemoryOnly()) {
durable.add(update);
}
}
if (durable.size() > 0) {
serialExecutor.execute(() -> {
jobDatabase.updateJobs(durable);
});
}
Map<String, JobSpec> updates = Stream.of(jobSpecs).collect(Collectors.toMap(JobSpec::getId));
ListIterator<JobSpec> iter = jobs.listIterator();
@ -276,10 +298,19 @@ public class FastJobStorage implements JobStorage {
@Override
public synchronized void deleteJobs(@NonNull List<String> jobIds) {
serialExecutor.execute(() -> {
jobDatabase.deleteJobs(jobIds);
});
List<String> durableIds = new ArrayList<>(jobIds.size());
for (String id : jobIds) {
JobSpec job = getJobById(id);
if (job == null || !job.isMemoryOnly()) {
durableIds.add(id);
}
}
if (durableIds.size() > 0) {
serialExecutor.execute(() -> {
jobDatabase.deleteJobs(durableIds);
});
}
Set<String> deleteIds = new HashSet<>(jobIds);
@ -355,4 +386,14 @@ public class FastJobStorage implements JobStorage {
.flatMap(Stream::of)
.toList();
}
private JobSpec getJobById(@NonNull String id) {
for (JobSpec job : jobs) {
if (job.getId().equals(id)) {
return job;
}
}
Log.w(TAG, "Was looking for job with ID JOB::" + id + ", but it doesn't exist in memory!");
return null;
}
}

Wyświetl plik

@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.jobs;
import android.net.Network;
import androidx.annotation.NonNull;
import com.annimon.stream.Stream;
@ -10,6 +12,7 @@ import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
@ -43,6 +46,8 @@ public class TypingSendJob extends BaseJob {
.setQueue(getQueue(threadId))
.setMaxAttempts(1)
.setLifespan(TimeUnit.SECONDS.toMillis(5))
.addConstraint(NetworkConstraint.KEY)
.setMemoryOnly(true)
.build(),
threadId,
typing);

Wyświetl plik

@ -88,7 +88,7 @@ public class JobMigratorTest {
private static JobStorage simpleJobStorage() {
JobStorage jobStorage = mock(JobStorage.class);
when(jobStorage.getAllJobSpecs()).thenReturn(new ArrayList<>(Collections.singletonList(new JobSpec("1", "f1", null, 1, 1, 1, 1, 1, 1, 1, "", null, false))));
when(jobStorage.getAllJobSpecs()).thenReturn(new ArrayList<>(Collections.singletonList(new JobSpec("1", "f1", null, 1, 1, 1, 1, 1, 1, 1, "", null, false, false))));
return jobStorage;
}

Wyświetl plik

@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec;
import org.thoughtcrime.securesms.testutil.DirectExecutor;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -24,6 +25,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -53,6 +55,16 @@ public class FastJobStorageTest {
verify(database).insertJobs(DataSet1.FULL_SPECS);
}
@Test
public void insertJobs_memoryOnlyJob_doesNotWriteToDatabase() {
JobDatabase database = noopDatabase();
FastJobStorage subject = new FastJobStorage(database, new DirectExecutor());
subject.insertJobs(DataSetMemory.FULL_SPECS);
verify(database, times(0)).insertJobs(DataSet1.FULL_SPECS);
}
@Test
public void insertJobs_dataCanBeFound() {
FastJobStorage subject = new FastJobStorage(noopDatabase(), new DirectExecutor());
@ -86,10 +98,10 @@ public class FastJobStorageTest {
@Test
public void updateAllJobsToBePending_allArePending() {
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, true),
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, true, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, true),
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, true, false),
Collections.emptyList(),
Collections.emptyList());
@ -104,32 +116,44 @@ public class FastJobStorageTest {
@Test
public void updateJobs_writesToDatabase() {
JobDatabase database = noopDatabase();
JobDatabase database = fixedDataDatabase(DataSet1.FULL_SPECS);
FastJobStorage subject = new FastJobStorage(database, new DirectExecutor());
List<JobSpec> jobs = Collections.emptyList();
List<JobSpec> jobs = Collections.singletonList(new JobSpec("id1", "f1", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, false, false));
subject.init();
subject.updateJobs(jobs);
verify(database).updateJobs(jobs);
}
@Test
public void updateJobs_updatesAllFields() {
public void updateJobs_memoryOnly_doesNotWriteToDatabase() {
JobDatabase database = fixedDataDatabase(DataSetMemory.FULL_SPECS);
FastJobStorage subject = new FastJobStorage(database, new DirectExecutor());
List<JobSpec> jobs = Collections.singletonList(new JobSpec("id1", "f1", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, false, false));
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, false),
subject.init();
subject.updateJobs(jobs);
verify(database, times(0)).updateJobs(jobs);
}
@Test
public void updateJobs_updatesAllFields() {
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, false),
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec fullSpec3 = new FullSpec(new JobSpec("3", "f3", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, false),
FullSpec fullSpec3 = new FullSpec(new JobSpec("3", "f3", null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Arrays.asList(fullSpec1, fullSpec2, fullSpec3)), new DirectExecutor());
JobSpec update1 = new JobSpec("1", "g1", "q1", 2, 2, 2, 2, 2, 2, 2, "abc", null, true);
JobSpec update2 = new JobSpec("2", "g2", "q2", 3, 3, 3, 3, 3, 3, 3, "def", "ghi", true);
JobSpec update1 = new JobSpec("1", "g1", "q1", 2, 2, 2, 2, 2, 2, 2, "abc", null, true, false);
JobSpec update2 = new JobSpec("2", "g2", "q2", 3, 3, 3, 3, 3, 3, 3, "def", "ghi", true, false);
subject.init();
subject.updateJobs(Arrays.asList(update1, update2));
@ -141,12 +165,13 @@ public class FastJobStorageTest {
@Test
public void updateJobRunningState_writesToDatabase() {
JobDatabase database = noopDatabase();
JobDatabase database = fixedDataDatabase(DataSet1.FULL_SPECS);
FastJobStorage subject = new FastJobStorage(database, new DirectExecutor());
subject.updateJobRunningState("1", true);
subject.init();
subject.updateJobRunningState("id1", true);
verify(database).updateJobRunningState("1", true);
verify(database).updateJobRunningState("id1", true);
}
@Test
@ -163,17 +188,29 @@ public class FastJobStorageTest {
@Test
public void updateJobAfterRetry_writesToDatabase() {
JobDatabase database = noopDatabase();
JobDatabase database = fixedDataDatabase(DataSet1.FULL_SPECS);
FastJobStorage subject = new FastJobStorage(database, new DirectExecutor());
subject.updateJobAfterRetry("1", true, 1, 10, "a");
subject.init();
subject.updateJobAfterRetry("id1", true, 1, 10, "a");
verify(database).updateJobAfterRetry("1", true, 1, 10, "a");
verify(database).updateJobAfterRetry("id1", true, 1, 10, "a");
}
@Test
public void updateJobAfterRetry_memoryOnly_doesNotWriteToDatabase() {
JobDatabase database = fixedDataDatabase(DataSetMemory.FULL_SPECS);
FastJobStorage subject = new FastJobStorage(database, new DirectExecutor());
subject.init();
subject.updateJobAfterRetry("id1", true, 1, 10, "a");
verify(database, times(0)).updateJobAfterRetry("id1", true, 1, 10, "a");
}
@Test
public void updateJobAfterRetry_stateUpdated() {
FullSpec fullSpec = new FullSpec(new JobSpec("1", "f1", null, 0, 0, 0, 3, 30000, -1, -1, EMPTY_DATA, null, true),
FullSpec fullSpec = new FullSpec(new JobSpec("1", "f1", null, 0, 0, 0, 3, 30000, -1, -1, EMPTY_DATA, null, true, false),
Collections.emptyList(),
Collections.emptyList());
@ -193,10 +230,10 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_noneWhenEarlierItemInQueueInRunning() {
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true),
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -208,7 +245,7 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_noneWhenAllJobsAreRunning() {
FullSpec fullSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true),
FullSpec fullSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true, false),
Collections.emptyList(),
Collections.emptyList());
@ -220,7 +257,7 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_noneWhenNextRunTimeIsAfterCurrentTime() {
FullSpec fullSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 10, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec fullSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 10, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -232,12 +269,12 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_noneWhenDependentOnAnotherJob() {
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true),
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.singletonList(new DependencySpec("2", "1")));
Collections.singletonList(new DependencySpec("2", "1", false)));
FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Arrays.asList(fullSpec1, fullSpec2)), new DirectExecutor());
@ -248,7 +285,7 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_singleEligibleJob() {
FullSpec fullSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec fullSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -260,10 +297,10 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_multipleEligibleJobs() {
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -276,10 +313,10 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_singleEligibleJobInMixedList() {
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true),
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -295,10 +332,10 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_firstItemInQueue() {
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec fullSpec1 = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec fullSpec2 = new FullSpec(new JobSpec("2", "f2", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -314,10 +351,10 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_migrationJobTakesPrecedence() {
FullSpec plainSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec plainSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec migrationSpec = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec migrationSpec = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -332,10 +369,10 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_runningMigrationBlocksNormalJobs() {
FullSpec plainSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec plainSpec = new FullSpec(new JobSpec("1", "f1", "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec migrationSpec = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true),
FullSpec migrationSpec = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true, false),
Collections.emptyList(),
Collections.emptyList());
@ -349,10 +386,10 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_runningMigrationBlocksLaterMigrationJobs() {
FullSpec migrationSpec1 = new FullSpec(new JobSpec("1", "f1", Job.Parameters.MIGRATION_QUEUE_KEY, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true),
FullSpec migrationSpec1 = new FullSpec(new JobSpec("1", "f1", Job.Parameters.MIGRATION_QUEUE_KEY, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, true, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec migrationSpec2 = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec migrationSpec2 = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -366,10 +403,10 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_onlyReturnFirstEligibleMigrationJob() {
FullSpec migrationSpec1 = new FullSpec(new JobSpec("1", "f1", Job.Parameters.MIGRATION_QUEUE_KEY, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec migrationSpec1 = new FullSpec(new JobSpec("1", "f1", Job.Parameters.MIGRATION_QUEUE_KEY, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec migrationSpec2 = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec migrationSpec2 = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -384,10 +421,10 @@ public class FastJobStorageTest {
@Test
public void getPendingJobsWithNoDependenciesInCreatedOrder_onlyMigrationJobWithAppropriateNextRunTime() {
FullSpec migrationSpec1 = new FullSpec(new JobSpec("1", "f1", Job.Parameters.MIGRATION_QUEUE_KEY, 0, 999, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec migrationSpec1 = new FullSpec(new JobSpec("1", "f1", Job.Parameters.MIGRATION_QUEUE_KEY, 0, 999, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
FullSpec migrationSpec2 = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false),
FullSpec migrationSpec2 = new FullSpec(new JobSpec("2", "f2", Job.Parameters.MIGRATION_QUEUE_KEY, 5, 0, 0, 0, 0, -1, -1, EMPTY_DATA, null, false, false),
Collections.emptyList(),
Collections.emptyList());
@ -401,15 +438,28 @@ public class FastJobStorageTest {
@Test
public void deleteJobs_writesToDatabase() {
JobDatabase database = noopDatabase();
JobDatabase database = fixedDataDatabase(DataSet1.FULL_SPECS);
FastJobStorage subject = new FastJobStorage(database, new DirectExecutor());
List<String> ids = Arrays.asList("1", "2");
List<String> ids = Arrays.asList("id1", "id2");
subject.init();
subject.deleteJobs(ids);
verify(database).deleteJobs(ids);
}
@Test
public void deleteJobs_memoryOnly_doesNotWriteToDatabase() {
JobDatabase database = fixedDataDatabase(DataSetMemory.FULL_SPECS);
FastJobStorage subject = new FastJobStorage(database, new DirectExecutor());
List<String> ids = Collections.singletonList("id1");
subject.init();
subject.deleteJobs(ids);
verify(database, times(0)).deleteJobs(ids);
}
@Test
public void deleteJobs_deletesAllRelevantPieces() {
FastJobStorage subject = new FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS), new DirectExecutor());
@ -509,13 +559,13 @@ public class FastJobStorageTest {
}
private static final class DataSet1 {
static final JobSpec JOB_1 = new JobSpec("id1", "f1", "q1", 1, 2, 3, 4, 5, 6, 7, EMPTY_DATA, null, false);
static final JobSpec JOB_2 = new JobSpec("id2", "f2", "q2", 1, 2, 3, 4, 5, 6, 7, EMPTY_DATA, null, false);
static final JobSpec JOB_3 = new JobSpec("id3", "f3", "q3", 1, 2, 3, 4, 5, 6, 7, EMPTY_DATA, null, false);
static final ConstraintSpec CONSTRAINT_1 = new ConstraintSpec("id1", "f1");
static final ConstraintSpec CONSTRAINT_2 = new ConstraintSpec("id2", "f2");
static final DependencySpec DEPENDENCY_2 = new DependencySpec("id2", "id1");
static final DependencySpec DEPENDENCY_3 = new DependencySpec("id3", "id2");
static final JobSpec JOB_1 = new JobSpec("id1", "f1", "q1", 1, 2, 3, 4, 5, 6, 7, EMPTY_DATA, null, false, false);
static final JobSpec JOB_2 = new JobSpec("id2", "f2", "q2", 1, 2, 3, 4, 5, 6, 7, EMPTY_DATA, null, false, false);
static final JobSpec JOB_3 = new JobSpec("id3", "f3", "q3", 1, 2, 3, 4, 5, 6, 7, EMPTY_DATA, null, false, false);
static final ConstraintSpec CONSTRAINT_1 = new ConstraintSpec("id1", "f1", false);
static final ConstraintSpec CONSTRAINT_2 = new ConstraintSpec("id2", "f2", false);
static final DependencySpec DEPENDENCY_2 = new DependencySpec("id2", "id1", false);
static final DependencySpec DEPENDENCY_3 = new DependencySpec("id3", "id2", false);
static final FullSpec FULL_SPEC_1 = new FullSpec(JOB_1, Collections.singletonList(CONSTRAINT_1), Collections.emptyList());
static final FullSpec FULL_SPEC_2 = new FullSpec(JOB_2, Collections.singletonList(CONSTRAINT_2), Collections.singletonList(DEPENDENCY_2));
static final FullSpec FULL_SPEC_3 = new FullSpec(JOB_3, Collections.emptyList(), Collections.singletonList(DEPENDENCY_3));
@ -540,4 +590,11 @@ public class FastJobStorageTest {
assertTrue(dependencies.contains(DataSet1.DEPENDENCY_3));
}
}
private static final class DataSetMemory {
static final JobSpec JOB_1 = new JobSpec("id1", "f1", "q1", 1, 2, 3, 4, 5, 6, 7, EMPTY_DATA, null, false, true);
static final ConstraintSpec CONSTRAINT_1 = new ConstraintSpec("id1", "f1", true);
static final FullSpec FULL_SPEC_1 = new FullSpec(JOB_1, Collections.singletonList(CONSTRAINT_1), Collections.emptyList());
static final List<FullSpec> FULL_SPECS = Collections.singletonList(FULL_SPEC_1);
}
}