- every libmsgque communication link is a link between one client and one server
- the link is created and maintained by libmsgque as a socket communication using unix-domain-sockets or inet-domain-sockets
- client and server are using the same communication library called libmsgque
- find and start the service (e.g. server)
- setup and maintain the socket communication interface between client and server
- choose the right byte-order (little/big endian)
- verify 'service' api version
- if an error happen, propagate the error to the client
- do all the send and recv stuff
- do (if necessary) the casting of different types
- provide an event-loop to smoothly integrate multiple tasks
- after the work was done do a clean shutdown of the communication
- DEFINITION: understand means knowing the exact definition of the procedure called.
- client and server using the same protocol as part of libmsgque
and this protocol include the service called together with the arguments provided in a libmsgque package. The type of a argument can be string, binary, list or native. The native type is defined in MqBufferAtomU. The type string is casted into native if the application require this.
- the protocol layer is totally hidden to the programmer
- the server provides a service identified as a 4 byte character string
- the client is calling the service with the arguments included (example calling service
ECOI):
using libmsgque code using ccmsgque code ctx.SendSTART ();
ctx.SendI (567);
ctx.SendEND_AND_WAIT ("ECOI", 10);
using csmsgque code ctx.SendSTART ();
ctx.SendI (567);
ctx.SendEND_AND_WAIT ("ECOI", 10);
using tclmsgque code
$ctx SendSTART
$ctx SendI 567
$ctx SendEND_AND_WAIT ECOI 10
using javamsgque code
ctx.SendSTART();
ctx.SendI(567);
ctx.SendEND_AND_WAIT("ECOI", 10);
using pymsgque code
ctx.SendSTART()
ctx.SendI(567)
ctx.SendEND_AND_WAIT("ECOI", 10)
using perlmsgque code
$ctx->SendSTART();
$ctx->SendI(567);
$ctx->SendEND_AND_WAIT("ECOI", 10);
using vbmsgque code
ctx.SendSTART()
ctx.SendI(567)
ctx.SendEND_AND_WAIT("ECOI", 10)
and wait (MqSendEND_AND_WAIT) or does not wait (MqSendEND) for an answer.
- the server reply the client-service-call with the return data.
- the number and the type of the call-arguments and the number and the type of the reply-arguments are not agreed by the protocol but the type checking is strict. strict mean that every argument send type have to be read by the same type with the exception that a cast from and to type C is supported. Every type mismatch will result in an error even if the send value will fit into the target type.
- no login verification
- no encoding or decoding of binary data
- no encryption or decryption of binary data
- WHAT-IS: client versa server
- every client-parent-context start its own server
- every started server is totally independent from the other server might exist
- advantage: easy load balancing because every server process is able to use an other processor
- advantage: no namespace pollution by the server
- advantage: no crash dependency between the client and the server. (If the server crashes the client still continue to work)
- advantage: using different programming languages between client and server
- DEFINITION: The "state" ought to be the totality of everything that can make two identical sequences of libmsgque library commands return different results. A typical case could be if one wants to wrap a Tcl shell up as a libmsgque service; this then has an internal state (values of variables, commands defined, etc.), and it would have to be part of the total state of the service.
- INTRO: WHAT-IS: client versa server
- every client creating a new parent-context is creating a new parent-context on the server.
- a new parent context on the server is in fact a struct able to store every per-context data.
- For tclmsgque the new context struct is a command and every new Server-Parent-Context is a new interpreter.
- For javamsgque the new context is a javamsgque.MqS object and every new Server-Parent-Context is a new thread.
- For pymsgque the new context is a pymsgque.MqS type and every new Server-Parent-Context is a new interpreter.
- from the client point of view it is an replacement
- OLD: I have to link with libXXX.so
- NEW: I have to link with libmsgque.so and using service XXX
- NEW: no need for libXXX.so, no linking, no searching for the right library for my OS, no errors on linking again a wrong version of library, no need for installing all libraries on my host and last but not least your tcl event-loop will always been working
- I personal call it a network shared library or just a service
- from a programming point of view writing applications based on services is much more easy as writing applications based on shared libraries
- reuse service based code is a lot easier as reusing shared library based code
(Example: libXXX.so need a libperlXXX.so, libtclXXX.so, libphpXXX.so, libjavaXXX.so. libc::XXX.so, infinite long ... interface library but only one libmsgque.so interface library)
- DEFINITION: shared as think of it means that the same code can be used by multiple threads of execution simultaneously.
- a service usually has: libSomthing.(a|lib|so|dll) + libmsgque.(a|lib|so|dll) + main.c + context.c + ... *.c
- sharing code means using dynamic linking (so|dll) rather than static linking (a|lib)
- sharing a running service is available as:
- only one client connect to one server
- every client has one parent-context but multiple child-context
- an advanced event-queue is available to serve multiple requests at the same time
- INTRO: WHAT-IS: client versa server
- DEFINITION server:
- a server is an application which can handle multiple client connections and serve some kind of services, with the help of a server-API, to the client (example: Sybase/Oracle/Db2/... database, Ars, SAP, PeopleSoft, ... infinite long ...)
- a libmsgque - server is a wrapper around the server-API form 1. to disconnect the client from the server-API
- in libmsgque one libmsgque - server supports one client but every client supports multiple libmsgque - server.
- libmsgque was designed to replace server specific API's (as static or dynamic libraries)
- libmsgque was designed to be very simple and easy to use for programming purpose
- libmsgque was designed to solve the every 'scripting' language maintain its own link between application API's and language API's problem
- example: Ars (http://en.wikipedia.org/wiki/Action_Request_System) is an application server using a SQL database to serve a work-flow like applications. Ars has its own user management and providing it's own API for login, query, modify ... . the ArsService created by libmsgque does not replace the Ars server. a libmsgque ArsService is used to replace the Ars specific protocol and the Ars specific API with a common usable API. in this case you can call it a protocol-converter with additional features to pre-process the data.
OLD: Database NEW: Database *
| | *
ArsServer ArsServer *
| | | | <- Ars-Protocol *
Ars-Protocol -> | | ArsService1 ArsService2 <- libmsgque-API + Ars-API *
| | | | <- libmsgque-Protocol *
Ars-API -> Client1 Client2 Client1 Client2 <- libmsgque-API *
- OLD: your client depend on Ars - Api
- NEW: your client depend on libmsgque - Api
- OLD: if you keep in mind that every application (e.g. Ars, SAP, Peoplesoft, Oracle, Sybase, MqSeries, ... infinite long) providing its own API you will recognize that your application(s) will depend on all these API's
- NEW: it doesn't matter which application you are using, there is only ONE API -> libmsgque
- to use a new, already available, libmsgque - service in TCL you only have to write a wrapper in TCL and NOT in C using the, already available, tclmsgque API
- the connection between the ArsServiceX and the ArsServer is just an traditional software engineering project. libmsgque is providing a solution to connect the client to the ArsService not to the ArsServer because the ArsServer is Ars specific and usually hidden to external programmers.
- the difference between OLD and NEW is that:
- OLD: ClientX is using the Ars - API direct
- NEW: ClientX is using the libmsgque - API and ArsServiceX is using the libmsgque - API plus the Ars - API
- Ars - API: handle the communication between ArsServiceX and ArsServer using the Ars - Protocol (every application-API providing methods like init (ARInitialization), login (ARVerifyUser), send something (ARSetEntry,...) and read something (ARGetEntry,...))
- Ars - API: is part of the Ars distribution of Remedy and is a closed source library
- libmsgque - API: handle the communication between ClientX and ArsServiceX using the libmsgque - Protocol
- YES and NO
- YES: if the application is 'closed' source (e.g. commercial) you have no chance to integrate the libmsgque - API into the application
- NO: if the application is 'open' source you can integrate the libmsgque - API direct into the application:
YES: 'closed' NO: 'open' *
Application Application *
Application-API: -> | | | | *
Service1 Service2 | | <- libmsgque-API *
libmsgque-API: -> | | | | *
Client1 Client2 Client1 Client2 *
- NO: libmsgque is able to use an external created file-descriptor as argument to the
"--pipe --socket #" MqLinkCreate configuration option for socket communication
- INTRO: WHAT-IS: client versa server
- DEFINITION: Re-entrant means that the same body of code can be used by multiple threads of control at once, provided that each thread supplies its own data segment for the code to use.
- Every Context (parent-context and child-context) has its own services and data.
- DEFINITION: Serially reusable means that the same body of code can be used by multiple threads of control, provided that execution of the code is allowed to complete before another thread can use the shared body of code.
- The body of a service-function get the according context as first parameter of type MqS. This parameter is used to read package data (example: MqReadU) and to answer the service-request (example: MqSendU)
- DEFINITION: In this case locked means prevented from execution.
- Every parent-context is a process or a thread.
- Every child-context of this parent-context is part of this single process too.
- One single process can handle only one request per time but is able to listen on other incoming requests if the original request is waiting on an external resource. This waiting is done in the MqSendEND_AND_WAIT and the MqProcessEvent function.
- libmsgque was designed to act as an event based scheduler doing io in a parallel manner.
- Example: multiple parent-context (CTX1, CTX2, CTX3) : using 'Tcl' code
# SLEP ... service doing a 'sleep' system-call on the server -> blocking the server
# client is doing the following 3 jobs
after 100 "$CTX1 send -wait SLEP 10"; # test-case: service sleeps 10 seconds
after 100 "$CTX2 send -wait SLEP 5"; # test-case: service sleeps 5 seconds
after 100 "$CTX3 send -wait SLEP 8"; # test-case: service sleeps 8 seconds
# wait on finish all 3 jobs
the example needs 10 seconds to finish and not 23
- Example: single parent-context (CTX) : using 'Tcl' code
# SLEP ... service doing a 'sleep' system-call on the server -> blocking the server
# client is doing the following 3 jobs
after 100 "$CTX send -wait SLEP 10"; # test-case: service sleeps 10 seconds
after 100 "$CTX send -wait SLEP 5"; # test-case: service sleeps 5 seconds
after 100 "$CTX send -wait SLEP 8"; # test-case: service sleeps 8 seconds
# wait on finish all 3 jobs
the example needs 23 seconds to finish and not 10