Event Driven Remoting and Executor Based Remoting allow you to simply expose and execute custom services using the Space as the transport layer. The dynamic tasks feature (also known as "scripting support") allows you to utilize a built remote service, exposed using these two remoting mechanisms, that can execute dynamic language scripts in the space.
The following section goes through the steps needed in order to execute dynamic language tasks. The other sections in this page dive more deeply into different dynamic language support features.
The first step in using scripting is exposing the built in scripting service over the Space. Here is a simple example:
The next simple step is using the exposed scripting service on the client side, here is a groovy example (for more complete client side configuration instructions refer to the Scripting on the Client Side section below):
On the client side Spring XML configuration, the following needs to be defined (mainly to define the connection to the Space as the transport layer, and define the scripting annotation processor):
Script is a simple interface that is defined within the OpenSpaces scripting over remoting support. It has the following basic methods:
There are several implementations of this class which is covered more in the client section. OpenSpaces comes with three different implementations of the Script interface, they are:
OpenSpaces scripting over remoting support has a built in service that allows to expose the execution of scripting code. The service is implemented using the DefaultScriptingExecutor class. The executor supports several scripting languages out of the box, allows to cache compiled scripts, and automatically expose common beans as script parameters.
The DefaultScriptingExecutor holds one or more LocalScriptExecutor. A LocalScriptExecutor implementation is an abstraction on top of an actual scripting language (such as groovy or jruby). OpenSpaces scripting support comes with built in local executors for groovy, jruby, and Java 6 ScriptEngine abstraction.
By default, the default scripting executor identifies if groovy, jruby, or Java 6 scripting support exist within the classpath, and automatically registers then as possible local executors. The relevant local executors are GroovyLocalScriptExecutor for groovy, JRubyLocalScriptExecutor for jruby, and Jsr223LocalScriptExecutor for Java 6. The local scripting executor is chosen based on the Script#getType().
The Script interface allows to define specific parameters per script. The DefaultScriptingExecutor can be configured with a set of parameters that is passed to each script execution. A setParameters that accepts a Map can be passed to each script.
By default, the DefaultScriptingExecutor passes beans of type GigaSpace, keyed by their bean id. The Spring ApplicationContext is passed to the script under the applicationContext key, and the ClusterInfo object is passed under the clusterInfo key.
As an example, if my server side Spring application context has a GigaSpace bean with id of myGigaSpace, a simple groovy script to use it (without configuring anything within the default executor) can be: myGigaSpace.write(new Object()). Note, we use the id of the bean to access the GigaSpace and write a new Object.
A quick note regarding usage of GigaSpace beans. The clustered flag plays an important role when using it. This basically allows to control if the script execution of GigaSpace operations works only against its clustered member space, or against the whole cluster.
If a scripting engine support compilation of scripting, the DefaultScriptingExecutor allows caching of compiled scripts for faster execution. The actual caching of scripts is abstracted using CompiledScriptCache interface, and has default LRU type cache built in.
The compilation is done based on a flag on the Script interface (which defaults to true), and if cached, the "key" of the cache is the script name. This means that if a script was changed, it needs to be executed with a different script name in order for it to recompile and take affect.
Using scripting on the client side is very similar to how similar remoting services are used. There are two types of proxies, executor-proxy and event-driven-proxy, and there are specific scripting annotations that allow to simplify the injection of scripting proxies.
Here is the xml definition of an async scripting proxy (the sync proxy is exactly the same except for the tag/class name of the proxy):
Asynchronous scripting executor:
Executor based scripting executor:
The different components implemented by scripting basically enables all the different scripting client side features which we will cover in the next sections. The annotation based injection is a much simplified way to use scripting on the client side and is shown in the Overview section.
The Script interface allows to set a routing index which controls, both in async and sync mode (not in broadcast mode), where the execution of the script is directed. Here is a simple example of it:
This causes the routing to go the the second member (assuming hash based routing is configured). Naturally, most often a business level routing will be used, for example, direct a script that executed on a certain share to a partition based on the share symbol.
The StaticResourceScript holds the actual script contents and it gets passed for each execution of the script. If script supports caching, there is no need to pass the actual contents of the script on each execution, since once the script was compiled, only its parameters and other values are required, not the actual script. The LazyLoadingRemoteInvocationAspect aspect (on the client side) with the ResourceLazyLoadingScript script type allow for such behavior. As an example:
The above code only loads the test.groovy file if it is required on the server side. By default it is not sent, and if the server has not compiled it, it returns to the client and request the actual script content. The script is then loaded and sent again to the server. This logic is implemented by the LazyLoadingRemoteInvocationAspect.