Skip to content

Instantly share code, notes, and snippets.

@vvakame
Created April 15, 2011 11:05
Show Gist options
  • Save vvakame/921529 to your computer and use it in GitHub Desktop.
Save vvakame/921529 to your computer and use it in GitHub Desktop.
package net.vvakame.appengine.deferred.sample;
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Map;
import net.vvakame.appengine.deferred.annotation.Deferred;
import net.vvakame.appengine.deferred.util.DeferredUtil;
import com.google.appengine.api.datastore.Key;
/**
* なんか適当な処理.
*
* @author vvakame
*/
public class SampleService {
static int count = 0;
/**
* テスト用メソッド
* @param sample
* @return 適当
* @author vvakame
*/
@Deferred
public static int hoge(long sample) {
try {
if ((count % 4) == 0) {
count += sample;
throw new IllegalStateException();
} else {
count += sample;
}
} catch (IllegalStateException e) {
DeferredUtil.throwWithValue(count, "error!", e);
}
return count;
}
/**
* テスト用メソッド
* @param keyBy
* @return 適当
* @author vvakame
*/
@Deferred
public static List<Key> getKeys(Key keyBy) {
return null;
}
/**
* テスト用メソッド
* @param key
* @param keys
* @return 適当
* @author vvakame
*/
@Deferred
public static Map<String, List<? extends Number>> generics(Key key, List<Key> keys) {
return null;
}
/**
* テスト用メソッド
* @author vvakame
* @throws ConcurrentModificationException
*/
@Deferred
public static void throwRuntimeException() throws ConcurrentModificationException {
}
/**
* テスト用メソッド
* @throws Exception
* @author vvakame
*/
@Deferred
public static void throwException() throws Exception {
}
/**
* テスト用メソッド
* @return 適当
* @author vvakame
*/
@Deferred
public static boolean returnBoolean() {
return false;
}
/**
* テスト用メソッド
* @return 適当
* @author vvakame
*/
@Deferred
public static char returnChar() {
return 'a';
}
/**
* テスト用メソッド
* @return 適当
* @author vvakame
*/
@Deferred
public static byte returnByte() {
return 0;
}
/**
* テスト用メソッド
* @return 適当
* @author vvakame
*/
@Deferred
public static short returnShort() {
return 0;
}
/**
* テスト用メソッド
* @return 適当
* @author vvakame
*/
@Deferred
public static int returnInteger() {
return 0;
}
/**
* テスト用メソッド
* @return 適当
* @author vvakame
*/
@Deferred
public static long returnLong() {
return 0;
}
/**
* テスト用メソッド
* @return 適当
* @author vvakame
*/
@Deferred
public static Float returnFloat() {
return 0.0f;
}
/**
* テスト用メソッド
* @return 適当
* @author vvakame
*/
@Deferred
public static Double returnDouble() {
return 0.0;
}
}
package net.vvakame.appengine.deferred.sample;
import net.vvakame.appengine.deferred.util.PersistentException;
import com.google.appengine.api.taskqueue.DeferredTask;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
/**
* {@link SampleService} を遅延処理させる.
*
* @author vvakame
*/
public class SampleServiceDeferred {
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @param key
* @param keys
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static java.util.Map<java.lang.String,java.util.List<? extends java.lang.Number>> generics(com.google.appengine.api.datastore.Key key,java.util.List<com.google.appengine.api.datastore.Key> keys) {
try {
return SampleService.generics(key,keys);
} catch (PersistentException e) {
DeferredTask deferred = new Task_generics_Key_List(key,keys);
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_generics_Key_List implements DeferredTask {
com.google.appengine.api.datastore.Key key;
java.util.List<com.google.appengine.api.datastore.Key> keys;
Task_generics_Key_List(com.google.appengine.api.datastore.Key key,java.util.List<com.google.appengine.api.datastore.Key> keys) {
this.key = key;
this.keys = keys;
}
@Override
public void run() {
try{
SampleService.generics(key,keys);
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @param keyBy
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static java.util.List<com.google.appengine.api.datastore.Key> getKeys(com.google.appengine.api.datastore.Key keyBy) {
try {
return SampleService.getKeys(keyBy);
} catch (PersistentException e) {
DeferredTask deferred = new Task_getKeys_Key(keyBy);
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_getKeys_Key implements DeferredTask {
com.google.appengine.api.datastore.Key keyBy;
Task_getKeys_Key(com.google.appengine.api.datastore.Key keyBy) {
this.keyBy = keyBy;
}
@Override
public void run() {
try{
SampleService.getKeys(keyBy);
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @param sample
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static int hoge(long sample) {
try {
return SampleService.hoge(sample);
} catch (PersistentException e) {
DeferredTask deferred = new Task_hoge_long(sample);
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return (Integer) e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_hoge_long implements DeferredTask {
long sample;
Task_hoge_long(long sample) {
this.sample = sample;
}
@Override
public void run() {
try{
SampleService.hoge(sample);
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static boolean returnBoolean() {
try {
return SampleService.returnBoolean();
} catch (PersistentException e) {
DeferredTask deferred = new Task_returnBoolean_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return (Boolean) e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_returnBoolean_ implements DeferredTask {
Task_returnBoolean_() {
}
@Override
public void run() {
try{
SampleService.returnBoolean();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static byte returnByte() {
try {
return SampleService.returnByte();
} catch (PersistentException e) {
DeferredTask deferred = new Task_returnByte_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return (Byte) e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_returnByte_ implements DeferredTask {
Task_returnByte_() {
}
@Override
public void run() {
try{
SampleService.returnByte();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static char returnChar() {
try {
return SampleService.returnChar();
} catch (PersistentException e) {
DeferredTask deferred = new Task_returnChar_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return (Character) e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_returnChar_ implements DeferredTask {
Task_returnChar_() {
}
@Override
public void run() {
try{
SampleService.returnChar();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static java.lang.Double returnDouble() {
try {
return SampleService.returnDouble();
} catch (PersistentException e) {
DeferredTask deferred = new Task_returnDouble_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_returnDouble_ implements DeferredTask {
Task_returnDouble_() {
}
@Override
public void run() {
try{
SampleService.returnDouble();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static java.lang.Float returnFloat() {
try {
return SampleService.returnFloat();
} catch (PersistentException e) {
DeferredTask deferred = new Task_returnFloat_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_returnFloat_ implements DeferredTask {
Task_returnFloat_() {
}
@Override
public void run() {
try{
SampleService.returnFloat();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static int returnInteger() {
try {
return SampleService.returnInteger();
} catch (PersistentException e) {
DeferredTask deferred = new Task_returnInteger_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return (Integer) e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_returnInteger_ implements DeferredTask {
Task_returnInteger_() {
}
@Override
public void run() {
try{
SampleService.returnInteger();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static long returnLong() {
try {
return SampleService.returnLong();
} catch (PersistentException e) {
DeferredTask deferred = new Task_returnLong_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return (Long) e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_returnLong_ implements DeferredTask {
Task_returnLong_() {
}
@Override
public void run() {
try{
SampleService.returnLong();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @return 実行結果(非同期化した場合も帰る)
* @author vvakame
*/
public static short returnShort() {
try {
return SampleService.returnShort();
} catch (PersistentException e) {
DeferredTask deferred = new Task_returnShort_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
return (Short) e.getValue();
}
}
@SuppressWarnings("serial")
static class Task_returnShort_ implements DeferredTask {
Task_returnShort_() {
}
@Override
public void run() {
try{
SampleService.returnShort();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @throws java.lang.Exception
* @author vvakame
*/
public static void throwException() throws java.lang.Exception {
try {
SampleService.throwException();
} catch (PersistentException e) {
DeferredTask deferred = new Task_throwException_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
}
}
@SuppressWarnings("serial")
static class Task_throwException_ implements DeferredTask {
Task_throwException_() {
}
@Override
public void run() {
try{
SampleService.throwException();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
/**
* {@link SampleService} の同名メソッドの失敗時非同期化.
*
* @throws java.util.ConcurrentModificationException
* @author vvakame
*/
public static void throwRuntimeException() throws java.util.ConcurrentModificationException {
try {
SampleService.throwRuntimeException();
} catch (PersistentException e) {
DeferredTask deferred = new Task_throwRuntimeException_();
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withPayload(deferred));
}
}
@SuppressWarnings("serial")
static class Task_throwRuntimeException_ implements DeferredTask {
Task_throwRuntimeException_() {
}
@Override
public void run() {
try{
SampleService.throwRuntimeException();
}catch(Exception e){
if(e instanceof RuntimeException){
throw (RuntimeException)e;
}else{
throw new RuntimeException(e);
}
}
}
}
}
@vvakame
Copy link
Author

vvakame commented Apr 15, 2011

SampleService.java が手書きクラスで、@deferredを付けたメソッドは自動的にSampleServiceDeferred.javaが生成されて同名同シグネチャのメソッドが生成される。
例外が発生した時、DeferredUtil.throwWithValue(count, "error!", e); ってやるとDeferredTaskがTQにツッコまれ再実行される。valueを与えると処理が成功したかのように継続できる。冪等な処理を書いていて、計算順序が変更可能なら問題なく同期的に処理されたように見えるはず。
どうやってテストすればいいのかわからない…。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment