# 9. Threading

Building a well-behaved multi-threaded desktop application has been a hard task for many years, however it does not have to be that way anymore. The following sections explain the threading facilities exposed by the Griffon framework.

> Prior to version 0.9.2 Controller actions were called in the same thread that published the event; most of the times this thread would be the UI thread. From 0.9.2 and onwards Controller actions will be executed outside of the UI thread. This feature can be disabled altogether or in a per case basis as explained in section 8.1.1.

## 9.1 Swing Threading

The Swing toolkit has a single golden rule: all long computations must be performed outside of the Event Dispatch Thread (or EDT for short). This rule also states that all interaction with UI components must be done inside the EDT, including building a component and reading/writing component properties. See Concurrency in Swing for more information.

Often times this rule can be broken easily as there is no compile time check for it. The Swing toolkit offers a helper class `SwingUtilities` that exposes a pair of method that let you run code inside the EDT, however there is no helper method for running code outside of the EDT

SwingBuilder provides a few methods that let you build multi-threaded applications the easy way. These methods are available in Views and Controllers.

## 9.1.1 Synchronous Calls

Synchronous calls inside the EDT can be achieved by calling the `edt{}` method. This method is smarter than plain `SwingUtilities.invokeAndWait` as it won't throw an exception if called inside the EDT, on the contrary, it will simply call the block of code it was given.

Example:

    class MyController {
        def model    def action1 = {
            // will be invoked inside the EDT by default (pre 0.9.2)
            def value = model.value
            Thread.start {
                // do some calculations
                edt {
                    // back inside the EDT
                    model.result = …
                }
            }
        }    def action2 = {
            // will be invoked outside of the EDT by default (post 0.9.2)
            def value = model.value
            // do some calculations
            edt {
                // back inside the EDT
                model.result = …
            }
        }
    }

## 9.1.2 Asynchronous Calls

Asynchronous calls inside the EDT can be made by calling the `doLater{}` method. This method simply posts a new event to the underlying EventQueue using `SwingUtilities.invokeLater`, meaning you spare a few characters and a class import.

Example:

    class MyController {
        def model    def action1 = {
            // will be invoked inside the EDT by default (pre 0.9.2)
            def value = model.value
            Thread.start {
                // do some calculations
                doLater {
                    // back inside the EDT
                    model.result = …
                }
            }
        }    def action2 = {
            // will be invoked outside of the EDT by default (post 0.9.2)
            def value = model.value
            // do some calculations
            doLater {
                // back inside the EDT
                model.result = …
            }
        }
    }

## 9.1.3 Outside Calls

The previous two examples showed a simple way to execute code outside of the EDT, simply put they spawn a new Thread. The problem with this approach is that creating new threads is an expensive operation, also you shouldn't need to create a new thread if the code is already being executed outside of the EDT.

The `doOutside{}` method takes these concerns into account, spawning a new thread if and only if the code is currently being executed inside the EDT. A rewrite of the previous example would be thus

    class MyController {
        def model    def action1 = {
            // will be invoked inside the EDT by default (pre 0.9.2)
            def value = model.value
            doOutside {
                // do some calculations
                doLater {
                    // back inside the EDT
                    model.result = …
                }
            }
        }    def action2 = {
            // will be invoked outside of the EDT by default (post 0.9.2)
            def value = model.value
            // do some calculations
            doLater {
                // back inside the EDT
                model.result = …
                doOutside {
                    // do more calculations
                }
            }
        }
    }

## 9.2 Toolkit-agnostic Threading

Swing is not the only toolkit supported by Griffon. For those additional toolkits the three methods exposed in the previous sections (edt, doLater, doOutside) make no sense, however running code inside the UI thread in a synchronous/asynchronous way, as well as outside of it is something you must keep in mind.

The following sections outline toolkit-agnostic threading options, which can also be used with Swing in case you're wondering. These methods are available to all classes that implement the griffon.core.GriffonArtifact or griffon.core.GriffonApplication interfaces.

## 9.2.1 Synchronous Calls

Synchronous calls inside the UIThread are made by invoking the `execInsideUISync{}` method. This method is equivalent to calling `edt{}` in Swing.

