Writing a singleton startable plugin
A Singleton startable plugin runs on a single server in the cluster.
Write a new class that implements the
IStartablePlugin interface.
Implement the following methods.
- A start method to start your service.
- A stop method to stop your service.
- A property accessor function to get the
Stateproperty from your startable plugin.This method returns a typecode from the typelist
StartablePluginState: the valueStoppedorStarted. The administration user interface uses this property accessor to show the state to the user. Define a private variable to hold the current state and your property accessor (get) function can look simple.// Private variables... var _state = StartablePluginState.Stopped; ... // Property accessor (get) function... override property get State() : StartablePluginState { return _state // return our private variable }Alternatively, combine the variable definition with the shortcut keyword to simplify your code. You can combine the property definition with the variable definition in a single code statement.
var _state : StartablePluginState as State
The plugin includes a constructor which is called on system startup. However, locate the service code in the plugin’s start method, not its constructor.
The start
method must initialize the plugin’s State
property by using an internal variable defined in the plugin. The variable’s
value must be one of the supported values of the StartablePluginState class, such
as Started or Stopped.
The start method can also start any desired listener code or threads, such as a JMS queue listener.
The start
method accepts an argument that references a callback handler of type
StartablePluginCallbackHandler.
This callback is important if the startable plugin modifies any entity
data, which most startable plugins do.
Any plugin code that affects entity data
must be run within a method called execute.
The execute method accepts
an argument of a special type of in-line function called a Gosu block,
which is described in the Gosu Reference
Guide. The Gosu block itself accepts no arguments. The execute method is then passed
to the callback handler.
If you do not need a user context, use the simplest version of the callback handler method execute, whose one argument is the Gosu block.
You do not need to create a separate bundle. If you create new entities to the current bundle, they are in the correct default database transaction the application sets up for you. Use the code returned by the Transaction.getCurrent method to get the current bundle if you need a reference to the current writable bundle.
The Java language does not directly support blocks. If you implement your plugin in Java, you cannot use a Gosu block but you can use an anonymous class to do the same thing.
The plugin’s start method also includes a boolean variable that indicates
whether the server is starting. If true,
the server is starting up. If false,
the start request comes from the Startable Services
user interface.
The following shows a simple Gosu block
that changes entity data. This example assumes your listener defined
a variable messageBody
with information from your remote system. If you get entities from a
database query, remember to add them to the current bundle.
The following example queries all User entities and sets a property
on results of the query.
// Variable definition earlier in your class...
var _callback : StartablePluginCallbackHandler;
...
override function start( cbh: StartablePluginCallbackHandler, isStarting: boolean ) {
_callback = cbh
_callback.execute( \ -> {
var q = gw.api.database.Query.make(User) // run a query
var b = gw.Transaction.Transaction.Current // get the current bundle
for (e in q.select()) {
// Add entity instance to writable bundle, then save and only modify that result
var writable_object = bundle.add(e)
// Modify properties as desired on the result of bundle.add(e)
writable_object.Department = "Example of setting a property on a writable entity instance."
}
})
// You do not need to commit the bundle here. The execute method commits after your block runs.
}
Note that to make an entity instance writable, save and use the return result of the bundle add method.
Just like your start method must set your internal
variable that sets its state to started, your stop method must set your internal
state variable to StartablePluginState.Stopped.
Additionally, stop whatever background processes or listeners you started
in your start method.
For example, if your start
method creates a new JMS queue listener, your stop method destroys the listener.
Similar to the start method’s
isStartingUp parameter,
the stop method includes
a boolean variable that
indicates whether the server is shutting down now. If true, the server is shutting down.
If false, the stop request
comes from the Startable Services
user interface.
