• How to send a onetime scheduled task to executorService that has a repe

    From mike@21:1/5 to All on Thu Mar 10 04:32:40 2022
    Hi,

    We have implemented a "KeepAlive service" that we use over TLS.

    This service will send a message every 10 seconds to a server and if we get a response then we are ok and connection is considered ok.

    This is started using:

    KeepAlive keepAlive = new KeepAlive(this);
    keepAlive.init();
    future = scheduledTaskExecutor.newScheduledTask(keepAlive, 0, properties.getKeepAliveTime(),
    TimeUnit.SECONDS);

    Note: newScheduledTask() calls ScheduledFuture<?> future = executorService.scheduleAtFixedRate(runnable, delay, period, timeUnit);

    However we also have a method where we "instantly" want to find out if we are connected to the server.

    This is how it looks like:

    public synchronized boolean isConnected() {

    KeepAlive keepAlive = new KeepAlive(this);//create another keepAlive for same session.
    keepAlive.init();

    if (scheduledTaskExecutor!= null) {

    ScheduledFuture<?> scheduledTaskOnce = scheduledTaskExecutor.newScheduledTaskOnce(keepAlive, 10,
    TimeUnit.MILLISECONDS);
    try {
    Object object = scheduledTaskOnce.get();
    if (object == null) {
    logger.debug("Task has finished! {}", object);
    }
    } catch (InterruptedException | ExecutionException e) {
    logger.debug("We could not finished check of connection", e);
    }
    return keepAlive.isAlive();
    }

    Note: newScheduledTaskOnce() calls ScheduledFuture<?> future = executorService.schedule(runnable, delay, timeUnit);

    Q1: The KeepAlive hangs when doing it as a onetime task in the same executor. Any ideas why?
    Q2: How will a onetime task in same scheduledExecutor be handled when we have a repeatedly ongoing?

    br,

    //mike

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeffrey H. Coffield@21:1/5 to mike on Thu Mar 10 07:21:18 2022
    On 03/10/2022 04:32 AM, mike wrote:
    Hi,

    We have implemented a "KeepAlive service" that we use over TLS.

    This service will send a message every 10 seconds to a server and if we get a response then we are ok and connection is considered ok.

    This is started using:

    KeepAlive keepAlive = new KeepAlive(this);
    keepAlive.init();
    future = scheduledTaskExecutor.newScheduledTask(keepAlive, 0, properties.getKeepAliveTime(),
    TimeUnit.SECONDS);

    Note: newScheduledTask() calls ScheduledFuture<?> future = executorService.scheduleAtFixedRate(runnable, delay, period, timeUnit);

    However we also have a method where we "instantly" want to find out if we are connected to the server.

    This is how it looks like:

    public synchronized boolean isConnected() {

    KeepAlive keepAlive = new KeepAlive(this);//create another keepAlive for same session.
    keepAlive.init();

    if (scheduledTaskExecutor!= null) {

    ScheduledFuture<?> scheduledTaskOnce = scheduledTaskExecutor.newScheduledTaskOnce(keepAlive, 10,
    TimeUnit.MILLISECONDS);
    try {
    Object object = scheduledTaskOnce.get();
    if (object == null) {
    logger.debug("Task has finished! {}", object);
    }
    } catch (InterruptedException | ExecutionException e) {
    logger.debug("We could not finished check of connection", e);
    }
    return keepAlive.isAlive();
    }

    Note: newScheduledTaskOnce() calls ScheduledFuture<?> future = executorService.schedule(runnable, delay, timeUnit);

    Q1: The KeepAlive hangs when doing it as a onetime task in the same executor. Any ideas why?
    Q2: How will a onetime task in same scheduledExecutor be handled when we have a repeatedly ongoing?

    br,

    //mike


    Mike,

    Without actually running the code or any deep analysis, my first
    reaction to this problem would be to create a single method that does
    one ping when called and exits with a boolean, possibly with a lock so
    only one at a time can run. Then use the scheduler to run it every 10
    seconds and set a static variable that other threads can check. Then if
    you need an immediate test, just call the original method.

    hth,
    jeff

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stanimir Stamenkov@21:1/5 to All on Thu Mar 10 22:16:09 2022
    Thu, 10 Mar 2022 04:32:40 -0800 (PST), /mike/:

    This service will send a message every 10 seconds to a server and if we get a response then we are ok and connection is considered ok.

    future = scheduledTaskExecutor.newScheduledTask(keepAlive, 0, properties.getKeepAliveTime(),
    TimeUnit.SECONDS);

    Note: newScheduledTask() calls ScheduledFuture<?> future = executorService.scheduleAtFixedRate(runnable, delay, period, timeUnit);

    However we also have a method where we "instantly" want to find out if we are connected to the server.

    ScheduledFuture<?> scheduledTaskOnce = scheduledTaskExecutor.newScheduledTaskOnce(keepAlive, 10,
    TimeUnit.MILLISECONDS);
    Object object = scheduledTaskOnce.get();

    Note: newScheduledTaskOnce() calls ScheduledFuture<?> future = executorService.schedule(runnable, delay, timeUnit);

    Q1: The KeepAlive hangs when doing it as a onetime task in the same executor. Any ideas why?
    Q2: How will a onetime task in same scheduledExecutor be handled when we have a repeatedly ongoing?

    You haven't specified what is your ScheduledExecutorService configuration/implementation.

    I'm using the following in a real world project:

    import java.util.concurrent.*;

    public static void main(String[] args) throws Exception {
    ScheduledExecutorService executor =
    Executors.newSingleThreadScheduledExecutor();

    executor.scheduleAtFixedRate(slowTask("Regular", 10),
    0, 100, TimeUnit.MILLISECONDS);

    ScheduledFuture<?> oneOff = executor
    .schedule(slowTask("One-off with delay", 50),
    100, TimeUnit.MILLISECONDS);
    oneOff.get();

    executor.execute(slowTask("Immediate one-off", 100));

    Future<?> oneOff2 = executor
    .submit(slowTask("Immediate one-off with result", 100));
    oneOff2.get();

    Thread.sleep(50);

    executor.shutdown();
    }

    static Runnable slowTask(String name, long timeMillis) {
    return () -> {
    System.out.append(name).print("...");
    try {
    Thread.sleep(timeMillis);
    } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    throw new IllegalStateException(e);
    }
    System.out.println(" done.");
    };
    }

    That is a single-thread scheduled executor [1] to serialize both:

    * A task scheduled to run at regular intervals; and
    * One-off executions.

    Q1: The KeepAlive hangs when doing it as a onetime task in the same executor. Any ideas why?
    Q2: How will a onetime task in same scheduledExecutor be handled when we have a repeatedly ongoing?

    One of my uses actually triggers one-off task at the end of the
    scheduled task, also – not just externally submitted. Not sure what
    "onetime task in the same executor" in you case means.

    [1] https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadScheduledExecutor--

    --
    Stanimir

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)