Example:

    class MyController {
        def model    def action1 = {
            // will be invoked inside the UI thread by default (pre 0.9.2)
            def value = model.value
            Thread.start {
                // do some calculations
                execInsideUISync {
                    // back inside the UI thread
                    model.result = …
                }
            }
        }    def action2 = {
            // will be invoked outside of the UI thread by default (post 0.9.2)
            def value = model.value
            // do some calculations
            execInsideUISync {
                // back inside the UI thread
                model.result = …
            }
        }
    }

## 9.2.2 Asynchronous Calls

Similarly to synchronous calls, asynchronous calls inside the UIThread are made by invoking the `execInsideUIAsync{}` method. This method is equivalent to calling `doLater{}` in Swing.

Example:

    class MyController {
        def model    def action1 = {
            // will be invoked inside the UI Thread by default (pre 0.9.2)
            def value = model.value
            Thread.start {
                // do some calculations
                execInsideUIAsync {
                    // back inside the UI Thread
                    model.result = …
                }
            }
        }    def action2 = {
            // will be invoked outside of the UI Thread by default (post 0.9.2)
            def value = model.value
            // do some calculations
            execInsideUIAsync {
                // back inside the UI Thread
                model.result = …
            }
        }
    }

## 9.2.3 Outside Calls

Making sure a block of code is executed outside the UIThread is made by invoking the `execOutsideUI{}` method. This method is equivalent to calling `doOutside{}` in Swing.

Example:

    class MyController {
        def model    def action1 = {
            // will be invoked inside the UI Thread by default (pre 0.9.2)
            def value = model.value
            execOutsideUI {
                // do some calculations
                execInsideUIAsync {
                    // back inside the UI Thread
                    model.result = …
                }
            }
        }    def action2 = {
            // will be invoked outside of the UI Thread by default (post 0.9.2)
            def value = model.value
            // do some calculations
            execInsideUIAsync {
                // back inside the UI Thread
                model.result = …
                execOutsideUI {
                    // do more calculations
                }
            }
        }
    }

## 9.2.4 Additional Methods

There are two additional methods that complement the generic threading facilities that Griffon exposes to the application and its artifacts

- `isUIThread()` - returns true if the current thread is the UI Thread, false otherwise. Functionally equivalent to calling `SwingUtilities.isEventDispatchThread()` in Swing.
- `execFuture(ExecutorService s, Closure c)` - schedules a closure on the target ExecutorService. The executor service can be left unspecified, if so a default Thread pool executor (with 2 threads) will be used.
- `execFuture(ExecutorService s, Callable c)` - schedules a callable on the target ExecutorService. The executor service can be left unspecified, if so a default Thread pool executor (with 2 threads) will be used.

## 9.3 Annotation Based Threading

Starting with Griffon 0.9.2 there's also the possibility to define an specific thread execution policy for methods and properties via annotations

> This feature is only available for Groovy code at the moment as it relies on the AST Transformation framework.

You must annotate a method or property with `@griffon.transform.Threading` and define a value of type `griffon.transform.Threading.Policy` (though the annotation uses `Threading.Policy.OUTSIDE_UITHREAD` by default). Annotated methods and properties must conform to these rules

- must be public.
- name does not match an event handler.
- must pass `GriffonClassUtils.isPlainMethod()` if it's a method.
- must have `void` as return type if it's a method.
- its value must be a closure (including curried method pointers) if it's a property.

Here's a trivial example

    package sampleimport griffon.transform.Threadingclass Sample {
        @Threading
        void doStuff() {
            // executed outside of the UI thread
        }    @Threading(Threading.Policy.INSIDE_UITHREAD_SYNC)
        void moreStuff() {
            // executed synchronously inside the UI thread
        }    @Threading
        def work = {
            // executed outside of the UI thread
        }    @Threading(Threading.Policy.INSIDE_UITHREAD_SYNC)
        def update = {
            // executed synchronously inside the UI thread
        }
    }

It is worth noting that a `@Threading` annotation applied to a Controller's action/method will take precedence, this means you can force an specific threading policy on a Controller action other than the default one.

    package sampleclass SampleController {
        @Threading(Threading.Policy.INSIDE_UITHREAD_ASYNC)
        def popupDialog = {
            // build and show the dialog
        }    def equivalentPopupDialog = {
            execInsideUIAsync {
                // build and show the dialog
            }
        }
    }