BackgroundThread plugin

  • Tags: asynchronous, scheduling, jobs
  • Latest: 1.6
  • Last Updated: 25 March 2010
  • Grails version: 1.2.0 > *
  • Authors: null
8 votes
Dependency:
compile ":background-thread:1.6"

 Documentation

Summary

Installation

grails install-plugin background-thread

Description

DEPRECATED

Please use the Executor plugin instead

BackgroundThread Plugin

This plugin provides your application the ability to throw off background work. It can be used to provide some asynchronous processing in response to key events: the code originally evolved out of parallel web service calls as triggered by a Quartz job. Work is processed by a fixed-size thread pool.

Beyond the inherent difficulty of concurrent programming, Grails had a few other difficulties: most significantly, the Hibernate session is bound to the thread, and so threads need to do their own Hibernate session management. This plugin takes care of those issues.

It is released under the same terms as Grails itself (the Apache 2 license).

Usage

Installation

grails install-plugin background-thread

Provided Functionality

This plugin provides a service called "backgroundService". As of now, it provides a single method, "execute", which takes two arguments: the name of the work to be executed (an arbitrary label) and a closure which performs the work.

An example usage might be this:

class FooService {
  boolean transactional = false
  def backgroundService

def serviceMethod() { (1..<10).each { cnt -> backgroundService.execute("Logging '$cnt' asynchronously", { log.info("${cnt}") }) } }

If you have a Runnable kicking around that you wanted to run as some background work, you can access the underlying implementation this way:

class BarService {
  boolean transactional = false
  def bgThreadManager

def serviceMethod() { (1..<10).each { bgThreadManager.queueRunnable(new MyRunnable()) } }

Gotchas

  • Almost everything you touch in Groovy is not thread-safe, so you need to pass as little information into your closure as possible.
  • You will almost certainly need to crank up the maximum number of connections for your datasource, assuming your background work is talking to your database.
  • Groovy will hold onto your entire surrounding context when you have a closure, so if you are memory-sensitive, try to consume as much of it as possible to keep your memory footprint down. This means that it is better to use a consuming iterator (an iterator where you call #remove()) than to use Groovy's built-in functional iterators (e.g. #each{}) More at the plugin author's blog.

Config Example

The following snippet can go into your Config.groovy: the values are the default values for those properties.

backgroundThread {
  queueSize = 1000 // Maximum number of tasks to queue up
  threadCount = 5 // Number of threads processing background tasks.
  tasksPerDrain = 100 // See Note
}
  • tasksPerDrain: In concurrent systems, the point of hand-off often becomes a throughput bottleneck. So when one of the background processing threads runs out of work to do, instead of drawing just a single task from the queue, it may opt to drain the queue. This property controls the maximum number of tasks the thread will drain at a time.

Spring Beans

These beans are provided for your use, and can be overridden in the
  • bgThreadFactory: A ThreadFactory used to generate new threads.
  • bgExceptionHandler: A Thread.UncaughtExceptionHandler that is used to handle otherwise uncaught exceptions in the default bgThreadFactory.
  • bgQueue: The java.util.concurrent.BlockingQueue which stores the tasks to be run.
  • bgThreadManager: The BackgroundThreadManager that manages the background threads and processes.

Future Development Roadmap

At this point, only maintenance development is being done on this plugin. If you would like additional functionality, please create a JIRA for this component under the Grails-BackgroundThread component of GRAILSPLUGINS.

Here are two requests on the radar already. If you would like to see them, vote for the issue in JIRA and leave a comment explaining your use case.

Author, Support, and Contact Information

Contact Robert Fischer for commercial support. You can also try #groovy and/or #grails on FreeNode IRC.

Contributing

Please use the GitHub repository for contributing. Fork the project and request a pull when your fix is done.

Contributors

Thanks to Vaclav Pech for implementing the ThreadFactory spring bean and adding in testing.