package com.workshare.msnos.core;
import static com.workshare.msnos.soup.Shorteners.shorten;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.workshare.msnos.core.receipts.SingleReceipt;
import com.workshare.msnos.core.routing.Router;
import com.workshare.msnos.soup.json.Json;
import com.workshare.msnos.soup.threading.ExecutorServices;
public class Sender {
private static final ExecutorService DEFAULT_EXECUTOR_SERVICE = ExecutorServices.newFixedDaemonThreadPool(getThreadNum());
public static final String SYSP_SENDER_THREADS_NUM = "com.ws.msnos.sender.threads.num";
private static final Logger log = LoggerFactory.getLogger(Sender.class);
private static final Logger proto = LoggerFactory.getLogger("protocol");
public class Transmission implements Runnable {
private Cloud cloud;
private Message message;
private SingleReceipt receipt;
public Transmission(Message message, Cloud cloud) {
super();
this.message = message;
this.cloud = cloud;
this.receipt = SingleReceipt.unknown(message);
}
public Cloud cloud() {
return cloud;
}
public Message message() {
return message;
}
public SingleReceipt receipt() {
return receipt;
}
@Override
public void run() {
sendSync(this.cloud(), this.message(), this.receipt());
}
}
private final Executor executor;
private final Router router;
Sender(Router router) {
this(router, DEFAULT_EXECUTOR_SERVICE);
}
Sender(Router router, Executor executor) {
this.router = router;
this.executor = executor;
}
public Receipt send(final Cloud cloud, final Message amessage) throws MsnosException {
log.debug("Accepted message for delivery {} on cloud {}", amessage, cloud);
Transmission tx = new Transmission(amessage.hopped(), cloud);
executor.execute(tx);
return tx.receipt();
}
void sendSync(final Cloud cloud, final Message message, final SingleReceipt receipt) {
Receipt current = router.send(message);
receipt.update(current);
log.debug("Message {} routed, receipt {}", message, receipt);
logTX(message, receipt.getGate());
}
private static Integer getThreadNum() {
return Integer.getInteger(SYSP_SENDER_THREADS_NUM, 3);
}
private void logTX(Message msg, String gateName) {
if (!proto.isInfoEnabled())
return;
final String muid = shorten(msg.getUuid());
final String payload = Json.toJsonString(msg.getData());
proto.info("TX({}): {} {} {} {} {} {}", gateName, msg.getType(), muid, msg.getWhen(), msg.getFrom(), msg.getTo(), payload);
}
}