GRT - Generic Runtime Environment
Concepts
GRT
The GRT is a system that allows execution of functions that are
dynamically loaded from modules. Modules may be written in a variety of
languages and a program that uses the GRT may call them in a unified
way. Currently, there is a C API and a lua shell as frontends for the GRT, ie: you can
use the GRT from programs that link to the GRT library or from scripts
written in the Lua language.
When the GRT is started, you must call the functions to initialize the
module loaders that you want to use. Once the loaders are initialized,
you may call myx_grt_scan_for_modules
to look for modules in specific directories. All modules found will be
registered with the GRT. For C modules, you must register them with myx_grt_register_builtin_module
Modules
Modules may be written in any language, as long as there is a module
loader for that language. The current available loaders are for Lua,
Java and C. With exception of C modules (at least at this time), all
modules may be dynamically searched and loaded. C modules must be
compiled in and registered manually, one by one.
Modules implement functions that can be called by the GRT (it may
contain other internal use functions too). A module may also have a
"parent" module. This works similar to a class in an OO language. A
module would be a class and its functions are the methods. A module's
parent would be its "superclass". When a function from a module is
invoked, the GRT looks for the function name in the named module. If
it's not found there, the parent module will be searched and so on,
until the top parent module. Unlike classes, tho, modules can't have
attributes and are not instantiated.
A module must provide the following attributes to the GRT:
- a Name
- a list of Functions that are provided by it
- a "parent" module, which the module extends.
The GRT queries this data when the module is loaded. Therefore modules
must implement a function called getModuleInfo()
, which
takes no parameters and returns a dictionary
(or whatever equivalent datatype there is in the language). For
example, a Lua module would implement something like:
function getModuleInfo()
return {
name =
"someLuaModule",
extends =
"anotherModule",
functions
= {"function1:MyxObject:MyxObject", "function2:MyxObject:"}
}
end
a Java module would be like:
public static HashMap
getModuleInfo()
{
HashMap map= new HashMap();
Vector vector;
map.put("name", "someJavaModule");
map.put("extends", "anotherModule");
vector= new Vector();
vector.add("function1:MyxObject:MyxObject");
vector.add("function2:MyxObject");
map.put("functions", vector);
return map;
}
The function list is a list of function signatures in the form:
function_name
: parameter_struct_name : return_value_struct_name
where:
function_name
The name of the
function
parameter_struct_name
Name
of the struct that the parameter must conform to. May be left empty.
return_value_struct_name
Name
of the struct that the return value must conform to. May be left empty.
Functions
In the point of view of the GRT, all functions must be in the form:
GRT-Value function(GRT-Value)
That is, it must take a single parameter which is a GRT Value and also
return a GRT Value. On the other hand, module loaders, or even
individual modules, may provide higher level interfaces for exporting
functions. For example, in the MigrationTool, by convention, most
functions take and return dictionary GRT Values. So, the loader for
Java modules could provide a wrapper that will take the dictionary
value and transform its items into separate parametes. So, while
someone may invoke a function as:
value= {arg1=123, arg2="bla"}
javaModule.doSomething(value)
the actual implementation may be:
public static int doSomething(int
arg1, String arg2)
Naturally, the loader will have to take information about the function
prototype/signature in some way, from each module. That's up to the
loader itself and will be totally transparent for the rest of the GRT.
GRT Values
GRT Values is what is used to pass around data in the GRT,
between
frontends and modules etc. It supports the following data types:
- integer: (an int, in C)
- real: (a double value, in C)
- string
- list: a list of GRT values. The list contents must be uniform
(ie, only integers or only strings etc)
- dictionary: a mapping from keys to values. Keys are unique
strings in the dictionary that are associated to values, which can be
any GRT value.
The number of datatypes is limited to allow supporting simpler
languages that don't provide more complex data types. All data to be
received and returned from functions must be represented with these
types.
GRT Values may optionally be associated to a GRT Struct. These provide
information about how a given value is structured. It's analog to a
class definition.
The GRT provides functions to represent GRT values in XML. In fact,
some loaders may receive and pass GRT values to functions as XML text.
GRT Struct
GRT Structs provide information about how a piece of GRT Value is
structured. It's existance is optional, but when it exists, values
passed to and received from module functions will be validated against
it. It's sole use inside GRT is for validating data, although it may be
used externally from the GRT as documentation or for other things.
Structs can be assigned to dictionaries and lists. When assigned to
lists, the Struct will be applied to the contents of the list,
therefore they can only be assigned to lists that contain dictionaries.
When a function module needs to pass some kind of information back to the
main program during its execution, such as progress information
or warning messages, it may use a messaging for that.
Module messaging is done through a local socket created by the GRT. It will
only work with module function calls done from a secondary thread, since the
main program needs to check for messages while the function is being
executed. It also has the limitation that only one messaging session may be
active at a time.
To initiate a session, the GRT needs to be prepared by calling
myx_grt_setup_module_messaging()
before the module function is called.
Modules should perform the following:
- connect a socket to the port indicated by the GRT at localhost
- write the cookie string indicated by the GRT in the socket
Once connected and authenticated, the session is established and the socket
may be used to send and receive zero terminated UTF-8 strings.
Use myx_grt_check_module_connected()
to perform the GRT side
of the session establishment and myx_grt_check_module_message()
/
myx_grt_send_module_message() tgo send and receive messages
to the module.
After calling myx_grt_setup_module_messaging()
, usually
once the function has finished executing, you must call
myx_grt_cleanup_module_messaging()
.
The Lua Shell Frontend
GRT Commands
The C API Frontend
General
Module Handling
Functions
Value Handling
Struct Handling
Writing Modules
C Modules
Java Modules
Lua Modules
Python Modules