I have a message stream, where messages comes which I need to process and then store them in database. In Java, I've written polling code which polls stream and consumes messages every 20 seconds.
This is done inside an infinite for-loop, like below:
for (;;) {
try{
//1. Logic for polling.
//2. Logic for processing the message.
//3. Logic for storing the message in database.
Thread.sleep(20000 - <time taken for above 3 steps >);
} catch(Exception E){
//4. Exception handling.
}
}
This logic runs as expected and the stream is polled, but once in a while it hits an exception or something goes wrong and polling stops.
I want to have a mechanism, that as soon as polling stopped, let's say this for loop is not running for 60 seconds, I should receive a mail or ping.
What is the best way to invoke a method if this for loop is not running for 60 seconds?
I am thinking like, each for-loop execution will ping a heartbeat, and when that heartbeat pinging not received from for-loop then a mail sending is invoked.
There are two different reasons why polling stops making progress, and each needs a different approach:
If the logic throws a Throwable other than an Exception, for instance an Error, the catch does not match, and execution will leave the for-loop, and likely reach the thread's UncaughtExceptionHandler, the default implementation of which logs the exception to System.err and terminates the thread. To prevent this, you should catch Throwable rather than Exception.
The second possibility is that some step in your logic doesn't terminate, for instance due to an infinite loop, a deadlock, waiting for I/O operations, or whatever. In this case, you'll want to take a thread dump to see where the thread is stuck. You can automate this as follows:
class Watchdog {
final Duration gracePeriod;
final Thread watchedThread;
volatile Instant lastProgress;
public Watchdog(Duration gracePeriod) {
this.gracePeriod = gracePeriod;
watchedThread = Thread.currentThread();
everythingIsFine();
var t = new Thread(this::keepWatch);
t.setDaemon(true);
t.start();
}
public void everythingIsFine() {
lastProgress = Instant.now();
}
void keepWatch() {
while (true) {
var silence = Duration.between(lastProgress, Instant.now());
if (silence.compareTo(gracePeriod) > 0) {
System.err.println("Watchdog hasn't seen any progress for " + silence.toSeconds() + " seconds. The watched thread is currently at:");
for (var element : watchedThread.getStackTrace()) {
System.err.println("\tat " + element);
}
}
try {
Thread.sleep(gracePeriod);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
while you can use as follows:
public class Test {
void step() throws Exception {
System.in.read();
}
void job() {
var snoopy = new Watchdog(Duration.ofSeconds(2));
for (;;) {
try {
step();
snoopy.everythingIsFine();
Thread.sleep(1000);
} catch (Throwable t) {
System.err.println(t);
}
}
}
public static void main(String[] args) throws Exception {
new Test().job();
}
}
once the grace period elapses, the WatchDog will print something like:
Watchdog hasn't seen any progress for 2 seconds. The watched thread is currently at:
at java.base/java.io.FileInputStream.readBytes(Native Method)
at java.base/java.io.FileInputStream.read(FileInputStream.java:293)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:255)
at java.base/java.io.BufferedInputStream.implRead(BufferedInputStream.java:289)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:276)
at stackoverflow.Test.step(Test.java:48)
at stackoverflow.Test.job(Test.java:55)
at stackoverflow.Test.main(Test.java:65)
Related
So I have a function which looks like this
ExecutorService executorService = Executors.newFixedThreadPool(2000);
Boolean getMore = true;
try{
While (getMore) {
JSONObject response = getPaginatedResponse();
int[] ar = response.get("something");
if (ar.length > 0) {
// loop through the array and invoke executorService.submit() for each
}
else { getMore = false; }
}
executorService.shutdown();
try {
System.out.println("waiting for tasks to complete, termination starting at : "+java.time.LocalDateTime.now());
executorService.awaitTermination(15, TimeUnit.MINUTES);
} catch (InterruptedException e) {
throw new Exception("loading was interrupted... thread pool timed out!");
}
} catch (Exception) {
System.out.println("Fatal error");
}
My issue is that the each of these threads invoke x number of threads, which in turn each call an API and processes its response, the implementation stops execution after all the "First-level" threads gets fired, but not necessarily all the second level ones, which is crucial for my program, how or where can I invoke the executerService.shutdown() to make sure that all the threads were called.
you can put executorService.shutdown(); inside finally block of exception
I'm hoping some concurrency experts can advise as I'm not looking to rewrite something that likely exists.
Picture the problem; I have a web connection that comes calling looking for their unique computed result (with a key that they provide in order to retrieve their result) - however the result may not have been computed YET so I would like for the connection to wait (block) for UP TO n seconds before giving up and telling them I don't (yet) have their result (computation time to calculate value is non deterministic). something like;
String getValue (String key)
{
String value = [MISSING_PIECE_OF_PUZZLE].getValueOrTimeout(key, 10, TimeUnit.SECONDS)
if (value == null)
return "Not computed within 10 Seconds";
else
return "Value was computed and was " + value;
}
and then have another thread (the computation threads)that is doing the calculations - something like ;
public void writeValues()
{
....
[MISSING_PIECE_OF_PUZZLE].put(key, computedValue)
}
In this scenario, there are a number of threads working in the background to compute the values that will ultimately be picked up by a web connections. The web connections have NO control or authority over what is computed and when the computations execute - as I've said - this is being done in a pool in the background but these thread can publish when the computation has completed (how they do is the gist of this question). The publish message maybe consumed or not - depending if any subscribers are interested in this computed value.
As these are web connections that will be blocking - i could potentially have 1000s of concurrent connections waiting (subscribing) for their specific computed value so such a solution needs to be very light on blocking resources. The closest i've came to is this SO question which I will explore further but wanted to check i'm not missing something blindly obvious before writing this myself?
I think you should use a Future it gives an ability to compute data in a separate thread and block for the requested time period while waiting for an answer. Notice how it throws an exception if more then 3 seconds passed
public class MyClass {
// Simulates havy work that takes 10 seconds
private static int getValueOrTimeout() throws InterruptedException {
TimeUnit.SECONDS.sleep(10);
return 123;
}
public static void main(String... args) throws InterruptedException, ExecutionException {
Callable<Integer> task = () -> {
Integer val = null;
try {
val = getValueOrTimeout();
} catch (InterruptedException e) {
throw new IllegalStateException("task interrupted", e);
}
return val;
};
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(task);
System.out.println("future done? " + future.isDone());
try {
Integer result = future.get(3, TimeUnit.SECONDS);
System.out.print("Value was computed and was : " + result);
} catch (TimeoutException ex) {
System.out.println("Not computed within 10 Seconds");
}
}
}
After looking in changes in your question I wanted to suggest a different approach using BlockingQueue in such case the producer logic completely separated from the consumer so you could do something like this
public class MyClass {
private static BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
private static Map<String, String> dataComputed = new ConcurrentHashMap<>();
public static void writeValues(String key) {
Random r = new Random();
try {
// Simulate working for long time
TimeUnit.SECONDS.sleep(r.nextInt(11));
String value = "Hello there fdfsd" + Math.random();
queue.offer(value);
dataComputed.putIfAbsent(key, value);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static String getValueOrTimeout(String key) throws InterruptedException {
String result = dataComputed.get(key);
if (result == null) {
result = queue.poll(10, TimeUnit.SECONDS);
}
return result;
}
public static void main(String... args) throws InterruptedException, ExecutionException {
String key = "TheKey";
Thread producer = new Thread(() -> {
writeValues(key);
});
Thread consumer = new Thread(() -> {
try {
String message = getValueOrTimeout(key);
if (message == null) {
System.out.println("No message in 10 seconds");
} else {
System.out.println("The message:" + message);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
consumer.start();
producer.start();
}
}
With that said I have to agree with #earned that making the client thread to wait is not a good approach instead I would suggest using a WebSocket which gives you an ability to push data to the client when it is ready you can find lots of tutorials on WebSocket here is one for example ws tutorial
I have a simple JAVA code it will just print hello after compile and Run the Program. But I want to print one message after successful completion. Is this possible? If yes than how?
Although, the following code snippet is way too overkill for your task but, expanding on my comment - you may want to submit a custom task to a class
which implements Callable.
public class Main {
public static void main(String[] args) {
final ExecutorService executorService;
final Future<Integer> future;
final int statusCode;
executorService = Executors.newFixedThreadPool(1);
future = executorService.submit(new TextMessagePrinter());
try {
statusCode = future.get();
if (statusCode == 10) { // Printed successfully
System.out.println("JOB DONE. EXITING...");
Runtime.getRuntime().exit(0); // A zero status code indicates normal termination.
} else {
System.out.println("ERR...SOMETHING WEIRD HAPPENED!");
Runtime.getRuntime().exit(statusCode); // A non-zero status code indicates abnormal termination.
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executorService.shutdownNow();
}
}
}
class TextMessagePrinter implements Callable<Integer> {
public Integer call() {
Integer STATUS_CODE;
try {
System.out.println("Printing hello..."); // Try printing something
System.out.println("Dividing 6 by 0 gives us: " + 6 / 0); // And then you try to do something knowing which will result in an exception
STATUS_CODE = 10; // Indicates success.
} catch (ArithmeticException e) {
STATUS_CODE = 20; // Indicates failure...setting status code to 20.
}
return STATUS_CODE;
}
}
Running the above code on my IDE gives me the following output:
When the exception happens
(Note the status code set in the catch block getting printed when the process finishes):
No exception happens, everything happens fine:
(Comment the following line)
System.out.println("Dividing 6 by 0 gives us: " + 6 / 0);
If you mean completion of the application's Runtime, I think you are looking for the answer in this StackOverflow question: Java Runtime Shutdown Hook.
Or if you want to do what is in the question title and do something after building, then you may consider a build automation tool, like Maven.
I have a Runnable that watches for data to send out UDP as well as to send a keep alive every 10 seconds. The process is taking 100% CPU. I tried setting the thread to low priority but didn't seem to make any difference.
private Runnable keepAliveRunnable = new Runnable() {
long nextSend = 0;
byte[] sendData;
#Override
public void run() {
if(DEBUG)
System.out.println("Starting keepAlive.");
while (socket != null) {
synchronized (socketLock) {
try {
sendData = sendQueue.poll();
if (sendData != null) {
socket.send(new DatagramPacket(sendData, sendData.length,
InetAddress.getByName(Main.ipAddress), 10024));
} else if (nextSend < System.currentTimeMillis()) {
if(DEBUG && nextSend < System.currentTimeMillis())
System.out.println("Update keepAlive.");
// Send /xremote
socket.send(new DatagramPacket(("/xremote").getBytes(),
("/xremote").getBytes().length,
InetAddress.getByName(Main.ipAddress), 10024));
nextSend = System.currentTimeMillis() + keepAliveTimeout;
// Send /info
socket.send(new DatagramPacket(("/info").getBytes(),
("/info").getBytes().length,
InetAddress.getByName(Main.ipAddress), 10024));
}
} catch (IOException e) {
e.printStackTrace();
if(!e.getMessage().contains("Socket closed")) {
e.printStackTrace();
}
}
}
}
System.out.println("keepAliveRunnable ended.");
}
};
Make sendQueue a LinkedBlockingQueue, and use poll timeouts.
You are busy waiting, which essentially forces your app to keep running the same logic over and over instead of giving the CPU back to the system.
Don't count on your own implementation of checking the time, that is unreliable and can result in what you're seeing. Instead, use blockingQueue.poll(10, TimeUnit.SECONDS), which automatically handles returning the CPU to the system.
I made a few other changes to your code; I put the duplicated packet construction code in a separate method, and I wrapped the synchronization of the socket only when the socket is actually being used. Notice how much cleaner it is when you let the queue do the work for you.
while(socket != null) {
try {
sendData = sendQueue.poll(10, TimeUnit.SECONDS);
if (sendData != null) {
sendPacket(sendData);
} else {
sendPacket("/xremote".getBytes());
sendPacket("/info".getBytes());
}
} catch (IOException e) {
e.printStackTrace();
if (!e.getMessage().contains("Socket closed")) {
e.printStackTrace();
}
}
}
And here's sendPacket:
private static void sendPacket(byte[] data) throws UnknownHostException, IOException {
// Note, you probably only have to do this once, rather than looking it up every time.
InetAddress address = InetAddress.getByName(Main.ipAddress);
DatagramPacket p = new DatagramPacket(data, data.length, address, 10024);
synchronized(socketLock) {
socket.send(p);
}
}
You should add a Thread.sleep() at the bottom of your while loop, to slow down your loop. As is, you're busy-waiting and churning the CPU while you wait for the nextSend time to be reached. Thread.sleep() will actually pause the thread, allowing other threads and processes to use the CPU while this one sleeps.
Sleeping for a 10th of a second (100 milliseconds) should be a good amount of time to sleep between iterations of your loop, if your goal is to actually do work every 10 seconds.
There are more advanced techniques for dispatching work every so often, like ScheduledExecutorService, which you could also consider using. But for a small application the pattern you're using is fine, just avoid busy waiting.
I think rather than polling your sendqueue, its better to use semaphore signal and wait.
When a packet is inserted in sendqueue, call semaphore signal.
Use semaphore wait instead of call to sendqueue.poll().
I assume you have separate threads for pushing popping data from sendqueue.
This is standard consumer producer problem. https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem
After digging through my code, I had realized that over time I had whittled down the number of processes sending data to 1 (duh) so I really didn't need the runnable as I could just send the data directly. I also set up a separate runnable and used ScheduledExecutor. I thought I would just put that here for other to see. Durron597's code is a little prettier but since I'm only sending two packs now I decided to just put the code together.
// In main
pingXAir();
private void pingXAir() {
System.out.println("Start keepAlive");
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(keepAliveRunnable, 0, 5, TimeUnit.SECONDS);
}
private Runnable keepAliveRunnable = new Runnable() {
#Override
public void run() {
synchronized (socketLock) {
try {
if (DEBUG)
System.out.println("Update keepAlive.");
// Send /xremote
socket.send(new DatagramPacket(("/xremote").getBytes(),
("/xremote").getBytes().length,
InetAddress.getByName(Main.ipAddress), 10024));
// Send /info
socket.send(new DatagramPacket(("/info").getBytes(),
("/info").getBytes().length,
InetAddress.getByName(Main.ipAddress), 10024));
} catch (IOException e) {
e.printStackTrace();
if (!e.getMessage().contains("Socket closed")) {
e.printStackTrace();
}
}
}
}
};
I m having a server code to process an image.
Now there are n number of requests which tries to execute the code which results in OutOfMemory error or the server to hang and the server goes to not responding state.
To stop the code from executing at once all the requests I m limiting to execute the code one at a time using the below method where i have a variable
if the variable is 10 then wait for the variable to come at 0
if at 0 then set it to 10 then execute the code
run the code and finally set i to 0
The code here -
static newa.Counter cn;
public int getCounta() {
return cn.getCount();
}
public void setCounta(int i) {
cn = new newa.Counter();
cn.setCount(i);
}
at the function i m doing this -
public BufferedImage getScaledImage(byte[] imageBytes)
{
int i=0;
Boolean b = false;
BufferedImage scaledImage = null;
newa.NewClass1 sc = new newa.NewClass1();
try {
sc.getCounta();
} catch (NullPointerException ne) {
sc.setCounta(0);
}
i = sc.getCounta();
if(i==0)
{
sc.setCounta(10);
b = true;
}
else
{
while( b == false)
{
try
{
Thread.sleep(2000);
i = sc.getCounta();
if( i==0)
{
sc.setCounta(10);
b = true;
System.out.println("Out of Loop");
}
} catch (InterruptedException ex) {
System.out.println("getScaledImage Thread exception: " + ex);
}
}
}
..... execute further code
try { } catch { } finally { sc.setCounta(0); }
}
Is there any way I can have this simplified using the Runnable interface or something as I don't know how to do multi-threading.
Forget about the counter and use a synchronized method. Changed your method head to this:
public synchronized BufferedImage getScaledImage(byte[] imageBytes)
This lets all the threads entering the method wait until no other thread is executing the method.
If you want only a small number of threads doing the processing you can use Executor framework to have a thread pool of 10 threads. This will ensure that at one time maximum of 10 threads will be processing the requests.