mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
libjobqueue javadoc and scoping.
// FREEBIE
This commit is contained in:
parent
5b08791086
commit
3cd7c2d8e5
@ -21,6 +21,10 @@ import org.whispersystems.jobqueue.requirements.Requirement;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract class representing a unit of work that can be scheduled with
|
||||||
|
* the JobManager. This should be extended to implement tasks.
|
||||||
|
*/
|
||||||
public abstract class Job implements Serializable {
|
public abstract class Job implements Serializable {
|
||||||
|
|
||||||
private final JobParameters parameters;
|
private final JobParameters parameters;
|
||||||
@ -80,9 +84,31 @@ public abstract class Job implements Serializable {
|
|||||||
this.runIteration = runIteration;
|
this.runIteration = runIteration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after a job has been added to the JobManager queue. If it's a persistent job,
|
||||||
|
* the state has been persisted to disk before this method is called.
|
||||||
|
*/
|
||||||
public abstract void onAdded();
|
public abstract void onAdded();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to actually execute the job.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public abstract void onRun() throws Exception;
|
public abstract void onRun() throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If onRun() throws an exception, this method will be called to determine whether the
|
||||||
|
* job should be retried.
|
||||||
|
*
|
||||||
|
* @param exception The exception onRun() threw.
|
||||||
|
* @return true if onRun() should be called again, false otherwise.
|
||||||
|
*/
|
||||||
public abstract boolean onShouldRetry(Exception exception);
|
public abstract boolean onShouldRetry(Exception exception);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if a job fails to run (onShouldRetry returned false, or the number of retries exceeded
|
||||||
|
* the job's configured retry count.
|
||||||
|
*/
|
||||||
public abstract void onCanceled();
|
public abstract void onCanceled();
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import org.whispersystems.jobqueue.persistence.PersistentStorage;
|
import org.whispersystems.jobqueue.persistence.PersistentStorage;
|
||||||
|
|
||||||
public class JobConsumer extends Thread {
|
class JobConsumer extends Thread {
|
||||||
|
|
||||||
private static final String TAG = JobConsumer.class.getSimpleName();
|
private static final String TAG = JobConsumer.class.getSimpleName();
|
||||||
|
|
||||||
|
@ -27,11 +27,17 @@ import org.whispersystems.jobqueue.requirements.RequirementProvider;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JobManager allows you to enqueue {@link org.whispersystems.jobqueue.Job} tasks
|
||||||
|
* that are executed once a Job's {@link org.whispersystems.jobqueue.requirements.Requirement}s
|
||||||
|
* are met.
|
||||||
|
*/
|
||||||
public class JobManager implements RequirementListener {
|
public class JobManager implements RequirementListener {
|
||||||
|
|
||||||
private final JobQueue jobQueue = new JobQueue();
|
private final JobQueue jobQueue = new JobQueue();
|
||||||
@ -64,15 +70,22 @@ public class JobManager implements RequirementListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context An Android {@link android.content.Context}.
|
||||||
|
* @return a {@link org.whispersystems.jobqueue.JobManager.Builder} used to construct a JobManager.
|
||||||
|
*/
|
||||||
public static Builder newBuilder(Context context) {
|
public static Builder newBuilder(Context context) {
|
||||||
return new Builder(context);
|
return new Builder(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link org.whispersystems.jobqueue.requirements.RequirementProvider} registered with
|
||||||
|
* the JobManager by name.
|
||||||
|
*
|
||||||
|
* @param name The name of the registered {@link org.whispersystems.jobqueue.requirements.RequirementProvider}
|
||||||
|
* @return The RequirementProvider, or null if no provider is registered with that name.
|
||||||
|
*/
|
||||||
public RequirementProvider getRequirementProvider(String name) {
|
public RequirementProvider getRequirementProvider(String name) {
|
||||||
if (requirementProviders == null || requirementProviders.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (RequirementProvider provider : requirementProviders) {
|
for (RequirementProvider provider : requirementProviders) {
|
||||||
if (provider.getName().equals(name)) {
|
if (provider.getName().equals(name)) {
|
||||||
return provider;
|
return provider;
|
||||||
@ -88,6 +101,11 @@ public class JobManager implements RequirementListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a {@link org.whispersystems.jobqueue.Job} to be executed.
|
||||||
|
*
|
||||||
|
* @param job The Job to be executed.
|
||||||
|
*/
|
||||||
public void add(final Job job) {
|
public void add(final Job job) {
|
||||||
eventExecutor.execute(new Runnable() {
|
eventExecutor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@ -153,36 +171,79 @@ public class JobManager implements RequirementListener {
|
|||||||
this.consumerThreads = 5;
|
this.consumerThreads = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A name for the {@link org.whispersystems.jobqueue.JobManager}. This is a required parameter,
|
||||||
|
* and is linked to the durable queue used by persistent jobs.
|
||||||
|
*
|
||||||
|
* @param name The name for the JobManager to build.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
public Builder withName(String name) {
|
public Builder withName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link org.whispersystems.jobqueue.requirements.RequirementProvider}s to register with this
|
||||||
|
* JobManager. Optional. Each {@link org.whispersystems.jobqueue.requirements.Requirement} an
|
||||||
|
* enqueued Job depends on should have a matching RequirementProvider registered here.
|
||||||
|
*
|
||||||
|
* @param requirementProviders The RequirementProviders
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
public Builder withRequirementProviders(RequirementProvider... requirementProviders) {
|
public Builder withRequirementProviders(RequirementProvider... requirementProviders) {
|
||||||
this.requirementProviders = Arrays.asList(requirementProviders);
|
this.requirementProviders = Arrays.asList(requirementProviders);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link org.whispersystems.jobqueue.dependencies.DependencyInjector} to use for injecting
|
||||||
|
* dependencies into {@link Job}s. Optional. Injection occurs just before a Job's onAdded() callback, or
|
||||||
|
* after deserializing a persistent job.
|
||||||
|
*
|
||||||
|
* @param dependencyInjector The injector to use.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
public Builder withDependencyInjector(DependencyInjector dependencyInjector) {
|
public Builder withDependencyInjector(DependencyInjector dependencyInjector) {
|
||||||
this.dependencyInjector = dependencyInjector;
|
this.dependencyInjector = dependencyInjector;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link org.whispersystems.jobqueue.persistence.JobSerializer} to use for persistent Jobs.
|
||||||
|
* Required if persistent Jobs are used.
|
||||||
|
*
|
||||||
|
* @param jobSerializer The serializer to use.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
public Builder withJobSerializer(JobSerializer jobSerializer) {
|
public Builder withJobSerializer(JobSerializer jobSerializer) {
|
||||||
this.jobSerializer = jobSerializer;
|
this.jobSerializer = jobSerializer;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the number of threads dedicated to consuming Jobs from the queue and executing them.
|
||||||
|
*
|
||||||
|
* @param consumerThreads The number of threads.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
public Builder withConsumerThreads(int consumerThreads) {
|
public Builder withConsumerThreads(int consumerThreads) {
|
||||||
this.consumerThreads = consumerThreads;
|
this.consumerThreads = consumerThreads;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A constructed JobManager.
|
||||||
|
*/
|
||||||
public JobManager build() {
|
public JobManager build() {
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
throw new IllegalArgumentException("You must specify a name!");
|
throw new IllegalArgumentException("You must specify a name!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (requirementProviders == null) {
|
||||||
|
requirementProviders = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
return new JobManager(context, name, requirementProviders,
|
return new JobManager(context, name, requirementProviders,
|
||||||
dependencyInjector, jobSerializer,
|
dependencyInjector, jobSerializer,
|
||||||
consumerThreads);
|
consumerThreads);
|
||||||
|
@ -22,6 +22,9 @@ import java.io.Serializable;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The set of parameters that describe a {@link org.whispersystems.jobqueue.Job}.
|
||||||
|
*/
|
||||||
public class JobParameters implements Serializable {
|
public class JobParameters implements Serializable {
|
||||||
|
|
||||||
private transient EncryptionKeys encryptionKeys;
|
private transient EncryptionKeys encryptionKeys;
|
||||||
@ -63,6 +66,9 @@ public class JobParameters implements Serializable {
|
|||||||
return retryCount;
|
return retryCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a builder used to construct JobParameters.
|
||||||
|
*/
|
||||||
public static Builder newBuilder() {
|
public static Builder newBuilder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
@ -78,31 +84,64 @@ public class JobParameters implements Serializable {
|
|||||||
private int retryCount = 100;
|
private int retryCount = 100;
|
||||||
private String groupId = null;
|
private String groupId = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify a {@link org.whispersystems.jobqueue.requirements.Requirement }that must be met
|
||||||
|
* before the Job is executed. May be called multiple times to register multiple requirements.
|
||||||
|
* @param requirement The Requirement that must be met.
|
||||||
|
* @return the builder.
|
||||||
|
*/
|
||||||
public Builder withRequirement(Requirement requirement) {
|
public Builder withRequirement(Requirement requirement) {
|
||||||
this.requirements.add(requirement);
|
this.requirements.add(requirement);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify that the Job should be durably persisted to disk, so that it remains in the queue
|
||||||
|
* across application restarts.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
public Builder withPersistence() {
|
public Builder withPersistence() {
|
||||||
this.isPersistent = true;
|
this.isPersistent = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify that the job should use encryption when durably persisted to disk.
|
||||||
|
* @param encryptionKeys The keys to encrypt the serialized job with before persisting.
|
||||||
|
* @return the builder.
|
||||||
|
*/
|
||||||
public Builder withEncryption(EncryptionKeys encryptionKeys) {
|
public Builder withEncryption(EncryptionKeys encryptionKeys) {
|
||||||
this.encryptionKeys = encryptionKeys;
|
this.encryptionKeys = encryptionKeys;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify how many times the job should be retried if execution fails but onShouldRetry() returns
|
||||||
|
* true.
|
||||||
|
*
|
||||||
|
* @param retryCount The number of times the job should be retried.
|
||||||
|
* @return the builder.
|
||||||
|
*/
|
||||||
public Builder withRetryCount(int retryCount) {
|
public Builder withRetryCount(int retryCount) {
|
||||||
this.retryCount = retryCount;
|
this.retryCount = retryCount;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify a groupId the job should belong to. Jobs with the same groupId are guaranteed to be
|
||||||
|
* executed serially.
|
||||||
|
*
|
||||||
|
* @param groupId The job's groupId.
|
||||||
|
* @return the builder.
|
||||||
|
*/
|
||||||
public Builder withGroupId(String groupId) {
|
public Builder withGroupId(String groupId) {
|
||||||
this.groupId = groupId;
|
this.groupId = groupId;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the JobParameters instance that describes a Job.
|
||||||
|
*/
|
||||||
public JobParameters create() {
|
public JobParameters create() {
|
||||||
return new JobParameters(requirements, isPersistent, groupId, encryptionKeys, retryCount);
|
return new JobParameters(requirements, isPersistent, groupId, encryptionKeys, retryCount);
|
||||||
}
|
}
|
||||||
|
@ -16,29 +16,27 @@
|
|||||||
*/
|
*/
|
||||||
package org.whispersystems.jobqueue;
|
package org.whispersystems.jobqueue;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class JobQueue {
|
class JobQueue {
|
||||||
|
|
||||||
private final Set<String> activeGroupIds = new HashSet<>();
|
private final Set<String> activeGroupIds = new HashSet<>();
|
||||||
private final LinkedList<Job> jobQueue = new LinkedList<>();
|
private final LinkedList<Job> jobQueue = new LinkedList<>();
|
||||||
|
|
||||||
public synchronized void onRequirementStatusChanged() {
|
synchronized void onRequirementStatusChanged() {
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void add(Job job) {
|
synchronized void add(Job job) {
|
||||||
jobQueue.add(job);
|
jobQueue.add(job);
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void addAll(List<Job> jobs) {
|
synchronized void addAll(List<Job> jobs) {
|
||||||
jobQueue.addAll(jobs);
|
jobQueue.addAll(jobs);
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
@ -47,7 +45,7 @@ public class JobQueue {
|
|||||||
jobQueue.push(job);
|
jobQueue.push(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Job getNext() {
|
synchronized Job getNext() {
|
||||||
try {
|
try {
|
||||||
Job nextAvailableJob;
|
Job nextAvailableJob;
|
||||||
|
|
||||||
@ -61,7 +59,7 @@ public class JobQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setGroupIdAvailable(String groupId) {
|
synchronized void setGroupIdAvailable(String groupId) {
|
||||||
if (groupId != null) {
|
if (groupId != null) {
|
||||||
activeGroupIds.remove(groupId);
|
activeGroupIds.remove(groupId);
|
||||||
notifyAll();
|
notifyAll();
|
||||||
|
@ -1,5 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (C) 2014 Open Whisper Systems
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
package org.whispersystems.jobqueue.dependencies;
|
package org.whispersystems.jobqueue.dependencies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface responsible for injecting dependencies into Jobs.
|
||||||
|
*/
|
||||||
public interface DependencyInjector {
|
public interface DependencyInjector {
|
||||||
public void injectDependencies(Object object);
|
public void injectDependencies(Object object);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,10 @@ import java.io.IOException;
|
|||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of {@link org.whispersystems.jobqueue.persistence.JobSerializer} that uses
|
||||||
|
* Java Serialization.
|
||||||
|
*/
|
||||||
public class JavaJobSerializer implements JobSerializer {
|
public class JavaJobSerializer implements JobSerializer {
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
@ -21,9 +21,27 @@ import org.whispersystems.jobqueue.Job;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JobSerializer is responsible for serializing and deserializing persistent jobs.
|
||||||
|
*/
|
||||||
public interface JobSerializer {
|
public interface JobSerializer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize a job object into a string.
|
||||||
|
* @param job The Job to serialize.
|
||||||
|
* @return The serialized Job.
|
||||||
|
* @throws IOException if serialization fails.
|
||||||
|
*/
|
||||||
public String serialize(Job job) throws IOException;
|
public String serialize(Job job) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize a String into a Job.
|
||||||
|
* @param keys Optional encryption keys that could have been used.
|
||||||
|
* @param encrypted True if the job was encrypted using the encryption keys.
|
||||||
|
* @param serialized The serialized Job.
|
||||||
|
* @return The deserialized Job.
|
||||||
|
* @throws IOException If the Job deserialization fails.
|
||||||
|
*/
|
||||||
public Job deserialize(EncryptionKeys keys, boolean encrypted, String serialized) throws IOException;
|
public Job deserialize(EncryptionKeys keys, boolean encrypted, String serialized) throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,9 @@ import android.net.NetworkInfo;
|
|||||||
|
|
||||||
import org.whispersystems.jobqueue.dependencies.ContextDependent;
|
import org.whispersystems.jobqueue.dependencies.ContextDependent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A requirement that is satisfied when a network connection is present.
|
||||||
|
*/
|
||||||
public class NetworkRequirement implements Requirement, ContextDependent {
|
public class NetworkRequirement implements Requirement, ContextDependent {
|
||||||
|
|
||||||
private transient Context context;
|
private transient Context context;
|
||||||
|
@ -18,6 +18,12 @@ package org.whispersystems.jobqueue.requirements;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Requirement that must be satisfied before a Job can run.
|
||||||
|
*/
|
||||||
public interface Requirement extends Serializable {
|
public interface Requirement extends Serializable {
|
||||||
|
/**
|
||||||
|
* @return true if the requirement is satisfied, false otherwise.
|
||||||
|
*/
|
||||||
public boolean isPresent();
|
public boolean isPresent();
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,22 @@
|
|||||||
*/
|
*/
|
||||||
package org.whispersystems.jobqueue.requirements;
|
package org.whispersystems.jobqueue.requirements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies listeners when a {@link org.whispersystems.jobqueue.requirements.Requirement}'s
|
||||||
|
* state is likely to have changed.
|
||||||
|
*/
|
||||||
public interface RequirementProvider {
|
public interface RequirementProvider {
|
||||||
|
/**
|
||||||
|
* @return The name of the provider.
|
||||||
|
*/
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link org.whispersystems.jobqueue.requirements.RequirementListener} to call when
|
||||||
|
* a {@link org.whispersystems.jobqueue.requirements.Requirement}'s status is likely to
|
||||||
|
* have changed.
|
||||||
|
*
|
||||||
|
* @param listener The listener to call.
|
||||||
|
*/
|
||||||
public void setListener(RequirementListener listener);
|
public void setListener(RequirementListener listener);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user