I have a Java program that reads text files and processes them sequentially and on completion of each file a mail is triggered in a separate thread (using runnable). I have configured this program as a cron job in crontab to run every 15 mins.
The cron does not get triggered if the child thread of the last job run takes more than 20 minutes to send the email. How can I have the job triggered every 15 minutes, even if the last child thread is still executing?
Below is the code used::
EpdFeedLoader.java
public class EpdFeedLoader {
public static void main(String[] args) throws Exception {
startProcess(feedFile);
}
public static void startProcess(BatchFeedFile feedFile) {
EpdBatchLoader epdBatchLoader = new EpdBatchLoader(feedFile);
epdBatchLoader.execute();
}
}
EpdBatchLoader.java
public class EpdBatchLoader {
private static void sendDelayedFeedEmail(){
SendDelayedFeedJobStatusMail delayedFeedEmail = new SendDelayedFeedJobStatusMail();
delayedFeedEmail.setParameters(//parameters for my email method);
Thread delayedFeedThread = new Thread(delayedFeedEmail);
delayedFeedThread.start();
}
}
SendDelayedFeedJobStatusMail.java
public class SendDelayedFeedJobStatusMail implements Runnable {
private MailRequestDTO mailRequestDTO;
public void setParameters(MailRequestDTO mailRequestDTO){
this.mailRequestDTO = mailRequestDTO;
}
public void sendMail() {
boolean isSend = false;
message.setSubject(subject);
message.setSentDate(Utils.getDateInTimeZone(mailRequestDTO.getCountryCode(),new Date()));
message.setContent(mailRequestDTO.getMessageContent(), "text/html");
message.addHeader("Content-Transfer-Encoding", "7bit");
attachInlineImages(message, mailRequestDTO.getInlineImageMap());
ConfigUtils.logger.info("Ready to Send Delayed Feed Receipt Email for Process Code : " + mailRequestDTO.getProcessCode().toString());
Transport.send(message);
isSend = true;
ConfigUtils.logger.info("Delayed Feed Receipt Email Sent Successfully for Process Code : " + mailRequestDTO.getProcessCode().toString());
}
#Override
public void run(){
this.sendMail();
}
}
Related
I'm trying to build a system in which I can connect some devices to a server over the internet.
I want to stream some data over CoAP (10-30FPS), frame size = 3KB.
Firstly, I used Aiocoap, it sends up to 100FPS but uses too much CPU,
requests are NON, got low lose rate in Aiocoap,
while Eclipse/Californium could not send more than 3FPS,
when i use higher FPS, either I receive only the first block of each message or receiving nothing, also not ordered most of the times.
I was wondering if this is the real performance of Californium or am I using it in a wrong way?
I will share some code:
server.java
static class CoapObserverServer extends CoapResource {
int i = -1;
public CoapObserverServer() {
super("alarm");
setObservable(true); // enable observing
setObserveType(Type.NON); // configure the notification type to CONs
getAttributes().setObservable(); // mark observable in the Link-Format
System.out.println(this);
// schedule a periodic update task, otherwise let events call changed()
//new Timer().schedule(new UpdateTask(), 0, 1000/2);
}
private class UpdateTask extends TimerTask {
#Override
public void run() {
changed(); // notify all observers
}
}
#Override
public void handleGET(CoapExchange exchange) {
// the Max-Age value should match the update interval
exchange.setMaxAge(1);
//++i;
int leng = 2000;
String s = "" + i + "-" + fillString('X', leng - 1 - Integer.toString(i).len>
exchange.respond(s);
}
public static String fillString(char fillChar, int count){
// creates a string of 'x' repeating characters
char[] chars = new char[count];
while (count>0) chars[--count] = fillChar;
return new String(chars);
}
#Override
public void handleDELETE(CoapExchange exchange) {
delete(); // will also call clearAndNotifyObserveRelations(ResponseCode.NOT_>
exchange.respond(ResponseCode.DELETED);
}
#Override
public void handlePUT(CoapExchange exchange) {
exchange.accept();
int format = exchange.getRequestOptions().getContentFormat();
if (format == MediaTypeRegistry.TEXT_PLAIN) {
// ...
String plain = exchange.getRequestText();
try{
i = Integer.valueOf(plain);
} catch(NumberFormatException ex){
System.out.println("error converting string"+ plain);
}
exchange.respond(ResponseCode.CHANGED);
changed(); // notify all observers
}
}
Observer.java
private static final File CONFIG_FILE = new File("Californium3.properties");
private static final String CONFIG_HEADER = "Californium CoAP Properties file for client";
private static final int DEFAULT_MAX_RESOURCE_SIZE = 2 * 1024 * 1024; // 2 MB
private static final int DEFAULT_BLOCK_SIZE = 512;
static {
CoapConfig.register();
UdpConfig.register();
}
private static DefinitionsProvider DEFAULTS = new DefinitionsProvider() {
#Override
public void applyDefinitions(Configuration config) {
config.set(CoapConfig.MAX_RESOURCE_BODY_SIZE, DEFAULT_MAX_RESOURCE_SIZE);
config.set(CoapConfig.MAX_MESSAGE_SIZE, DEFAULT_BLOCK_SIZE);
config.set(CoapConfig.PREFERRED_BLOCK_SIZE, DEFAULT_BLOCK_SIZE);
}
};
private static class AsynchListener implements CoapHandler {
#Override
public void onLoad(CoapResponse response) {
System.out.println( response.getResponseText() );
}
#Override
public void onError() {
System.err.println("Error");
}
}
/*
* Application entry point.
*/
public static void main(String args[]) {
Configuration config = Configuration.createWithFile(CONFIG_FILE, CONFIG_HEADER, DEFAULTS);
Configuration.setStandard(config);
URI uri = null; // URI parameter of the request
if (args.length > 0) {
// input URI from command line arguments
try {
uri = new URI(args[0]);
} catch (URISyntaxException e) {
System.err.println("Invalid URI: " + e.getMessage());
System.exit(-1);
}
CoapClient client = new CoapClient(uri);
client.useNONs();
// observe
AsynchListener asynchListener = new AsynchListener();
CoapObserveRelation observation = client.observe(asynchListener);
// User presses ENTER to exit
System.out.println("Press ENTER to exit...");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try { br.readLine(); } catch (IOException e) { }
System.out.println("Exiting...");
observation.proactiveCancel();
}
So i'm controlling the FPS by sending PUT requests with a server that has a counter 0-50.
Not sure, what your doing.
That seems to be wired and not related to RFC7252 nor RFC7641.
CoAP is designed for REST, I don't see any benefit in using it for video streaming.
Using Eclipse/Californium on a Intel n6005 with 16GB RAM, the CoAP/DTLS server runs on about 60000 requests/second. The benchmark uses 2000 clients in parallel.
See also Eclipse/Californium - Benchmarks j5005
Using only one client with CON requests, the performance is mainly limited by the RTT. 30 requests/second should work, if that RTT is accordingly small.
Using NON requests doesn't really help. CoAP RFC7252 defines two layers, a messaging layer and an application layer. NON affects only the messaging layer, but a NON request will wait for it's response, if NSTART-1 should be used.
If your RTT is the issue, you may try to escape that either using requests with "No Server Response" (RFC7967) or multiple NON responses (RFC7641). The first is not intended for fast requests, the second is more a work-around of the initial statement, that CoAP is REST not video-streaming.
So, what is your RTT?
I'm using netty 4.
I have multiple nodes in the network, for simplicity, there are 3 nodes called A, B and C.
Every 10 seconds, A will sends a status message to B and C, B and C also do the same thing, B sends to A and C, C sends to A and B.
Because, sometimes, one node can be blocked (not sure about the reason), for example, A cannot send to B in 10 seconds and C will not receive any message from A.
So, I spawn a different thread for different connection to client:
for (final RemoteNode inpeerNode : inpeerNodes) {
log.debug("Total threads: " + java.lang.Thread.activeCount());
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
sendStatusMessage("a big status message");
}
}
thread.start();
}
and in sendStatusMessage method, it creates a new Eventloop which I don't seem it is right as this is expensive:
public void sendMessage(Integer timeoutInMilliseconds) throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new LoggingHandler(LogLevel.TRACE),
new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()),
new StringDecoder(),
new StringEncoder(),
new WriteTimeoutHandler(7000),
new ClientCommunicatorHandler(message));
}
});
if (timeoutInMilliseconds != null) {
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, timeoutInMilliseconds);
} else {
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 7000);
}
// Start the connection attempt.
bootstrap.connect(host, port).sync().channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
in ClientCommunicatorHandler it has simple code:
class ClientCommunicatorHandler extends SimpleChannelInboundHandler<String> {
private final Logger log = LoggerFactory.getLogger(ClientCommunicatorHandler.class);
private final String messageToSend;
ClientCommunicatorHandler(#NotNull Message message) {
// e.g. send local node's status message to inpeer nodes
this.messageToSend = message.toSerializedString().replace("\n", "").replace("\r", "");
}
#Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ServerCommunicatorHandler.clientChannels.add(ctx.channel());
String message = this.messageToSend;
ctx.writeAndFlush(message + System.lineSeparator())
.addListener(ChannelFutureListener.CLOSE);
}
Up to sometimes, the java application on node A cannot send any status messages anymore. I think some channels to send messages to clients (B and C) are blocked.
Any idea how to avoid that problem? For example, node A can still send to node C in 10 seconds, even if node B is blocked.
I'm building my first telegram bot. It send one message every 5 seconds to the user.
While it sends it to one user it cannot receive update from other chat.
public void foo(msg, Update update){
msg.setChatId(update.getMessage().getChatId());
for (int i = 1; i < links.size(); i++){
msg.setText(links.get(i));
execute(msg);
}
Thread.sleep(wait * 1000);
}
How can I use Thread? I've tried creating multiple thread here
public static void bot(){
ApiContextInitializer.init();
TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
try {
telegramBotsApi.registerBot(new myBot());
} catch (TelegramApiException e) {
e.printStackTrace();
}
But he tries to create multiple bots and fails. Same if this is the runnable function:
How can I do it? I'm Stuck. I cannot create this function in different thread
public void onUpdateReceived(Update update) {
leggi(new SendMessage(), update.getMessage().getText(), update);
//.setChatId(update.getMessage().getChatId())
public void leggi(SendMessage msg, String command, Update update){
if(command.equals("test") {
foo( msg, update);
}
Here the full code... https://github.com/siamoInPochi/Ilsottomarinobot/tree/prova/src/main/java/Ilsottomarinobot
If you spawn a thread for every bot user who wants to receive messages, you will quickly be out of computer's resources in case of high number of users. So I think threads is not a good idea for your task.
In my mind more natural approach is the following:
Find a library with an HTTP server.
Switch from GetUpdates to webhooks.
Schedule send-message-to-user-every-5-seconds tasks to server's event loop.
Send messages every 5 seconds asynchronously.
You can make it with this library https://github.com/pengrad/java-telegram-bot-api
<dependency>
<groupId>com.github.pengrad</groupId>
<artifactId>java-telegram-bot-api</artifactId>
<version>4.2.0</version>
</dependency>
Subscribe to new updates via bot.setUpdatesListener
Send messages via bot.execute(new SendMessage(chatId, link), callback)
Full working example:
static String[] links = {"1", "2", "3"};
static Callback emptyCallback = new Callback() {
#Override
public void onResponse(BaseRequest request, BaseResponse response) {
}
#Override
public void onFailure(BaseRequest request, IOException e) {
e.printStackTrace();
}
};
static void foo(TelegramBot bot, Update update) {
Message message = update.message();
if (message == null) return;
Long chatId = message.chat().id();
for (String link : links) {
bot.execute(new SendMessage(chatId, link), emptyCallback);
}
}
public static void main(String[] args) {
TelegramBot bot = new TelegramBot(TOKEN);
bot.setUpdatesListener(updates -> {
for (Update update : updates) {
foo(bot, update);
}
return UpdatesListener.CONFIRMED_UPDATES_ALL;
});
}
I am doing a project MAS project on jade.
I have 2 agents one to send and one to receive.
How do i make agent 1 send a message to agent 2, for example "1000", and only when agent 2 receives the "1000", agent 2 will reply with for example, "turn off"?
My sugestion is to create agent1 with a RequestPerformer behaviour and agent2 with a CyclicBehaviour to listen messages.
agent1 behaviour content can be like this:
ACLMessage cfp = new ACLMessage(ACLMessage.CFP);
cfp.addReceiver(/*agent2AID*/);
cfp.setContent("1000");
cfp.setConversationId(1000);
cfp.setReplyWith("cfp" + System.currentTimeMillis()); // Unique value
myAgent.send(cfp);
mt = MessageTemplate.and(MessageTemplate.MatchConversationId(targetProduct),
MessageTemplate.MatchInReplyTo(cfp.getReplyWith()));
agent2 behaviour can be like this:
private class CFPServer extends CyclicBehaviour {
private static final long serialVersionUID = 1L;
public void action() {
MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.CFP);
ACLMessage msg = myAgent.receive(mt);
if (msg != null) {
// CFP Message received. Process it
String title = msg.getContent();
ACLMessage reply = msg.createReply();
// The requested fruit is NOT available for sale.
reply.setPerformative(ACLMessage.INFORM);
reply.setContent("turn off");
myAgent.send(reply);
} else {
block();
}
}
}
The related problem is very well discussed and solved in many ways, you can check out the following implementation of a simple Contract Net Protocol where you can find send and reply functions:
https://github.com/clebercbr/tp_cnp/blob/master/src/java/
See that the agent initiator is like agent1 and participant and rejector are like your agent2
I do not recommend to write a cyclic behaviour for messageReception, it will burn the proc for nothing. A simpleBehaviour with done() at false and a block() in the action() is much more efficient.
Regarding your pb, something like that should work :
public class ReceiveMessageBehaviour extends SimpleBehaviour{
private boolean finished=false;
/**
*
* This behaviour is a one Shot.
* It receives a message tagged with an inform performative, print the content in the console and destroy itself if its equal to 1000
* #param myagent
*/
public ReceiveMessageBehaviour(final Agent myagent) {
super(myagent);
}
public void action() {
//1) receive the message
final MessageTemplate msg Template = MessageTemplate.MatchPerformative(ACLMessage.INFORM);
final ACLMessage msg = this.myAgent.receive(msgTemplate);
//2) check its caracts
if (msg != null && msg.getContent().equals("1000")) {
System.out.println(this.myAgent.getLocalName()+"<----Result received from "+msg.getSender().getLocalName()+" ,content= "+msg.getContent());
this.finished=true;
//3) answer
final ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM);
msg2.setSender(this.myAgent.getAID());
msg2.addReceiver(new AID(msg.getSender().getLocalName(), AID.ISLOCALNAME));
msg2.setContent("turn off");
this.myAgent.send(msg2);
}else{
block();// the behaviour goes to sleep until the arrival of a new message in the agent's Inbox.
}
}
public boolean done() { return finished;}
}
I'm new to these JADE related components. But I would like to add the simplest code that we can use to solve this problem using oneShotBehaviour and Cyclicehaviour.
The following code enables simple communication among two clients.
Agent A-Class:-
public class Agent_A extends Agent{
protected void setup(){
System.out.println(getAID().getName()+" is ready.");
addBehaviour(new AgentA_SendMessage());
addBehaviour(new AgentA_ReceiveMessage());
}
public class AgentA_SendMessage extends OneShotBehaviour{
#Override
public void action(){
ACLMessage msg = new ACLMessage(ACLMessage.REQUEST);
msg.addReceiver(new AID("AgentB",AID.ISLOCALNAME));
msg.setContent("1000");
send(msg);
}
}
public class AgentA_ReceiveMessage extends CyclicBehaviour{
Scanner scn2 = new Scanner(System.in);
#Override
public void action(){
ACLMessage remsg = myAgent.receive();
if(remsg!=null){
String reply = remsg.getContent();
System.out.println("Reply From "+remsg.getSender()+" :- "+reply);
}
else{
block();
}
}
}
}
Agent B Class:-
public class Agent_B extends Agent{
protected void setup(){
System.out.println("Hello Seller Agent : "+getAID().getName()+" is ready.");
addBehaviour(new AgentB_ReceiveMessage());
}
public class AgentB_ReceiveMessage extends CyclicBehaviour{
#Override
public void action(){
ACLMessage remsg = myAgent.receive();
if(remsg!=null){
System.out.println(""+remsg);
ACLMessage reply = remsg.createReply();
reply.setPerformative(ACLMessage.INFORM);
String price = remsg.getContent();
reply.setContent("off");
send(reply);
}else{
block();
}
}
}
}
akka novice here. Currently building a system to call some web services and update database... but akka actors are not working exactly as expected...My code sample...
Application Runner
public class Application
{
public static void main(String[] args) throws InterruptedException
{
ActorSystem system = ActorSystem.create("system");
ActorRef master = system.actorOf(Props.create(MasterActor.class));
String url = "http://some-web-service-url";
master.tell(url, ActorRef.noSender());
system.shutdown();
}
}
MasterActor
public class MasterActor extends UntypedActor
{
private final LoggingAdapter log = Logging.getLogger(getContext().system(), getSelf());
private final ActorRef childActor = getContext().actorOf(Props.create(ChildActor.class));
#Override
public void onReceive(Object message) throws Exception
{
if(message instanceof String)
{
childActor.tell(message, getSelf());
}else if(message instanceof Boolean){
log.info("all done");
}else {
unhandled(message);
}
}
}
ChildActor
public class ChildActor extends UntypedActor
{
private final LoggingAdapter log = Logging.getLogger(getContext().system(), getSelf());
#Override
public void onReceive(Object message) throws Exception
{
if (message instanceof String) {
String url = (String) message;
Integer result = getWebServiceResult(url);
log.info("result: {}", result);
getSender().tell(true, getSelf());
}else {
unhandled(message);
}
}
private Integer getWebServiceResult(final String url) throws Exception
{
ExecutionContextExecutor executor = getContext().dispatcher();
Future<Integer> future = Futures.future(new Callable<Integer>()
{
#Override
public Integer call() throws Exception
{
return new HttpClient().fetchData(url); //some web service call
}
}, executor);
return (Integer) Await.result(future, Duration.create(7000, TimeUnit.SECONDS));
}
}
but child actor is unable to send the message to its sender, master...getting this error stack...
[INFO] [03/28/2015 01:02:45.521] [system-akka.actor.default-dispatcher-3] [akka://system/user/$a/$a] result: TheWebservice Result
[INFO] [03/28/2015 01:02:45.528] [system-akka.actor.default-dispatcher-4] [akka://system/user/$a] Message [java.lang.Boolean] from Actor[akka://system/user/$a/$a#1601481298] to Actor[akka://system/user/$a#1257171720] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
I am unable to find what's wrong (spent 3 days)... In my sense this code should work...can you tell me what's I am doing wrong.
Thanks in advance...
You have a race condition. You're shutting down your ActorSystem
system.shutdown();
before the child actor has a chance to send its reply. Remember that more or less everything in akka is asynchronous.
Add, for example, a
Thread.sleep(someTime);
before the shutdown to see the message sent and received.
Just to deal with the exit part :
You could register a shutdown hook like below and shutdown the akka system in it
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
system.shutdown();
}
});
Then enter into a never ending loop as shown below while waiting for the processing to complete so that when it is done processing you press Ctrl + C on your terminal or raise a System.exit(0) within your code.
while(false == shutdownFlag){
Thread.sleep(sometime);
}