package org.zstack.core.asyncbatch;
import org.zstack.header.core.AsyncBackup;
import org.zstack.header.core.Completion;
import org.zstack.header.errorcode.ErrorCode;
import org.zstack.utils.DebugUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* Created by xing5 on 2016/9/11.
*/
public abstract class AsyncLoop<T> {
private AsyncBackup[] backups;
protected List<ErrorCode> errors = new ArrayList<>();
public AsyncLoop(AsyncBackup... backups) {
this.backups = backups;
}
public AsyncLoop() {
backups = new AsyncBackup[]{};
}
protected boolean continueOnError() {
return false;
}
protected abstract Collection<T> collectionForLoop();
protected abstract void run(T item, Completion completion);
protected abstract void done();
protected abstract void error(ErrorCode errorCode);
public void start() {
Collection<T> items = collectionForLoop();
DebugUtils.Assert(items != null, "collectionForLoop cannot return null");
runItem(items.iterator(), new Completion(null, backups) {
@Override
public void success() {
done();
}
@Override
public void fail(ErrorCode errorCode) {
error(errorCode);
}
});
}
private void runItem(Iterator<T> it, Completion completion) {
if (!it.hasNext()) {
completion.success();
return;
}
T i = it.next();
run(i, new Completion(completion) {
@Override
public void success() {
runItem(it, completion);
}
@Override
public void fail(ErrorCode errorCode) {
if (!continueOnError()) {
completion.fail(errorCode);
} else {
errors.add(errorCode);
runItem(it, completion);
}
}
});
}
}