package com.netifera.platform.tasks.internal;
import java.util.ArrayList;
import java.util.List;
import com.netifera.platform.api.dispatcher.IMessenger;
import com.netifera.platform.api.dispatcher.MessengerException;
import com.netifera.platform.api.dispatcher.ProbeMessage;
import com.netifera.platform.api.log.ILogger;
import com.netifera.platform.api.tasks.ITaskOutput;
import com.netifera.platform.api.tasks.ITaskStatus;
import com.netifera.platform.api.tasks.TaskOutputMessage;
import com.netifera.platform.tasks.messages.TaskChangedMessage;
public class TaskOutputHelper {
private IMessenger messenger;
private final Task task;
private final ILogger logger;
TaskOutputHelper(Task task, IMessenger messenger, ILogger logger) {
this.task = task;
this.messenger = messenger;
this.logger = logger;
}
private final List<ITaskOutput> pendingOutput = new ArrayList<ITaskOutput>();
private boolean changePending;
synchronized IMessenger getMessenger() {
return messenger;
}
void changed() {
if(messenger == null) {
return;
}
final TaskChangedMessage message = new TaskChangedMessage(
new ITaskStatus[] { task.getStatus() });
if(!transmitMessage(message)) {
changePending = true;
}
}
synchronized void setMessenger(IMessenger newMessenger) {
/* first send pending output if any */
if(!pendingOutput.isEmpty()) {
TaskOutputMessage outputMessage = new TaskOutputMessage();
/* send all the output in a single message */
for(ITaskOutput output : pendingOutput) {
outputMessage.addOutput(output);
}
/* If the message is sent successfully pending output are removed.
* Otherwise messenger will be null after returning from transmitMessage */
messenger = newMessenger;
if(transmitMessage(outputMessage)) {
pendingOutput.clear();
}
}
if(changePending) {
changed();
changePending = false;
}
}
void addMessage(ITaskOutput output) {
if (!output.isInitialized()) {
output.initialize(task.getStatus().getTaskId());
}
if(!transmitMessage(new TaskOutputMessage(output))) {
storeOutput(output);
}
}
private synchronized boolean transmitMessage(ProbeMessage message) {
if (messenger == null) {
/* can't send, store. */
return false;
}
try {
logger.debug("Sending ProbeMessage: " + message);
messenger.emitMessage(message);
return true;
} catch (MessengerException e) {
logger.warning("Send ProbeMessage failed", e);
/* can't send, store. */
messenger = null;
return false;
}
}
private void storeOutput(ITaskOutput output) {
/* commands are stored if they can not be sent. A queue could be used here. */
pendingOutput.add(output);
}
}