Compiling High-level Access Interfaces for Multi-site Software (CHAIMS) |
Catherine Tornabene
(catherine@cs.stanford.edu)
January 29, 1998
This is the most current version of the CHAIMS API for the main CHAIMS calls, as reflected in the BNF used by the compiler and the CHAIMS programs we have created and run. Some of this is not supported by the compiler, particularily the most recent changes.
One point to note is that I have not included the control
statements such as if
and while
. Since
we compile those statements without an error, they are technically
part of the CHAIMS language. However, such control statements will
eventually be used to do optimizations, and we do no such optimizing
at all, so they are essentially unsupported. I left them off of this
document for that reason.
Old API
I have updated this API to include the new primatives we have added to the language. Since this builds off of the old API, I have included a link here to the previous version of this document so we can track the changes as necessary.
Woody Pollack has made minor changes to the API 3/30/98.
The SETUP call establishes communication with a designated megamodule.
moduleID
= SETUP ("megamodulename
", "hostname
")
module_identifier
is an identifier for the connection. Future
invocations to the megamodule designated by megamodulename
are
specified using moduleID
.
See other CHAIMS calls below.
"megamodulename
" refers to the name of the megamodule as
it is registered at the server side. In CORBA terminology, this is
the server name as registered in the Implementation Repository. This
is required in the SETUP call and must be first in the argument list.
"hostname
" refers to the name of the machine that the
server is located on (or is the gateway server for the service; it's
possible the service consists of multiple servers). An
example of a hostname
used might be sole.stanford.edu.
This is required in the SETUP call and must be second in the argument
list.
In the earlier API, SETUP was used to establish a connection as well as set the default attributes of the megamodule. We have since split that behavior into two different calls, SETUP and SETATTRIBUTES. SETUP is now used only to establish a connection.
We are examining ways of eliminating the hostname
argument from the SETUP call, as this seems like information that
a megaprogrammer should not need. It's probable that information
regarding the hostname would be kept in a repository, and therefore
automatically incorporated into CHAIMS-generated clients.
For the CORBA runtime, the SETUP call produces the binding call necessary to bind to a CORBA object. While there is a matching SETUP API in the CHAIMS compliant RR (room reservation) server, we aren't currently using it; for CHAIMS compliant megamodules, there probably isn't much need to support SETUP directly.
The SETUP call also creates, in the CORBA client code, an
instantiation of the megamodule
object (CORBA server
name) which corresponds to the unique moduleID
specified
by the megaprogrammer. The actual name used in the generated CORBA
client code is not the same, but the correspondence is there.
The identifier moduleID
is not a return value in the
traditional sense; that is, the SETUP call does not return a value
from the megamodule which is assigned to the variable
moduleID
. I realize that it does look like a
traditional return value since it is on the left hand side of an
equality. However, this is to provide a simple means for the
megaprogrammer to identify the connection. The identifier assignment
is required by the CHAIMS compiler. The compiler will exit with an
error if the SETUP call does not have an assignment. We therefore
force an identifying association for each connection to a megamodule.
The SETATTRIBUTES call is used to establish any global parameters that are not invocation specific.
moduleID
.SETATTRIBUTES
(attribute1
= "value 1
",
attribute2
= value2
)
moduleID
is the connection identifier established by a
previous call to SETUP.
attribute1 and attribute2
are global attributes
of the megamodule identified by moduleID
.
"value 1"
is the value we want to assign to
attribute1
. This form of assignment is used for simple types such
as strings or integers.
value2
is the value we want to assign to
attribute2
. value2
is an ASN.1 object
that has a series of attributes inside in a form known by the megamodule
or by the megamodule wrapper.
The megaprogrammer can assign the global attributes needed using the SETATTRIBUTES call, but it is up to the megamodule to ensure that these settings are static. The megaprogrammer cannot force the megamodule to maintain internal consistency. However, if megamodules are providing a commercial service, then it is in their best interests to be reliable. Still, it is important to note that while the megaprogrammer can request a global attribute to be set, it is up to the megamodule to enforce that assignment.
There is no order required in the parameter list for the SETATTRIBUTE call, nor is every possible value assumed to be set. It is presumed that a megamodule will have responsible default values, if necessary.
The attributes along with the assignments are really a sequence of
attribute-name and value pairs. This format is designed to be
flexible. It is supported by the wrappers, which use an object
structure called CHAIMSATTRVALSEQ to transfer data and identifying
information from the CHAIMS megaprogram through the wrapper to the
non-CHAIMS compliant megamodule. (This is done using the
CORBA::any
to represent an arbitrary type and the
CORBA::typecode
to record the type of the value.) The name-value
pairing is also consistent with the internal representation of ASN.1
objects, which makes for an easier conversion to ASN.1 objects when
needed.
The INVOKE call starts the execution of a specified method.
invokeID
= moduleID.INVOKE ("methodname
", attribute1 = "value1", attribute2 = value2)
invokeID
is an identifier for the invocation.
Since control is returned to the CHAIMS program, this is used when doing
EXAMINE and TERMINATE calls so that
the correct process is identified for those calls.
moduleID
is the module identifier
created by the SETUP call. See SETUP description above.
"methodname"
is the name of the method in the megamodule
that the megaprogrammer wishes to use. In the case of megamodules that
only offer one service, this may be the name of the megamodule itself.
This argument is required in the INVOKE call, and
must be first in the argument list.
attribute1 and attribute2
are input arguments to the
megamodule. These are defined in the exact same manner as the
parameters to SETATTRIBUTES shown above. As with the SETATTRIBUTES
call, there can be as many arguments declared as the megamodule
wrapper (or native CHAIMS megamodules) will support. Order of the
input arguments is irrelvant as long as they follow
methodname
. No input arguments are required to compile
the megaprogram, but the megamodule may indicate an error if input
arguments are needed to perform any useful calculations or services.
The error would be seen by the megaprogrammer when GETATTRIBUTES is
performed (or possibly EXAMINE).
Currently, a CHAIMS INVOKE call results in a
CORBA method invocation by the megamodule instansiation which was created
by the SETUP call above. The method invoked is methodname
.
If the method is contained within a CHAIMS-compliant megamodule,
the method call within the generated CORBA client is asychronous, using
CORBA's oneway
designation.
However, as we cannot expect CHAIMS compliancy to be the norm, most invocations will go through a wrapper. In addition to providing some data marshalling services (see SETATTRIBUTES above), the wrapper will simulate an ayschronous call to a megamodule that may not provide for true asychrony. The call that the CHAIMS compiler generates is for the wrapper, and it is sychronous.
The EXAMINE call is used to determine the state of the invocation
referred to by invokeID
.
examine_output
= invokeID
.EXAMINE ()
examine_output
is an object that holds the
result of the examine call.
invokeID
is the invocation identifier assigned
in the INVOKE call above.
This call works like a traditional assignment. The variable
examine_output
is assigned the results of the call
to EXAMINE.
The compiler currently recognizes the result of the EXAMINE to be a character string. In other words, in the CORBA client code, the code is written such that the result of the call is assigned to a character string.
We do not have a megamodule that does anything approaching the concept for which the EXAMINE call was created. We have been able to test that the CORBA client code created is correct by returning a string from the megamodule, but our megamodules don't examine their own processes and return a descriptive result.
One point worth mentioning is that it is possible that the
object examine_output
might be more generalized to
hold both the output of the EXAMINE call and also the output
of an EXTRACT or GETATTRIBUTES call.
The EXTRACT call collects the results of an invocation within an object. Generally it is presumed this will be an ASN.1 object.
extract_output
= invokeID
.EXTRACT ()
extract_output
is the object that holds the
results of the invocation.
invokeID
is the invocation identifier assigned
in the INVOKE call above.
The assignment works like a traditional assignment in this case as well. The variable at the left hand side of the equality gets the value returned by the call on the right hand side of the equality.
We are looking at using some of ASN.1's print utilities within a CORBA compliant (and possible Java based) I/O module.
The GETATTRIBUTES call returns the (global?) attributes of the megamodule.
attributesObject
= invokeID
.
GETATTRIBUTES ()
attributesObject
= moduleID
.
GETATTRIBUTES ()
We have debated in several meetings whether to replace EXTRACT completely with GETATTRIBUTES, or whether to use EXTRACT for invocation specific attributes and GETATTRIBUTES for module specific attributes. This has not been fully decided.
The TERMINATE call kills either a running invocation or a connection to the megamodule.
moduleID
.TERMINATE ()
invokeID
.TERMINATE ()
moduleID
is the identifer for the connection
established by a call to SETUP.
invokeID
is the identifer for an invocation
established by a call to INVOKE.
The TERMINATE call which is done using setupID
produces the CORBA client code necessary to release the binding
created during the initial SETUP.
The call to TERMINATE using the invokeID
does the same thing, for now. This is obviously wrong, but I am
undecided as to what code to generate that would stop a running
CORBA process (i.e., do I kill it from the client end, or do
I sent the request to a CHAIMS wrapper or megamodule that will
process the request to terminate the method as it sees fit).
I'm leaning towards the latter; opinions are welcome.