com.devebot.opflow.OpflowRpcRequest Maven / Gradle / Ivy
package com.devebot.opflow;
import com.devebot.opflow.exception.OpflowJsonTransformationException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author drupalex
*/
public class OpflowRpcRequest implements Iterator, OpflowTask.Timeoutable {
private final static Logger LOG = LoggerFactory.getLogger(OpflowRpcRequest.class);
private final OpflowLogTracer logTracer;
private final String requestId;
private final String routineId;
private final long timeout;
private final OpflowTask.Listener completeListener;
private OpflowTask.TimeoutWatcher timeoutWatcher;
private long timestamp;
public OpflowRpcRequest(Map options, final OpflowTask.Listener completeListener) {
Map opts = OpflowUtil.ensureNotNull(options);
this.requestId = OpflowUtil.getRequestId(opts);
this.routineId = OpflowUtil.getRoutineId(opts);
if (opts.get("timeout") == null) {
this.timeout = 0;
} else if (opts.get("timeout") instanceof Long) {
this.timeout = (Long)opts.get("timeout");
} else if (opts.get("timeout") instanceof Integer) {
this.timeout = ((Integer)opts.get("timeout")).longValue();
} else {
this.timeout = 0;
}
logTracer = OpflowLogTracer.ROOT.branch("requestId", requestId);
this.completeListener = completeListener;
if (Boolean.TRUE.equals(opts.get("watcherEnabled")) && completeListener != null && this.timeout > 0) {
timeoutWatcher = new OpflowTask.TimeoutWatcher(requestId, this.timeout, new OpflowTask.Listener() {
@Override
public void handleEvent() {
OpflowLogTracer logWatcher = logTracer.copy();
if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(logWatcher
.text("Request timeout event has been raised")
.stringify());
list.add(OpflowMessage.ERROR);
if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(logWatcher
.text("Request raise completeListener (timeout)")
.stringify());
completeListener.handleEvent();
}
});
timeoutWatcher.start();
}
checkTimestamp();
}
public String getRequestId() {
return requestId;
}
public String getRoutineId() {
return routineId;
}
@Override
public long getTimeout() {
if (this.timeout <= 0) return 0;
return this.timeout;
}
@Override
public long getTimestamp() {
return this.timestamp;
}
@Override
public void raiseTimeout() {
this.push(OpflowMessage.ERROR);
}
private final BlockingQueue list = new LinkedBlockingQueue();
private OpflowMessage current = null;
@Override
public boolean hasNext() {
try {
this.current = list.take();
if (this.current == OpflowMessage.EMPTY) return false;
if (this.current == OpflowMessage.ERROR) return false;
return true;
} catch (InterruptedException ie) {
return false;
}
}
@Override
public OpflowMessage next() {
OpflowMessage result = this.current;
this.current = null;
return result;
}
public void push(OpflowMessage message) {
list.add(message);
if (timeoutWatcher != null) {
timeoutWatcher.check();
}
checkTimestamp();
if(isDone(message)) {
OpflowLogTracer pushTrail = logTracer.copy();
if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(pushTrail
.text("Request has completed/failed message")
.stringify());
list.add(OpflowMessage.EMPTY);
if (completeListener != null) {
if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(pushTrail
.text("Request raises completeListener (completed)")
.stringify());
completeListener.handleEvent();
}
if (timeoutWatcher != null) {
timeoutWatcher.close();
}
}
}
public List iterateResult() {
List buff = new LinkedList();
while(this.hasNext()) buff.add(this.next());
return buff;
}
public OpflowRpcResult extractResult() {
return extractResult(true);
}
public OpflowRpcResult extractResult(final boolean includeProgress) {
OpflowLogTracer extractTrail = logTracer;
if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(extractTrail
.text("Extracting result is running")
.stringify());
String workerTag = null;
boolean failed = false;
byte[] error = null;
boolean completed = false;
byte[] value = null;
List steps = new LinkedList();
while(this.hasNext()) {
OpflowMessage msg = this.next();
String status = getStatus(msg);
if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(extractTrail
.put("status", status)
.text("Extracting result receives a message")
.stringify());
if (status == null) continue;
if ("progress".equals(status)) {
if (includeProgress) {
try {
int percent = OpflowJsontool.extractFieldAsInt(msg.getBodyAsString(), "percent");
steps.add(new OpflowRpcResult.Step(percent));
} catch (OpflowJsonTransformationException jse) {
steps.add(new OpflowRpcResult.Step());
}
}
} else
if ("failed".equals(status)) {
workerTag = OpflowUtil.getMessageField(msg, "workerTag");
failed = true;
error = msg.getBody();
} else
if ("completed".equals(status)) {
workerTag = OpflowUtil.getMessageField(msg, "workerTag");
completed = true;
value = msg.getBody();
}
}
if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(extractTrail
.text("Extracting result has completed")
.stringify());
if (!includeProgress) steps = null;
return new OpflowRpcResult(routineId, requestId, workerTag, steps, failed, error, completed, value);
}
private static final List STATUS = Arrays.asList(new String[] { "failed", "completed" });
private boolean isDone(OpflowMessage message) {
String status = getStatus(message);
if (status == null) return false;
return STATUS.indexOf(status) >= 0;
}
private void checkTimestamp() {
timestamp = OpflowUtil.getCurrentTime();
}
public static String getStatus(OpflowMessage message) {
return OpflowUtil.getMessageField(message, "status");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy