background tasks in restlet

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

background tasks in restlet

Ralph van Etten
Hi,

I want to send an e-mail in response to a HTTP request by putting the e-mails to be send in a database backed queue and send them off one at a time by a background task. Is there a proper Restlet way to have a background thread which is woken up by a ServerResource ?

I figured I could try and use the TaskService for this but it seems Application#getTaskService() is deprecated. What is the recommended way of obtaining a TaskService or is there a better way to do this?

Thanks,
Ralph.

--
You received this message because you are subscribed to the Google Groups "Restlet Framework (Discuss)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|

Re: background tasks in restlet

Tim Peierls
The Application.getTaskService method was deprecated as part of this commit, with the following explanation:

- Added Component.taskService property and deprecated+disabled the 
  Application.taskService. The same task service/thread pool can then be shared 
  by multiple applications inside the same component/JVM.
- Added Context.executorService property to be able to invoke the parent task
  service without actually being able to control it (start/stop).

So you can use the executor service from the context of the resource. But you don't have to use a Restlet-provided executor service. You can use any executor service that you can provide to your resource implementation, perhaps by dependency injection.

In particular, you can use a single-threaded executor service to provide the queuing behavior directly. Here's a JavaMailSender-based example that enqueues each message (MimeMessagePreparator instance) and waits a fixed, brief amount of time to see if the message was successfully sent. It returns quickly, regardless of the result and whether the timeout was reached. If you don't want to wait, you could remove the timeout parameters entirely or just set them to 0.

    private static final ExecutorService executor = Executors.newSingleThreadExecutor();

    public static boolean sendEmail(final JavaMailSender mailSender, final MimeMessagePreparator preparer) {
        try {
            // Serialize all mailSender.send calls through single-thread executor.
            Future<Boolean> task = executor.submit(new Callable<Boolean>() {
                public Boolean call() {
                    try {
                        mailSender.send(preparer);
                        return true;
                    } catch (Exception ex) {
                        log.warn(">>>> send: Exception during execution: ", ex);
                        return false;
                    }
                }
            });

            try {
                return task.get(WAIT_SECONDS, TimeUnit.SECONDS);
            } catch (TimeoutException ex) {
                log.warn(">>> send: timeout (" + WAIT_SECONDS + "s)");
                task.cancel(true);
            } catch (ExecutionException ex) {
                log.warn(">>>> send: unexpected exception: ", ex.getCause());
                ex.getCause().printStackTrace();
            } catch (InterruptedException ex) {
                log.warn(">>>> send: unexpected interruption: ", ex);
                Thread.currentThread().interrupt();
            }
        } catch (RejectedExecutionException ex) {
            log.warn(">>>> send: rejected: ", ex);
        }
        return false;
    }


On Tue, Jun 7, 2016 at 9:42 AM, ralph <[hidden email]> wrote:
Hi,

I want to send an e-mail in response to a HTTP request by putting the e-mails to be send in a database backed queue and send them off one at a time by a background task. Is there a proper Restlet way to have a background thread which is woken up by a ServerResource ?

I figured I could try and use the TaskService for this but it seems Application#getTaskService() is deprecated. What is the recommended way of obtaining a TaskService or is there a better way to do this?

Thanks,
Ralph.

--
You received this message because you are subscribed to the Google Groups "Restlet Framework (Discuss)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].

--
You received this message because you are subscribed to the Google Groups "Restlet Framework (Discuss)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|

Re: background tasks in restlet

Ralph van Etten
Thanks. That is really helpful information.

Ralph.

On Tuesday, June 7, 2016 at 4:12:08 PM UTC+2, tim wrote:
The Application.getTaskService method was deprecated as part of <a href="https://github.com/restlet/restlet-framework-java/commit/cffa11de897722d4e54b6c95ad4ac9a3b6410861" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frestlet%2Frestlet-framework-java%2Fcommit%2Fcffa11de897722d4e54b6c95ad4ac9a3b6410861\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFJK9v6Uq-psitQ_qyDAMm0rU1ozA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frestlet%2Frestlet-framework-java%2Fcommit%2Fcffa11de897722d4e54b6c95ad4ac9a3b6410861\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFJK9v6Uq-psitQ_qyDAMm0rU1ozA&#39;;return true;">this commit, with the following explanation:

- Added Component.taskService property and deprecated+disabled the 
  Application.taskService. The same task service/thread pool can then be shared 
  by multiple applications inside the same component/JVM.
- Added Context.executorService property to be able to invoke the parent task
  service without actually being able to control it (start/stop).

So you can use the executor service from the context of the resource. But you don't have to use a Restlet-provided executor service. You can use any executor service that you can provide to your resource implementation, perhaps by dependency injection.

In particular, you can use a single-threaded executor service to provide the queuing behavior directly. Here's a JavaMailSender-based example that enqueues each message (MimeMessagePreparator instance) and waits a fixed, brief amount of time to see if the message was successfully sent. It returns quickly, regardless of the result and whether the timeout was reached. If you don't want to wait, you could remove the timeout parameters entirely or just set them to 0.

    private static final ExecutorService executor = Executors.newSingleThreadExecutor();

    public static boolean sendEmail(final JavaMailSender mailSender, final MimeMessagePreparator preparer) {
        try {
            // Serialize all mailSender.send calls through single-thread executor.
            Future<Boolean> task = executor.submit(new Callable<Boolean>() {
                public Boolean call() {
                    try {
                        mailSender.send(preparer);
                        return true;
                    } catch (Exception ex) {
                        log.warn(">>>> send: Exception during execution: ", ex);
                        return false;
                    }
                }
            });

            try {
                return task.get(WAIT_SECONDS, TimeUnit.SECONDS);
            } catch (TimeoutException ex) {
                log.warn(">>> send: timeout (" + WAIT_SECONDS + "s)");
                task.cancel(true);
            } catch (ExecutionException ex) {
                log.warn(">>>> send: unexpected exception: ", ex.getCause());
                ex.getCause().printStackTrace();
            } catch (InterruptedException ex) {
                log.warn(">>>> send: unexpected interruption: ", ex);
                Thread.currentThread().interrupt();
            }
        } catch (RejectedExecutionException ex) {
            log.warn(">>>> send: rejected: ", ex);
        }
        return false;
    }



--
You received this message because you are subscribed to the Google Groups "Restlet Framework (Discuss)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|

Re: background tasks in restlet

Thierry Boileau-4
Hi all,

thanks a lot Tim for your nice answer!

Thierry


Le mer. 8 juin 2016 à 08:12, ralph <[hidden email]> a écrit :
Thanks. That is really helpful information.

Ralph.


On Tuesday, June 7, 2016 at 4:12:08 PM UTC+2, tim wrote:
The Application.getTaskService method was deprecated as part of this commit, with the following explanation:

- Added Component.taskService property and deprecated+disabled the 
  Application.taskService. The same task service/thread pool can then be shared 
  by multiple applications inside the same component/JVM.
- Added Context.executorService property to be able to invoke the parent task
  service without actually being able to control it (start/stop).

So you can use the executor service from the context of the resource. But you don't have to use a Restlet-provided executor service. You can use any executor service that you can provide to your resource implementation, perhaps by dependency injection.

In particular, you can use a single-threaded executor service to provide the queuing behavior directly. Here's a JavaMailSender-based example that enqueues each message (MimeMessagePreparator instance) and waits a fixed, brief amount of time to see if the message was successfully sent. It returns quickly, regardless of the result and whether the timeout was reached. If you don't want to wait, you could remove the timeout parameters entirely or just set them to 0.

    private static final ExecutorService executor = Executors.newSingleThreadExecutor();

    public static boolean sendEmail(final JavaMailSender mailSender, final MimeMessagePreparator preparer) {
        try {
            // Serialize all mailSender.send calls through single-thread executor.
            Future<Boolean> task = executor.submit(new Callable<Boolean>() {
                public Boolean call() {
                    try {
                        mailSender.send(preparer);
                        return true;
                    } catch (Exception ex) {
                        log.warn(">>>> send: Exception during execution: ", ex);
                        return false;
                    }
                }
            });

            try {
                return task.get(WAIT_SECONDS, TimeUnit.SECONDS);
            } catch (TimeoutException ex) {
                log.warn(">>> send: timeout (" + WAIT_SECONDS + "s)");
                task.cancel(true);
            } catch (ExecutionException ex) {
                log.warn(">>>> send: unexpected exception: ", ex.getCause());
                ex.getCause().printStackTrace();
            } catch (InterruptedException ex) {
                log.warn(">>>> send: unexpected interruption: ", ex);
                Thread.currentThread().interrupt();
            }
        } catch (RejectedExecutionException ex) {
            log.warn(">>>> send: rejected: ", ex);
        }
        return false;
    }



--
You received this message because you are subscribed to the Google Groups "Restlet Framework (Discuss)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].