ScheduledExecutorService works in local & test server but only runs once in live server
I have a ScheduledExecutorService to schedule a task to run every 12 hours in a tomcat application. The task calls a REST endpoint and performs some other calculations and returns a result. It works perfectly fine locally and in test server however, it runs only once and never again in the live server. All exceptions are handled and the task takes less than 5 seconds to complete. I have also checked all properties in the server to make sure the time properties are not overridden by other properties. To test locally, I have reduced the delay time to every 10 minutes and this still shows the same behaviour so I’ve ruled time out as the issue. I have looked at other similar questions but none seem to help with this issue.
ScheduledExecutorService only runs once,
JAVA ScheduledExecutorService only runs once when calling a Task<V>,
ScheduledExecutorService only loops once,
ScheduledExecutorService - Task stops running,
ScheduledExecutorService - Ignore already running runnable,
ScheduledExecutorService schedule issue,
Timer vs. ScheduledExecutorService scheduling
Below is my code:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder({"name", "number"})
public class Company {
@JsonProperty("name")
private String name;
@JsonProperty("number")
private int number;
public String getName() {
return this.name;
}
public int getNumber() {
return this.number;
}
@Override
public String toString() {
return new ToStringBuilder(Company.class)
.append("name", this.name)
.append("number", this.number).toString();
}
}
public class CompanyDifference {
private String name;
private int difference;
public CompanyDifference(String name, int difference) {
this.name = name;
this.difference = difference;
}
public String getName() {
return this.name;
}
public int getDifference() {
return this.difference;
}
@Override
public String toString() {
return new ToStringBuilder(CompanyDifference.class)
.append("name", this.name)
.append("difference", this.difference).toString();
}
}
@Singleton
public class TaskRunner {
public void doTask () {
try {
System.out.println("takes 2 sets of json data and returns the difference for each company");
// takes 2 sets of json data and returns the difference for each company
ObjectMapper mapper = new ObjectMapper();
InputStream dataOne = Company.class.getResourceAsStream("/data.json");
InputStream dataTwo = Company.class.getResourceAsStream("/data2.json");
Company companyDataOne = mapper.readValue(dataOne, Company.class);
Company companyDataTwo = mapper.readValue(dataTwo, Company.class);
// Find the difference for each company and map company name to difference
Map<String, Integer> mapDifferenceToCompany = new HashMap<>();
for (int i = 0; i < companyDataOne.length; i++) {
mapDifferenceToCompany.put(companyDataOne[i].getName(), Math.abs(companyDataOne[i].getNumber() - companyDataTwo[i].getNumber()));
}
mapDifferenceToCompany.forEach((key, value) -> System.out.println(String.valueOf(new CompanyDifference(key, value))));
} catch (IOException e) {
logger.info(String.format("Error: Failed to convert json to object with exception %s", e));
throw new TaskSchedulerException("Failed to convert json to object with exception", e);
} catch (Exception e) {
logger.info(String.format("Error: Failed with exception %s", e));
throw new TaskSchedulerException("Failed with exception", e);
}
}
}
@Singleton
public class TaskScheduler {
private final Runnable runnable;
private final ScheduledExecutorService executorService;
private static final Logger logger = LoggerFactory.getLogger(TaskScheduler.class);
@Inject
public TaskScheduler(TaskRunner taskRunner, int initialDelay, int period, String timeUnits) {
this.executorService = Executors.newScheduledThreadPool(1);
this.runnable = taskRunner::doTask;
this.scheduledFuture = this.executorService.scheduleAtFixedRate(this.runnable, initialDelay, period,
TimeUnit.valueOf(timeUnits));
}
public static void main(String args) {
TaskRunner taskRunner = new TaskRunner();
new TaskScheduler(taskRunner, 1, 10, "MINUTES");
}
}
The task runs once on start-up after the initial delay of 1 minute but doesn’t run the next scheduled task. It attempts to run the scheduled task but doesn’t seem to complete the task and after examining the ScheduledThreadPoolExecutor properties in the live server, I find that the queue size drops to 0 (when it should always be 1) meaning that no task has been scheduled.
This suggests that when it attempts to run the scheduled task after the initial task is completed, it either removes the scheduled task or it fails to schedule the next task because the current task isn’t completed. No errors or exceptions are thrown as all exceptions have been handled in the doTask method. The scheduler works as expected locally and in the test server which makes it difficult to replicate the scenario.
Want to find out if the implementation is missing something or what might be causing it to not complete the next scheduled task and what makes the queue size drop to 0. Could the java version have any impact on the behaviour of the scheduler or are there any reasons why this might be happening in a live environment?
I created a REST endpoint to monitor what was going on under the hood with the properties from ScheduledFuture and ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) schedulerService;
this.queueSize = executor.getQueue().size();
this.remainingCapacity = executor.getQueue().remainingCapacity();
this.terminated = schedulerService.isTerminated();
this.shutdown = schedulerService.isShutdown();
this.taskCount = executor.getTaskCount();
this.activeTaskCount = executor.getActiveCount();
this.completedTaskCount = executor.getCompletedTaskCount();
this.keepAliveTime = executor.getKeepAliveTime(TimeUnit.SECONDS);
this.coreThreadTimeOut = executor.allowsCoreThreadTimeOut();
this.cancelled = scheduledFuture.isCancelled();
this.delay = scheduledFuture.getDelay(TimeUnit.MINUTES);
Result of first run after initial delay: from this, we can see that it completed the first task and I do get the required result from the calculations. The taskCount (number of scheduled tasks since start-up) is 2 meaning that the 2nd task has been scheduled and the queue size is still 1 which is fine.
{
"queueSize": 1,
"remainingCapacity": 2147483647,
"terminated": false,
"shutdown": false,
"taskCount": 2,
"activeTaskCount": 0,
"completedTaskCount": 1,
"keepAliveTime": 0,
"coreThreadTimeOut": false,
"periodic": true,
"cancelled": false
}
Result after it attempted 2nd run: this is where it gets stuck. The completedTaskCount is 2 but I don’t think it actually completes the task as I don’t get the result from the calculations or any logs to show that it has either started or completed the task. The taskCount should go up to 3 but it is stuck in 2 and the queue size is now 0.
{
"queueSize": 0,
"remainingCapacity": 2147483647,
"terminated": false,
"shutdown": false,
"taskCount": 2,
"activeTaskCount": 0,
"completedTaskCount": 2,
"keepAliveTime": 0,
"coreThreadTimeOut": false,
"periodic": true,
"cancelled": false
}
When I check these on the local and test server, it works fine and the taskCount goes up as expected and the queue size is always 1 which is expected. From this, I can tell that for some reason, the task gets stuck on the 2nd run and does not complete so it doesn’t schedule the next task.
The javadoc says: "If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute." I'm assuming this is why the next task is not scheduled. It would be great if you can explain what might cause this to happen
java scheduling runnable executorservice scheduledexecutorservice
add a comment |
I have a ScheduledExecutorService to schedule a task to run every 12 hours in a tomcat application. The task calls a REST endpoint and performs some other calculations and returns a result. It works perfectly fine locally and in test server however, it runs only once and never again in the live server. All exceptions are handled and the task takes less than 5 seconds to complete. I have also checked all properties in the server to make sure the time properties are not overridden by other properties. To test locally, I have reduced the delay time to every 10 minutes and this still shows the same behaviour so I’ve ruled time out as the issue. I have looked at other similar questions but none seem to help with this issue.
ScheduledExecutorService only runs once,
JAVA ScheduledExecutorService only runs once when calling a Task<V>,
ScheduledExecutorService only loops once,
ScheduledExecutorService - Task stops running,
ScheduledExecutorService - Ignore already running runnable,
ScheduledExecutorService schedule issue,
Timer vs. ScheduledExecutorService scheduling
Below is my code:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder({"name", "number"})
public class Company {
@JsonProperty("name")
private String name;
@JsonProperty("number")
private int number;
public String getName() {
return this.name;
}
public int getNumber() {
return this.number;
}
@Override
public String toString() {
return new ToStringBuilder(Company.class)
.append("name", this.name)
.append("number", this.number).toString();
}
}
public class CompanyDifference {
private String name;
private int difference;
public CompanyDifference(String name, int difference) {
this.name = name;
this.difference = difference;
}
public String getName() {
return this.name;
}
public int getDifference() {
return this.difference;
}
@Override
public String toString() {
return new ToStringBuilder(CompanyDifference.class)
.append("name", this.name)
.append("difference", this.difference).toString();
}
}
@Singleton
public class TaskRunner {
public void doTask () {
try {
System.out.println("takes 2 sets of json data and returns the difference for each company");
// takes 2 sets of json data and returns the difference for each company
ObjectMapper mapper = new ObjectMapper();
InputStream dataOne = Company.class.getResourceAsStream("/data.json");
InputStream dataTwo = Company.class.getResourceAsStream("/data2.json");
Company companyDataOne = mapper.readValue(dataOne, Company.class);
Company companyDataTwo = mapper.readValue(dataTwo, Company.class);
// Find the difference for each company and map company name to difference
Map<String, Integer> mapDifferenceToCompany = new HashMap<>();
for (int i = 0; i < companyDataOne.length; i++) {
mapDifferenceToCompany.put(companyDataOne[i].getName(), Math.abs(companyDataOne[i].getNumber() - companyDataTwo[i].getNumber()));
}
mapDifferenceToCompany.forEach((key, value) -> System.out.println(String.valueOf(new CompanyDifference(key, value))));
} catch (IOException e) {
logger.info(String.format("Error: Failed to convert json to object with exception %s", e));
throw new TaskSchedulerException("Failed to convert json to object with exception", e);
} catch (Exception e) {
logger.info(String.format("Error: Failed with exception %s", e));
throw new TaskSchedulerException("Failed with exception", e);
}
}
}
@Singleton
public class TaskScheduler {
private final Runnable runnable;
private final ScheduledExecutorService executorService;
private static final Logger logger = LoggerFactory.getLogger(TaskScheduler.class);
@Inject
public TaskScheduler(TaskRunner taskRunner, int initialDelay, int period, String timeUnits) {
this.executorService = Executors.newScheduledThreadPool(1);
this.runnable = taskRunner::doTask;
this.scheduledFuture = this.executorService.scheduleAtFixedRate(this.runnable, initialDelay, period,
TimeUnit.valueOf(timeUnits));
}
public static void main(String args) {
TaskRunner taskRunner = new TaskRunner();
new TaskScheduler(taskRunner, 1, 10, "MINUTES");
}
}
The task runs once on start-up after the initial delay of 1 minute but doesn’t run the next scheduled task. It attempts to run the scheduled task but doesn’t seem to complete the task and after examining the ScheduledThreadPoolExecutor properties in the live server, I find that the queue size drops to 0 (when it should always be 1) meaning that no task has been scheduled.
This suggests that when it attempts to run the scheduled task after the initial task is completed, it either removes the scheduled task or it fails to schedule the next task because the current task isn’t completed. No errors or exceptions are thrown as all exceptions have been handled in the doTask method. The scheduler works as expected locally and in the test server which makes it difficult to replicate the scenario.
Want to find out if the implementation is missing something or what might be causing it to not complete the next scheduled task and what makes the queue size drop to 0. Could the java version have any impact on the behaviour of the scheduler or are there any reasons why this might be happening in a live environment?
I created a REST endpoint to monitor what was going on under the hood with the properties from ScheduledFuture and ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) schedulerService;
this.queueSize = executor.getQueue().size();
this.remainingCapacity = executor.getQueue().remainingCapacity();
this.terminated = schedulerService.isTerminated();
this.shutdown = schedulerService.isShutdown();
this.taskCount = executor.getTaskCount();
this.activeTaskCount = executor.getActiveCount();
this.completedTaskCount = executor.getCompletedTaskCount();
this.keepAliveTime = executor.getKeepAliveTime(TimeUnit.SECONDS);
this.coreThreadTimeOut = executor.allowsCoreThreadTimeOut();
this.cancelled = scheduledFuture.isCancelled();
this.delay = scheduledFuture.getDelay(TimeUnit.MINUTES);
Result of first run after initial delay: from this, we can see that it completed the first task and I do get the required result from the calculations. The taskCount (number of scheduled tasks since start-up) is 2 meaning that the 2nd task has been scheduled and the queue size is still 1 which is fine.
{
"queueSize": 1,
"remainingCapacity": 2147483647,
"terminated": false,
"shutdown": false,
"taskCount": 2,
"activeTaskCount": 0,
"completedTaskCount": 1,
"keepAliveTime": 0,
"coreThreadTimeOut": false,
"periodic": true,
"cancelled": false
}
Result after it attempted 2nd run: this is where it gets stuck. The completedTaskCount is 2 but I don’t think it actually completes the task as I don’t get the result from the calculations or any logs to show that it has either started or completed the task. The taskCount should go up to 3 but it is stuck in 2 and the queue size is now 0.
{
"queueSize": 0,
"remainingCapacity": 2147483647,
"terminated": false,
"shutdown": false,
"taskCount": 2,
"activeTaskCount": 0,
"completedTaskCount": 2,
"keepAliveTime": 0,
"coreThreadTimeOut": false,
"periodic": true,
"cancelled": false
}
When I check these on the local and test server, it works fine and the taskCount goes up as expected and the queue size is always 1 which is expected. From this, I can tell that for some reason, the task gets stuck on the 2nd run and does not complete so it doesn’t schedule the next task.
The javadoc says: "If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute." I'm assuming this is why the next task is not scheduled. It would be great if you can explain what might cause this to happen
java scheduling runnable executorservice scheduledexecutorservice
Can you please provide what actually your "doTask" method does.
– Amit Bera
Nov 21 '18 at 17:12
@Amit Bera: I have included an example of what the doTask method does.
– Sam Aig
Nov 22 '18 at 18:47
As far as I can tell you're not closing the streams. Could that be it? A lock on a stream that hangs, thus the second iteration will not run as stream is still opened and locked?
– Frankie
Nov 27 '18 at 15:49
It still exhibits the same behaviour with the streams closed.
– Sam Aig
Nov 27 '18 at 16:45
add a comment |
I have a ScheduledExecutorService to schedule a task to run every 12 hours in a tomcat application. The task calls a REST endpoint and performs some other calculations and returns a result. It works perfectly fine locally and in test server however, it runs only once and never again in the live server. All exceptions are handled and the task takes less than 5 seconds to complete. I have also checked all properties in the server to make sure the time properties are not overridden by other properties. To test locally, I have reduced the delay time to every 10 minutes and this still shows the same behaviour so I’ve ruled time out as the issue. I have looked at other similar questions but none seem to help with this issue.
ScheduledExecutorService only runs once,
JAVA ScheduledExecutorService only runs once when calling a Task<V>,
ScheduledExecutorService only loops once,
ScheduledExecutorService - Task stops running,
ScheduledExecutorService - Ignore already running runnable,
ScheduledExecutorService schedule issue,
Timer vs. ScheduledExecutorService scheduling
Below is my code:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder({"name", "number"})
public class Company {
@JsonProperty("name")
private String name;
@JsonProperty("number")
private int number;
public String getName() {
return this.name;
}
public int getNumber() {
return this.number;
}
@Override
public String toString() {
return new ToStringBuilder(Company.class)
.append("name", this.name)
.append("number", this.number).toString();
}
}
public class CompanyDifference {
private String name;
private int difference;
public CompanyDifference(String name, int difference) {
this.name = name;
this.difference = difference;
}
public String getName() {
return this.name;
}
public int getDifference() {
return this.difference;
}
@Override
public String toString() {
return new ToStringBuilder(CompanyDifference.class)
.append("name", this.name)
.append("difference", this.difference).toString();
}
}
@Singleton
public class TaskRunner {
public void doTask () {
try {
System.out.println("takes 2 sets of json data and returns the difference for each company");
// takes 2 sets of json data and returns the difference for each company
ObjectMapper mapper = new ObjectMapper();
InputStream dataOne = Company.class.getResourceAsStream("/data.json");
InputStream dataTwo = Company.class.getResourceAsStream("/data2.json");
Company companyDataOne = mapper.readValue(dataOne, Company.class);
Company companyDataTwo = mapper.readValue(dataTwo, Company.class);
// Find the difference for each company and map company name to difference
Map<String, Integer> mapDifferenceToCompany = new HashMap<>();
for (int i = 0; i < companyDataOne.length; i++) {
mapDifferenceToCompany.put(companyDataOne[i].getName(), Math.abs(companyDataOne[i].getNumber() - companyDataTwo[i].getNumber()));
}
mapDifferenceToCompany.forEach((key, value) -> System.out.println(String.valueOf(new CompanyDifference(key, value))));
} catch (IOException e) {
logger.info(String.format("Error: Failed to convert json to object with exception %s", e));
throw new TaskSchedulerException("Failed to convert json to object with exception", e);
} catch (Exception e) {
logger.info(String.format("Error: Failed with exception %s", e));
throw new TaskSchedulerException("Failed with exception", e);
}
}
}
@Singleton
public class TaskScheduler {
private final Runnable runnable;
private final ScheduledExecutorService executorService;
private static final Logger logger = LoggerFactory.getLogger(TaskScheduler.class);
@Inject
public TaskScheduler(TaskRunner taskRunner, int initialDelay, int period, String timeUnits) {
this.executorService = Executors.newScheduledThreadPool(1);
this.runnable = taskRunner::doTask;
this.scheduledFuture = this.executorService.scheduleAtFixedRate(this.runnable, initialDelay, period,
TimeUnit.valueOf(timeUnits));
}
public static void main(String args) {
TaskRunner taskRunner = new TaskRunner();
new TaskScheduler(taskRunner, 1, 10, "MINUTES");
}
}
The task runs once on start-up after the initial delay of 1 minute but doesn’t run the next scheduled task. It attempts to run the scheduled task but doesn’t seem to complete the task and after examining the ScheduledThreadPoolExecutor properties in the live server, I find that the queue size drops to 0 (when it should always be 1) meaning that no task has been scheduled.
This suggests that when it attempts to run the scheduled task after the initial task is completed, it either removes the scheduled task or it fails to schedule the next task because the current task isn’t completed. No errors or exceptions are thrown as all exceptions have been handled in the doTask method. The scheduler works as expected locally and in the test server which makes it difficult to replicate the scenario.
Want to find out if the implementation is missing something or what might be causing it to not complete the next scheduled task and what makes the queue size drop to 0. Could the java version have any impact on the behaviour of the scheduler or are there any reasons why this might be happening in a live environment?
I created a REST endpoint to monitor what was going on under the hood with the properties from ScheduledFuture and ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) schedulerService;
this.queueSize = executor.getQueue().size();
this.remainingCapacity = executor.getQueue().remainingCapacity();
this.terminated = schedulerService.isTerminated();
this.shutdown = schedulerService.isShutdown();
this.taskCount = executor.getTaskCount();
this.activeTaskCount = executor.getActiveCount();
this.completedTaskCount = executor.getCompletedTaskCount();
this.keepAliveTime = executor.getKeepAliveTime(TimeUnit.SECONDS);
this.coreThreadTimeOut = executor.allowsCoreThreadTimeOut();
this.cancelled = scheduledFuture.isCancelled();
this.delay = scheduledFuture.getDelay(TimeUnit.MINUTES);
Result of first run after initial delay: from this, we can see that it completed the first task and I do get the required result from the calculations. The taskCount (number of scheduled tasks since start-up) is 2 meaning that the 2nd task has been scheduled and the queue size is still 1 which is fine.
{
"queueSize": 1,
"remainingCapacity": 2147483647,
"terminated": false,
"shutdown": false,
"taskCount": 2,
"activeTaskCount": 0,
"completedTaskCount": 1,
"keepAliveTime": 0,
"coreThreadTimeOut": false,
"periodic": true,
"cancelled": false
}
Result after it attempted 2nd run: this is where it gets stuck. The completedTaskCount is 2 but I don’t think it actually completes the task as I don’t get the result from the calculations or any logs to show that it has either started or completed the task. The taskCount should go up to 3 but it is stuck in 2 and the queue size is now 0.
{
"queueSize": 0,
"remainingCapacity": 2147483647,
"terminated": false,
"shutdown": false,
"taskCount": 2,
"activeTaskCount": 0,
"completedTaskCount": 2,
"keepAliveTime": 0,
"coreThreadTimeOut": false,
"periodic": true,
"cancelled": false
}
When I check these on the local and test server, it works fine and the taskCount goes up as expected and the queue size is always 1 which is expected. From this, I can tell that for some reason, the task gets stuck on the 2nd run and does not complete so it doesn’t schedule the next task.
The javadoc says: "If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute." I'm assuming this is why the next task is not scheduled. It would be great if you can explain what might cause this to happen
java scheduling runnable executorservice scheduledexecutorservice
I have a ScheduledExecutorService to schedule a task to run every 12 hours in a tomcat application. The task calls a REST endpoint and performs some other calculations and returns a result. It works perfectly fine locally and in test server however, it runs only once and never again in the live server. All exceptions are handled and the task takes less than 5 seconds to complete. I have also checked all properties in the server to make sure the time properties are not overridden by other properties. To test locally, I have reduced the delay time to every 10 minutes and this still shows the same behaviour so I’ve ruled time out as the issue. I have looked at other similar questions but none seem to help with this issue.
ScheduledExecutorService only runs once,
JAVA ScheduledExecutorService only runs once when calling a Task<V>,
ScheduledExecutorService only loops once,
ScheduledExecutorService - Task stops running,
ScheduledExecutorService - Ignore already running runnable,
ScheduledExecutorService schedule issue,
Timer vs. ScheduledExecutorService scheduling
Below is my code:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder({"name", "number"})
public class Company {
@JsonProperty("name")
private String name;
@JsonProperty("number")
private int number;
public String getName() {
return this.name;
}
public int getNumber() {
return this.number;
}
@Override
public String toString() {
return new ToStringBuilder(Company.class)
.append("name", this.name)
.append("number", this.number).toString();
}
}
public class CompanyDifference {
private String name;
private int difference;
public CompanyDifference(String name, int difference) {
this.name = name;
this.difference = difference;
}
public String getName() {
return this.name;
}
public int getDifference() {
return this.difference;
}
@Override
public String toString() {
return new ToStringBuilder(CompanyDifference.class)
.append("name", this.name)
.append("difference", this.difference).toString();
}
}
@Singleton
public class TaskRunner {
public void doTask () {
try {
System.out.println("takes 2 sets of json data and returns the difference for each company");
// takes 2 sets of json data and returns the difference for each company
ObjectMapper mapper = new ObjectMapper();
InputStream dataOne = Company.class.getResourceAsStream("/data.json");
InputStream dataTwo = Company.class.getResourceAsStream("/data2.json");
Company companyDataOne = mapper.readValue(dataOne, Company.class);
Company companyDataTwo = mapper.readValue(dataTwo, Company.class);
// Find the difference for each company and map company name to difference
Map<String, Integer> mapDifferenceToCompany = new HashMap<>();
for (int i = 0; i < companyDataOne.length; i++) {
mapDifferenceToCompany.put(companyDataOne[i].getName(), Math.abs(companyDataOne[i].getNumber() - companyDataTwo[i].getNumber()));
}
mapDifferenceToCompany.forEach((key, value) -> System.out.println(String.valueOf(new CompanyDifference(key, value))));
} catch (IOException e) {
logger.info(String.format("Error: Failed to convert json to object with exception %s", e));
throw new TaskSchedulerException("Failed to convert json to object with exception", e);
} catch (Exception e) {
logger.info(String.format("Error: Failed with exception %s", e));
throw new TaskSchedulerException("Failed with exception", e);
}
}
}
@Singleton
public class TaskScheduler {
private final Runnable runnable;
private final ScheduledExecutorService executorService;
private static final Logger logger = LoggerFactory.getLogger(TaskScheduler.class);
@Inject
public TaskScheduler(TaskRunner taskRunner, int initialDelay, int period, String timeUnits) {
this.executorService = Executors.newScheduledThreadPool(1);
this.runnable = taskRunner::doTask;
this.scheduledFuture = this.executorService.scheduleAtFixedRate(this.runnable, initialDelay, period,
TimeUnit.valueOf(timeUnits));
}
public static void main(String args) {
TaskRunner taskRunner = new TaskRunner();
new TaskScheduler(taskRunner, 1, 10, "MINUTES");
}
}
The task runs once on start-up after the initial delay of 1 minute but doesn’t run the next scheduled task. It attempts to run the scheduled task but doesn’t seem to complete the task and after examining the ScheduledThreadPoolExecutor properties in the live server, I find that the queue size drops to 0 (when it should always be 1) meaning that no task has been scheduled.
This suggests that when it attempts to run the scheduled task after the initial task is completed, it either removes the scheduled task or it fails to schedule the next task because the current task isn’t completed. No errors or exceptions are thrown as all exceptions have been handled in the doTask method. The scheduler works as expected locally and in the test server which makes it difficult to replicate the scenario.
Want to find out if the implementation is missing something or what might be causing it to not complete the next scheduled task and what makes the queue size drop to 0. Could the java version have any impact on the behaviour of the scheduler or are there any reasons why this might be happening in a live environment?
I created a REST endpoint to monitor what was going on under the hood with the properties from ScheduledFuture and ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) schedulerService;
this.queueSize = executor.getQueue().size();
this.remainingCapacity = executor.getQueue().remainingCapacity();
this.terminated = schedulerService.isTerminated();
this.shutdown = schedulerService.isShutdown();
this.taskCount = executor.getTaskCount();
this.activeTaskCount = executor.getActiveCount();
this.completedTaskCount = executor.getCompletedTaskCount();
this.keepAliveTime = executor.getKeepAliveTime(TimeUnit.SECONDS);
this.coreThreadTimeOut = executor.allowsCoreThreadTimeOut();
this.cancelled = scheduledFuture.isCancelled();
this.delay = scheduledFuture.getDelay(TimeUnit.MINUTES);
Result of first run after initial delay: from this, we can see that it completed the first task and I do get the required result from the calculations. The taskCount (number of scheduled tasks since start-up) is 2 meaning that the 2nd task has been scheduled and the queue size is still 1 which is fine.
{
"queueSize": 1,
"remainingCapacity": 2147483647,
"terminated": false,
"shutdown": false,
"taskCount": 2,
"activeTaskCount": 0,
"completedTaskCount": 1,
"keepAliveTime": 0,
"coreThreadTimeOut": false,
"periodic": true,
"cancelled": false
}
Result after it attempted 2nd run: this is where it gets stuck. The completedTaskCount is 2 but I don’t think it actually completes the task as I don’t get the result from the calculations or any logs to show that it has either started or completed the task. The taskCount should go up to 3 but it is stuck in 2 and the queue size is now 0.
{
"queueSize": 0,
"remainingCapacity": 2147483647,
"terminated": false,
"shutdown": false,
"taskCount": 2,
"activeTaskCount": 0,
"completedTaskCount": 2,
"keepAliveTime": 0,
"coreThreadTimeOut": false,
"periodic": true,
"cancelled": false
}
When I check these on the local and test server, it works fine and the taskCount goes up as expected and the queue size is always 1 which is expected. From this, I can tell that for some reason, the task gets stuck on the 2nd run and does not complete so it doesn’t schedule the next task.
The javadoc says: "If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute." I'm assuming this is why the next task is not scheduled. It would be great if you can explain what might cause this to happen
java scheduling runnable executorservice scheduledexecutorservice
java scheduling runnable executorservice scheduledexecutorservice
edited Nov 27 '18 at 15:15
Sam Aig
asked Nov 21 '18 at 16:49
Sam AigSam Aig
265
265
Can you please provide what actually your "doTask" method does.
– Amit Bera
Nov 21 '18 at 17:12
@Amit Bera: I have included an example of what the doTask method does.
– Sam Aig
Nov 22 '18 at 18:47
As far as I can tell you're not closing the streams. Could that be it? A lock on a stream that hangs, thus the second iteration will not run as stream is still opened and locked?
– Frankie
Nov 27 '18 at 15:49
It still exhibits the same behaviour with the streams closed.
– Sam Aig
Nov 27 '18 at 16:45
add a comment |
Can you please provide what actually your "doTask" method does.
– Amit Bera
Nov 21 '18 at 17:12
@Amit Bera: I have included an example of what the doTask method does.
– Sam Aig
Nov 22 '18 at 18:47
As far as I can tell you're not closing the streams. Could that be it? A lock on a stream that hangs, thus the second iteration will not run as stream is still opened and locked?
– Frankie
Nov 27 '18 at 15:49
It still exhibits the same behaviour with the streams closed.
– Sam Aig
Nov 27 '18 at 16:45
Can you please provide what actually your "doTask" method does.
– Amit Bera
Nov 21 '18 at 17:12
Can you please provide what actually your "doTask" method does.
– Amit Bera
Nov 21 '18 at 17:12
@Amit Bera: I have included an example of what the doTask method does.
– Sam Aig
Nov 22 '18 at 18:47
@Amit Bera: I have included an example of what the doTask method does.
– Sam Aig
Nov 22 '18 at 18:47
As far as I can tell you're not closing the streams. Could that be it? A lock on a stream that hangs, thus the second iteration will not run as stream is still opened and locked?
– Frankie
Nov 27 '18 at 15:49
As far as I can tell you're not closing the streams. Could that be it? A lock on a stream that hangs, thus the second iteration will not run as stream is still opened and locked?
– Frankie
Nov 27 '18 at 15:49
It still exhibits the same behaviour with the streams closed.
– Sam Aig
Nov 27 '18 at 16:45
It still exhibits the same behaviour with the streams closed.
– Sam Aig
Nov 27 '18 at 16:45
add a comment |
1 Answer
1
active
oldest
votes
Issue was not with the implementation, the implementation is fine. After much debugging, the VM box running the app seemed to have had a glitch. After restarting multiple times and redeploying app service, It's back to normal.
Please see question for steps taken when debugging app.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53416915%2fscheduledexecutorservice-works-in-local-test-server-but-only-runs-once-in-live%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Issue was not with the implementation, the implementation is fine. After much debugging, the VM box running the app seemed to have had a glitch. After restarting multiple times and redeploying app service, It's back to normal.
Please see question for steps taken when debugging app.
add a comment |
Issue was not with the implementation, the implementation is fine. After much debugging, the VM box running the app seemed to have had a glitch. After restarting multiple times and redeploying app service, It's back to normal.
Please see question for steps taken when debugging app.
add a comment |
Issue was not with the implementation, the implementation is fine. After much debugging, the VM box running the app seemed to have had a glitch. After restarting multiple times and redeploying app service, It's back to normal.
Please see question for steps taken when debugging app.
Issue was not with the implementation, the implementation is fine. After much debugging, the VM box running the app seemed to have had a glitch. After restarting multiple times and redeploying app service, It's back to normal.
Please see question for steps taken when debugging app.
answered Dec 6 '18 at 0:49
Sam AigSam Aig
265
265
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53416915%2fscheduledexecutorservice-works-in-local-test-server-but-only-runs-once-in-live%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Can you please provide what actually your "doTask" method does.
– Amit Bera
Nov 21 '18 at 17:12
@Amit Bera: I have included an example of what the doTask method does.
– Sam Aig
Nov 22 '18 at 18:47
As far as I can tell you're not closing the streams. Could that be it? A lock on a stream that hangs, thus the second iteration will not run as stream is still opened and locked?
– Frankie
Nov 27 '18 at 15:49
It still exhibits the same behaviour with the streams closed.
– Sam Aig
Nov 27 '18 at 16:45