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:
  1. a Name
  2. a list of Functions that are provided by it
  3. 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:
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.

Module Messaging

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:
  1. connect a socket to the port indicated by the GRT at localhost
  2. 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