package restservices.publish;
import java.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;
import javax.servlet.AsyncContext;
import javax.servlet.ServletOutputStream;
import com.mendix.thirdparty.org.json.JSONObject;
import restservices.RestServices;
import restservices.util.RestServiceRuntimeException;
class ChangeLogConsumer {
static long nextId = 1L;
private final String id = "FeedRequest#" + nextId++;
final private LinkedBlockingQueue<JSONObject> pendingInstructions = new LinkedBlockingQueue<JSONObject>(RestServices.MAXPOLLQUEUE_LENGTH);
final private AsyncContext continuation;
private boolean completeAfterFirst;
private ChangeLogManager changeLogManager;
public ChangeLogConsumer(AsyncContext asyncContext, boolean completeAfterFirst, ChangeLogManager changeLogManager) {
this.continuation = asyncContext;
this.completeAfterFirst = completeAfterFirst;
this.changeLogManager = changeLogManager;
}
public void addInstruction(JSONObject json)
{
if (RestServices.LOGPUBLISH.isDebugEnabled())
RestServices.LOGPUBLISH.debug(this.id + " received instruction " + json.toString());
if (!pendingInstructions.offer(json))
throw new RestServiceRuntimeException(this.id + " dropped message; maximum queue size exceeded");
writePendingChanges();
}
private void writePendingChanges() {
//MWE: hmm... printwriter doesn't do the job!
//PrintWriter writer = new PrintWriter(continuation.getServletResponse().getOutputStream());
JSONObject instr = null;
try {
while(null != (instr = pendingInstructions.poll())) {
RestServices.LOGPUBLISH.debug("Publishing " + instr);
ServletOutputStream out = continuation.getResponse().getOutputStream();
out.write("\r\n".getBytes(RestServices.UTF8));
out.write(instr.toString().getBytes(RestServices.UTF8));
}
continuation.getResponse().flushBuffer();
if (completeAfterFirst) //return ASAP
this.complete();
} catch (IOException e) {
throw new RestServiceRuntimeException("Failed to write changes to" + id, e);
}
}
void complete() {
try {
this.continuation.complete();
}
catch (Throwable e) {
RestServices.LOGPUBLISH.warn("Failed to complete " + id + ": " + e.getMessage(), e);
}
changeLogManager.unregisterConsumer(this);
}
}