Help us understand the problem. What is going on with this article?

AppEngine の便利 JobQueue クラス DeferredTask の使い方

More than 3 years have passed since last update.

DeferredTask とは

TaskQueue を、URL ハンドラの実装なしに使える便利クラスです。

通常、TaskQueue は指定された URL を叩いて Task を実行します。
この挙動は厳密な設計には便利ですが、Task の種類の数だけ URL を制御しなければなりません。
新たにルーティングを設定し、新たにコントローラメソッドを実装する必要があります。

これらを廃し、より気楽に使えるようにしたのが DeferredTask クラスです。
必要な要素はたった一つ、DeferredTask interface (#run のみ) を実装したクラスのみです。

基本的な使い方

public class SomeTask implements DeferredTask {
    @Override
    public void run() {
        Log.d("SomeTask", "Hello World!");
    }
}

// 登録
final TaskOptions option = TaskOptions.Builder.withPayload(new SomeTask());
QueueFactory.getDefaultQueue().add(option);

パラメータの渡し方

プロパティ持たせて渡します。

public class SomeTask implements DeferredTask {
    private static final Logger logger = Logger.getLogger(SomeTask.class.getSimpleName());

    private final String someParam;

    public SomeTask(String someParam) {
        this.someParam = someParam;
    }

    @Override
    public void run() {
        logger.info("Performing a task with someParam: " + someParam);
    }
}

TaskQueue への登録

インスタンス化し Payload として TaskQueue に登録すれば勝手に処理されます。

final TaskOptions option = TaskOptions.Builder
    .withPayload(new SomeTask("someparamvalue"));
QueueFactory.getDefaultQueue().add(option);

内部的には POST /_ah/queue/__deferred__ でこのタスクをハンドリングしてくれる。
タスクに渡したパラメータはログや TaskQueue の管理画面に出ないので注意。

Task 内でパラメータを Log しておくことをおすすめします。

注意点

DeferredTask は Serializable であることに気を付けてください。内部的には、DeferredTask はシリアライズされて TaskQueue に突っ込まれ、内部的にデシリアライズされて run() されています。

そのため、内部クラスで実装すると、Serializable でないと思われる親クラスへの参照を持ってしまうため、正常に動きません。(多分)
同様の理由で、匿名クラスでの実装も出来ません。文法的には一番便利なのですが…

上記の理由により、親クラスの内部プロパティや、今のメソッドスコープの変数に依存した実装は出来ません。
要は、必要な情報は全て DeferredTask インスタンスに渡してあげてください。

便利な分、シリアライズの面で取り扱いが難しくなっています。この点を注意し、DeferredTask は気軽なタスクで利用しましょう。

TaskQueue について便利情報

○ 秒後とかしたければ countdownMillis(long) を使う。

final TaskOptions option = TaskOptions.Builder
    .withPayload(new SomeTask("someparamvalue"))
    .countdownMillis(10000); // 10 秒後

taskName(String) を使えば TaskQueue 管理画面に名前が出ます(多分)

final TaskOptions option = TaskOptions.Builder
    .withPayload(new SomeTask("someparamvalue"))
    .taskName("SomeTask");
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away