javamsgque
The
JAVA Application-Server Project
import javamsgque.*;
OBJECT CREATION AND DELETION
OBJECT CONFIGURATION
LINK CREATION AND DELETION
ADDING SERVICES
SEND DATA
READ DATA
SLAVE OBJECT
BUFFER OBJECT
EXCEPTION OBJECT
The msgque project is an infrastructure to link software together to act like a single software. To link mean distributing work from one software to an other software an wait or not wait for an answer. The linking is done using unix or inet domain sockets and is based on packages send from one software to an other software and back. The msgque project is used to handle all the different aspects for setup and maintain the link and is responsible for:
- starting and stopping the server application
- starting and stopping the communication interface
- sending and receiving package data
- reading and writing data from or into a package
- setup and maintain the event-handling for an asynchronous transfer
- propagate the error messages from the server to the client
The
object is the user visible part of a
javamsgque application link.
Create an object ready to be used with
ctx.LinkCreate(String... argv) to setup an application link. Use the
isConnected to check if a link is already available.
final class MyClass extends MqS ... { ... }
public static void main(String[] args) {
MyClass ctx = new MyClass(); ...
}
Delete the entire object including the application link using
ctx.LinkDelete(). The object can
not be reused.
The configuration of an object is done using the functions starting with
MqConfig... or by using command-line arguments.
Initialize the process startup argument prefix. The startup-prefix have to be the name of the executable found in the
PATH and additional arguments like a script name or required startup options. The startup-prefix is used for two different purpose:
- To start a new entity using the --spawn command-line option
- To replace the SELF argument after the "@" command-line argument
The startup-prefix is not set by default.
type: int,
get: ConfigGetBuffersize ,
set: ConfigSetBuffersize
The send and receive buffersize in bytes (default: 4KB)
type: int,
get: ConfigGetDebug ,
set: ConfigSetDebug
Debug a message-queue application. Valid values are 0 <= NUM <= 9 using 0 for "no debugging" and 9 for "maximum debugging". (default: 0)
type: long,
get: ConfigGetTimeout ,
set: ConfigSetTimeout
User defined timeout used for connection setup and data sending (default: 90 seconds)
type: String,
get: ConfigGetName ,
set: ConfigSetName
Use STRING as basename of the new message-queue object. The name shows up in the debugging output and is used as prefix for the new created command. (default: the name of the executable)
type: String,
get: ConfigGetSrvName ,
set: ConfigSetSrvName
Use STRING as a client specific prefix in the server debugging output. This is used to link debugging and error messages on the server to a specific client connection. (default: empty)
type: boolean,
get: ConfigGetIsSilent ,
set: ConfigSetIsSilent
Write (false) or don't write (true) any output to stdout or stderr. (default: write to stdout or stderr)
type: boolean,
get: ConfigGetIsString ,
set: ConfigSetIsString
Use (true), as much as possible, strings in the data-package. Convert any native data-type, like integer or double, into a string (sending) and back to native (receiving). (default: use binary)
type: int,
get: ConfigGetStartAs ,
set: ConfigSetStartAs (startAs)
Start a new server as thread or spawn a new process or fork a new process. This arguments are used with:
- Parameters:
-
| [in] | startAs | 0=default, 1=fork, 2=thread and 3=spawn |
type: String,
get: ConfigGetIoTcpHost/Port/MyHost/MyPort ,
set: ConfigSetIoTcp (host, port, myhost, myport)
Configure a tcp socket link.
- Parameters:
-
| host | client: name of the remote host (default: localhost)
server: name of the local interface (default: listen on all interfaces) |
| port | client: name of the remote port
server: name of the local port |
| myhost | client: name of the local interface |
| myport | client: name of the local port |
- Attention:
- named ports are supported as well
type: String,
get: ConfigGetIoUdsFile ,
set: ConfigSetIoUds (file)
Use a uds (http://en.wikipedia.org/wiki/Unix_domain_socket) socket link. The uds communication is usually 50% faster than a local tcp communication but only available on UNIX.
- Parameters:
-
| [in] | file | the name of the uds file |
type: int,
get: ConfigGetIoPipeSocket ,
set: ConfigSetIoPipe (socket)
Start a pipe server to listen on socket. This is the default mode to start a server. The socket option is special because it is used for internal purpose to submit the socket from the client to the server started as pipe by the client.
- Parameters:
-
| [in] | socket | the file-descriptor number. The only public usage for this option is to serve as interface for an existing tool like (x)inetd. The (x)inetd tool is a UNIX service to listen on a tcp/ip port and start for every connection the proper entry from the file /etc/(x)inetd.conf with the file-descriptor 0 as send/recv socket handle. |
type: MqC,
get: ConfigGetMaster ,
set: SLAVE OBJECT
return the master if ctx is a slave-context or NULL if ctx is not a slave-context. !Only a SLAVE has a master!
type: int,
get: ConfigGetCtxId ,
set: NO
return an identifier as integer and is unique per parent-context. The parent-context is always 0 and every new child-context get a new identifier by adding 1.
type: String,
get: ConfigGetToken ,
set: NO
return the current TOKEN IDENTIFIER and is only useful in a service callback. This command is needed on the server to implement a generic service (A ctx.ServiceCreate(String token, IService service) with different TOKEN IDENTIFIER but with the same service callback).
type: boolean,
get: ConfigGetIsConnected ,
set: NO
Is the javamsgque context connected ? A context is connected if the ctx.LinkCreate(String... argv) command was successful and a context is NOT connected if a) the object has just been created or b) the link was deleted with ctx.LinkDelete()
type: boolean,
get: ConfigGetIsServer ,
set: IServerSetup or IServerCleanup
True if object is a server object (default: false, be a client)
type: boolean,
get: MqConfigGetIsParent ,
set: NO
True if object is a parent object (default: true, be a parent)
type: boolean,
get: ConfigGetIsSlave ,
set: NO
True if object is a slave object (default: false, not be a slave)
type: Interface,
get: NO ,
set: javamsgque.IServerSetup
Interface to define a server javamsgque object. This Interface define the ServerSetup callback called at ctx.LinkCreate(String... argv) to define the services or to initialize context specific variables. This interface set the isServer configuration value to true.
type: Interface,
get: NO ,
set: javamsgque.IServerCleanup
Interface to define a server javamsgque object. This Interface define the ServerCleanup callback called at ctx.LinkDelete() to free context specific variables. This interface set the isServer configuration value to true.
type: Interface,
get: NO ,
set: javamsgque.IFilterFTR
Interface required to define a filter data stream object. This Interface define the IFilterFTR callback. The callback is used to act on filter data rows. Every filter input data is a list of filter data rows and every row is a list of filter data columns. Every row is send from one filter-command to the following filter-command as FTR service request. This interface set the isServer configuration value to true. (read more at: FILTER MODE)
type: Interface,
get: NO ,
set: javamsgque.IFilterEOF
Interface required to define a filter data stream object. This Interface define the IFilterEOF callback. The callback is used to act on End-Of-Filter data and is called after all IFilterFTR data was send. Sometimes the filter data can not be served as IFilterFTR data (example: sorting of the input rows need to read all rows before the data can be send to the next filter command) and the IFilterEOF callback is used to continue send IFilterFTR data rows. This interface set the isServer configuration value to true. (read more at: FILTER MODE)
type: Interface,
get: NO ,
set: javamsgque.IFactory
The factory pattern is used to create a new application object (read more at: MqSetupS::Factory) Without the Factory pattern only the initial startup context is available to serve incoming requests. In general every server need to provide a Factory pattern.
final class Server extends MqS implements IFactory, ... {
public MqS Factory() {
return new Server();
}
...
}
type: Interface,
get: NO ,
set: javamsgque::IBgError
Define an asyncrone error handler. This handler is used for handle errors send with ctx.SendERROR(). Use int ex.GetNum() or ctx.ErrorGetNum() and String ex.GetTxt() or ctx.ErrorGetText() to access the error.
To create and to destroy a link is the main purpose of the
javamsgque library. A link is a client/server connection used to perform various tasks.
Create a
parent-context using the
OBJECT CONFIGURATION. A parent-context is responsible to setup the client/server link:
- the client-parent-context create the server-parent-context
- the server-parent-context wait for a client-parent-context connection request
- Parameters:
-
- Attention:
- if the first argument after the "@" item is the string "SELF" an independent server of the current server is started. This is not a SLAVE OBJECT. The "SELF" argument is replaced by an application default setting (if available) or by arguments set with static: Init(String... args).
Create a
child-context from a
javamsgque parent-context and command-line arguments. A child is using the same process or thread as the parent but a different namespace. With a different namespace a child is able to act on different services on the shared server.
- Parameters:
-
| [in] | ctx | the object from OBJECT CREATION AND DELETION |
| [in] | parent | the parent object |
| [in] | args | all command-line arguments including the "@" token |
Close the client/server link and delete the underlying communication object. All depending objects will be deleted as well like depending
child-context and
slave-context local and on the remote site of the link.
Shutdown the entire communication and exit the current process or thread.
To provide a
service is the main purpose of a server. The
ctx.ServiceCreate(String token, IService service) method is usually added in the
ServerSetup method of the
IServerSetup.
public void ServerSetup() { ServiceCreate ("SRV1", new SRV1()); }
The
token is a 4 byte string and identifies the service. The
token is used in:
A service is using a callback to act on an incoming service request. The callback is used on a
server using
ctx.ServiceCreate(String token, IService service) or on a
client using
ctx.SendEND_AND_CALLBACK(String token, IService callback).
The callback is implemented using Interface: IService method Service(MqS ctx)
Create a new service listen on
TOKEN IDENTIFIER and start for every incoming request a
service. (on error return an
EXCEPTION OBJECT)
Delete a new service listen on
TOKEN IDENTIFIER . (on error return an
EXCEPTION OBJECT)
Start the Event-Loop and check for the next event. In
client mode this command is usually used together with
ctx.SendEND_AND_CALLBACK(String token, IService callback) to process the results.
- Parameters:
-
| [in] | timeout | don't wait more than TIMEOUT seconds to get an answer from the server. If no answer is available an error is raised. (default: command-line: --timeout) |
| [in] | MqS.WAIT | use flag value to define the action (default: NO)
- NO, don't wait for an event do just the check
- ONCE, use timeout seconds to wait for exact one event
- FOREVER, wait forever and only come back on error or on exit
|
The
Send style methods are used to build and send data using the
javamsgque send data package. The data is typed using the
TYPE IDENTIFIER and the methods can wait or not for an answer. During waiting the the application is still able to work on events like other
javamsgque client/server links.
ctx.SendSTART();
ctx.SendI(num);
ctx.SendL_START();
ctx.SendD(balance);
ctx.SendC("name of the owner");
ctx.SendB(signature);
ctx.SendL_END();
ctx.SendEND_AND_WAIT("SRV1");
Initialize a
javamsgque send data package. This method is required.
Send the package using
TOKEN IDENTIFIER without expecting an answer (FireAndForget). (on error return an
EXCEPTION OBJECT)
- Attention:
- if an error is raised on the server during service-processing the error is send back as asynchronous event and can be raised sometime in the future. To be sure to get the error immediately use ctx.SendEND_AND_WAIT(String token, [int timeout])
Send the package using
TOKEN IDENTIFIER and wait
timeout seconds for an answer. (on error return an
EXCEPTION OBJECT)
Send the package using
TOKEN IDENTIFIER and
don't wait for an answer. The answer will be handled by the
SERVICE CALLBACK. (on error return an
EXCEPTION OBJECT)
Answer an incoming service-call started with
ctx.SendEND_AND_WAIT(String token, [int timeout]) or
ctx.SendEND_AND_CALLBACK(String token, IService callback). The return package is build-up like the previous service call package but with a
ctx.SendRETURN() as final command. (on error return an
EXCEPTION OBJECT)
Send an asyncrone error to the link target. (on error return an
EXCEPTION OBJECT)
Send a filter stream data package using
FILTER MODE. (on error return an
EXCEPTION OBJECT)
Send a filter end-of-file data package using
FILTER MODE. (on error return an
EXCEPTION OBJECT)
Add an item using
TYPE IDENTIFIER to the
javamsgque send data package. (example:
SendY)
Start to send an embedded list item.
Finish to send an embedded list item.
Read data from an incoming
javamsgque read data package:
- on a server to serve an incoming service-call from the client
- on a client to process the return-data from a previous service-call
Reading data is a passive task in opposite to sending data which is an active task. Passive mean that the read is triggered by an incoming data-package and not by the software-workflow.
num = ctx.ReadI();
ctx.ReadL_START();
balance = ctx.ReadD();
owner = ctx.ReadC();
signature = ctx.ReadB();
ctx.ReadL_END();
return an item using the
TYPE IDENTIFIER from the
javamsgque read data package. (on error return an
EXCEPTION OBJECT)
return a temporary
BUFFER OBJECT. (on error return an
EXCEPTION OBJECT)
- Attention:
- The object is only valid until a new javamsgque read data package has arrived.
Link two
javamsgque objects to direct pass a data item from one object to the other. (on error return an
EXCEPTION OBJECT)
return the number of items left in the
javamsgque read data package.
Check if are still items in the
javamsgque read data package.
Undo the
last read operation. This is useful if an error was raised or if a buffer object (returned from
MqBufferS ctx.ReadU()) has not the expected type. (on error return an
EXCEPTION OBJECT)
Start to read an embedded list item. Use the current read package (
buffer = NULL) or a
buffer object. (on error return an
EXCEPTION OBJECT)
Finish to read an embedded list item.
The master/slave link is used to create a mesh of nodes by linking different PARENT context objects together.
The master control the slave.
The link is used to perform the following tasks:
- report error messages from the slave to the master
- to create a slave-child-context if a master-child-context is created
- to delete a slave-context if a master-context is deleted
In difference to the client/server link the master/slave link connect two independent msgque-context in the same process or thread (e.g. node). This leads to the restriction that only the master-msgque-context can be a server because only one server per node is possible.
Create a worker as
slave of the
ctx object using the image of the
ctx object self and started as an independent process or thread based on the
command-line: --thread --spawn --fork argument.
- Parameters:
-
| [in] | ctx | the master javamsgque object as SERVER-PARENT without a CHILD |
| [in] | id | an integer used as unique identifer for the master/slave link |
| [in] | args | command-line arguments passed to the worker-client or the worker-server. all arguments prior the first @ token are added to the worker-client and the other arguments to the worker-server. |
example create a worker with id 7 as thread.
ctx.SlaveCreate (7, "--thread", "--silent", "@", "WORKER", "--name", "MyWorker");
Create a master/slave link between the
ctx object and the
slave object. (on error return an
EXCEPTION OBJECT)
- Parameters:
-
| [in] | ctx | the master javamsgque object as PARENT without a CHILD |
| [in] | id | an integer used as unique identifer for the master/slave link |
| [in] | slave | the slave javamsgque object as CLIENT-PARENT without a CHILD |
Delete a
slave-context from a former
ctx.SlaveCreate(int id, MqS slave) command using the same identifier
id. By default the
slave-context object will be deleted if the
master-context is deleted. In addition
only the
parent-slave-context can be deleted explicit. If
id is invalid nothing will happen. (on error return an
EXCEPTION OBJECT)
return the
slave-context from the
ctx.SlaveCreate(int id, MqS slave) using the same identifier
id or
NULL if the
id is not valid or if
ctx is not a
master.
The
class MqBufferS object is created by
MqBufferS ctx.ReadU() and id used to save a
typeless temporary data item from the
javamsgque data package. The lifetime of the
class MqBufferS is only the current callback up to the next read operation of the same context.
MqBufferS buf = ctx.ReadU();
if (buf.GetType() == 'C')
System.out.println(buf.GetC());
A
javamsgque buffer data package is type safe, this mean that every item has a type prefix and every
TYPE ctx.Read[TYPE]() or
TYPE val=buffer.[TYPE] have to match the previous
ctx.Send[TYPE](TYPE value) with the same
TYPE. One exception, the cast from and to string (TYPE=C) is allowed. The following type identifier's are available:
Y : 1 byte signed characterO : 1 byte boolean character using true for yes or true or false for no or wrongS : 2 byte signed shortI : 4 byte signed integerW : 8 byte signed long long integerF : 4 byte floatD : 8 byte doubleB : unsigned char array used for binary dataC : string data using a \0 at the endL : list type able to hold a list of all items from aboveU : typeless buffer able to hold a single item from above
return the data form the buffer using the
TYPE IDENTIFIER. (on error return an
EXCEPTION OBJECT)
return the type as single character of the item stored in the buffer object.
The exception object is used to transport a
javamsgque error using the
class MqSException.
try {
i = ctx.ReadI();
} catch (Throwable ex) {
ctx.ErrorSet(ex);
System.out.println(ctx.ErrorGetText());
ctx.ErrorReset();
}
return the error message from the error object.
return the error number from the error object. The number can be used as exit-code.
create a
javamsgque error object but do
not raise the
EXCEPTION OBJECT
convert a
class MqSException into a
javamsgque conform error using the
ctx object. This method is used to enable additional error processing capabilities from
ctx.LinkDelete() or
ctx.Exit() after the exception was caught and before the application exit or the object is deleted.
clear the
javamsgque error object.
convert and raise an
javamsgque error object into a JAVA
EXCEPTION OBJECT.
print an
javamsgque error object to stderr and
clear the
javamsgque error
The filter mode is related to a special usage of the
javamsgque software called a command pipeline. A command pipeline is well known from the
unix shell to link different commands together to act like a single application:
command1 | command2 | command3
A command pipeline with
javamsgque queues is using the special token
@ to link the commands together:
msgcmd1 @ msgcmd2 @ msgcmd3
To create a
javamsgque filter use:
and to send data to the next filter command use:
The library was tested on Linux, FreeBSD and WindowsXP using a x86_64, ppc processor or i686 processor from the VritualBox emulator.
package example;
import javamsgque.*;
final class mulserver extends MqS implements IServerSetup, IFactory {
class MMUL implements IService {
public void Service (MqS ctx) throws MqSException {
SendSTART();
SendD(ReadD() * ReadD());
SendRETURN();
}
}
public void ServerSetup() throws MqSException {
ServiceCreate("MMUL", new MMUL());
}
public MqS Factory() {
return new mulserver();
}
public static void main(String[] argv) {
MqS.Init("java", "example.mulserver");
mulserver srv = new mulserver();
try {
srv.ConfigSetName("MyMulServer");
srv.LinkCreate(argv);
srv.ProcessEvent(MqS.WAIT.FOREVER);
} catch (Throwable e) {
srv.ErrorSet(e);
}
srv.Exit();
}
}
Start
mulserver.java using
TCP port
7777 and create a
thread for every incoming connection
> java example.mulserver --tcp --port 7777 --thread
package example;
import javamsgque.*;
class mulclient extends MqS {
public static void main(String[] argv) {
mulclient ctx = new mulclient();
try {
ctx.ConfigSetName("MyMul");
ctx.LinkCreate(argv);
ctx.SendSTART();
ctx.SendD(3.67);
ctx.SendD(22.3);
ctx.SendEND_AND_WAIT("MMUL", 5);
System.out.println(ctx.ReadD());
} catch (Throwable e) {
ctx.ErrorSet(e);
}
ctx.Exit();
}
}
Use
mulclient.java to connect to
mulserver.java using
TCP port
7777:
> java example.mulclient --tcp --port 7777
package example;
import javamsgque.*;
class manfilter extends MqS implements IFilterFTR {
public void FTR () throws MqSException {
SendSTART();
while (ReadItemExists()) {
SendC("<" + ReadC() + ">");
}
SendFTR(10);
}
public static void main(String[] argv) {
manfilter srv = new manfilter();
try {
srv.ConfigSetName("filter");
srv.LinkCreate(argv);
srv.ProcessEvent(MqS.WAIT.FOREVER);
} catch (Throwable e) {
srv.ErrorSet(e);
}
srv.Exit();
}
}
Use
manfilter.java in a LibMsgque command pipeline:
> echo -e "1:2:3\na:b:c" | atool split -d : @ java example.manfilter @ atool join -d :
JAVA, C: libmsgque(n), C++: ccmsgque(n), C#: csmsgque(n), JAVA: javamsgque(n), PYTHON: pymsgque(n), TCL: tclmsgque(n), PERL: perlmsgque(n)
JAVA, unix, socket, message, msgque