Tape

About

Tape is a collection of queue-related classes for Android and Java by Square, Inc.

QueueFile is a lightning-fast, transactional, file-based FIFO. Addition and removal from an instance is an O(1) operation and is atomic. Writes are synchronous; data will be written to disk before an operation returns. The underlying file is structured to survive process and even system crashes and if an I/O exception is thrown during a mutating change, the change is aborted.

An ObjectQueue represents an ordering of arbitrary objects which can be backed either by the filesystem (via QueueFile) or in memory only.

TaskQueue is a special object queue which holds Tasks, objects which have a notion of being executed. Instances are managed by an external executor which prepares and executes enqueued tasks.

Download

Available via Maven or as a downloadable .jar.

Download Latest

Fork Tape on GitHub

<dependency>
    <groupId>com.squareup</groupId>
    <artifactId>tape</artifactId>
    <version>(insert latest)</version>
</dependency>

Examples

For a more complete example of a background image uploader which expands on both of the following examples see the sample Android application in the repository.

Android Task Queue Service

When used on Android, a service is the perfect companion to a TaskQueue since it allows actions to be completed in the background. If the user is uploading new photos to their favorite sharing site, the service will iterate through the queue until all of the upload tasks completes successfully.

/** Listener for starting the upload service when the queue has tasks. */
public class ImageQueueServiceListener implements ObjectQueue.Listener<ImageUploadTask> {
  private final Context context;

  public ImageQueueServiceStarter(Context context) {
    this.context = context;
  }

  @Override public void onAdd(ObjectQueue<ImageUploadTask> queue, ImageUploadTask task) {
    context.startService(new Intent(context, ImageQueueService.class));
  }

  @Override public void onRemove(ObjectQueue<ImageUploadTask> queue) {}
}

/** Service which iterates through pending upload tasks one-by-one. */
public class ImageQueueService extends Service implements ImageUploadTask.Callback {
  private TaskQueue<ImageUploadTask> queue;
  private boolean running;

  @Override public void onCreate() {
    super.onCreate();
    // Obtain TaskQueue here (e.g., through injection)
  }

  @Override public int onStartCommand(Intent intent, int flags, int startId) {
    executeNext();
    return START_STICKY;
  }

  public void executeNext() {
    if (running) return; // Only one task at a time.
    ImageUploadTask task = queue.peek();
    if (task != null) {
      task.execute(this);
      running = true;
      return;
    }
    stopSelf(); // We're done for now.
  }

  @Override public void imageUploadComplete() {
    running = false;
    queue.remove();
    executeNext();
  }
}

GSON Object Converter

As an alternative to traditional object serialization, GSON makes it really easy to convert objects to and from a format that can be written to disk by the FileObjectQueue. This allows for much more flexibility in modifying classes moving forward as well as providing a human-readable storage format.

/** Converter which uses GSON to serialize instances of class T to disk. */
public class GsonConverter<T> implements FileObjectQueue.Converter<T> {
  private final Gson gson;
  private final Class<T> type;

  public GsonConverter(Gson gson, Class<T> type) {
    this.gson = gson;
    this.type = type;
  }

  @Override public T from(byte[] bytes) {
    Reader reader = new InputStreamReader(new ByteArrayInputStream(bytes));
    return gson.fromJson(reader, type);
  }

  @Override public void toStream(T object, OutputStream bytes) throws IOException {
    Writer writer = new OutputStreamWriter(bytes);
    gson.toJson(object, writer);
    writer.close();
  }
}

Contribute

If you would like to contribute code to Tape you can do so through GitHub by forking the repository and sending a pull request.

When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible. Please also make sure your code compiles by running mvn clean verify. Checkstyle failures during compilation indicate errors in your style and can be viewed in the target/checkstyle-result.xml file.

Before your code can be accepted into the project you must also sign the Individual Contributor License Agreement (CLA).

License

Copyright 2012 Square, Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.