A library to connect things, run a server and integrate an application.
The libmqmsgque package is the implementation of the Programming-Language-Micro-Kernel (PLMK) into the target-language C.
link: -Lpath -lmqmsgque
or automake: LDADD = libmqmsgque.la
The libmqmsgque package is a composition of multiple classes defining the Programming-Language-Micro-Kernel (PLMK) :
object | description |
---|---|
Mq | the namespace with all libmqmsgque specific definitions |
MqAttribute(…) | the interface to access the package specific attribute |
MqClassAttribute(…) | the interface to access the class specific attribute |
MqClassAttribute(Instance,…) | the interface to access the instance specific attribute |
To access all features without Mq prefix use:
#include "msgque_mq.h"
orLDADD = path/to/libmqmsgque.la
Example from acmds/Makefile.am using libmkkernel.la and libmqmsgque.la:mylib_la_LIBADD = path/to/libmqmsgque.la
C-API: MQ_C_API - theLink - a API to link multiple package-items together to act as one application …
The theLink project is an infrastructure that allows multiple package-items to be linked together to act as one application.
To link, you need to distribute the work from one package-item to another package-item and wait for an answer or not.
The package-item can be a thread, a separate local process that is started by fork or spawn, or even a network of multiple services on multiple hosts.
The package-item can be written in any language that is supported by the Programming-Language-Micro-Kernel (PLMK) support.
It even supports running multiple programming languages in a single piece of software.
Supported Languages are: (C,C++,C#,VB.NET,Java,Python,Ruby,Perl,PHP,Tcl or GO)
The package-item is connected to one another via a pipe or a socket and is based on packages which are sent from one package-item to another package-item and back.
theLink is responsible for:
The LibMsgque library is separted into three programming-layers:
C-API: MqConfigS::cfg - add libconfig configuration file …
A config-file is used to add configuration-values to a libmqmsgque-application using a structured text-file.
A service-callback and "programming" is not supported. To "programm and modify" something use a scripting language like tcl or python.
libconfig is used to parse a config-file using the application … --config fileName …
option.
The following restrictions apply to the --config
option.
--config
option is parsed groupname : { ... }
( ":" or "=" is allowed ) MyClient … --XXX … --config YYY … --ZZZ …
MyClient
: XXX < YYY < ZZZ MyClient --AAA … --config BBB --CCC … @ Filter3 --name otto --DDD … @ MyServer --EEE …
application | groupname | option-parsing-order |
---|---|---|
MyClient | MyClient | AAA < BBB < CCC |
Filter3 | otto | DDD < BBB |
MyServer | MyServer | EEE < BBB |
--name
or --prefix
option from DDD
or EEE
change the group read from the config-file --config
option--config
option overwrite the options from the config-file groupname : { … filter : [ … ] }
) config-file-option define the server to start in a pipe and have to be an array of strings starting with the application-executable OR the factory-identifer 1. Example from MyClient.config
→ filter-pipeline with last server start in debug mode
2. Example from libconfig.test
→ filter-pipeline with last server connect by tcp/ip
MqMsgque SETUP | |||
Cleanup | cleanup libmqmsgque internal memory … | ||
Setup | setup libmqmsgque internal memory … | ||
MqMsgque ENUM | |||
enum MqWaitOnEventE | wait for an event? … | ||
enum MqStatusIsEF | Information about how the context was created. | ||
enum MqStartE | User preferences on HOWTO start a new entity. | ||
enum MqSlaveE | predefined slave-id for well known slaves … | ||
enum MqIdentE | identify the application using prefix (default) or factory … | ||
MqMsgque HELP | |||
Help | write libmqmsgque specific user-help to stderr | ||
HelpMsgque | return a page with the usage of all libmqmsgque specific options | ||
MqMsgque INIT | |||
InitGetArg0 | get the process startup-prefix argument | ||
InitResetArg0 | Reset the process-startup-prefix argument to an empty list … | ||
InitSetArg0 | set the process startup-prefix argument to bfl | ||
InitSetArg0VA | set the process startup-prefix to a args | ||
InitSetArg0VAL | set the process startup-prefix to var_list | ||
MqMsgque MAIN | |||
Main | Main entrypoint - start the application |
C-API: MqMsgque_C_API - MqMsgque PACKAGE - the package is the toplevel structure of the libmqmsgque …
The libmqmsgque package is loaded with:
link:
-Lpath -lmqmsgque
or automake:LDADD = libmqmsgque.la
and is a composition of one or more package-item and exact one package-main.
The libmqmsgque package add the following classes into MkObjectC_C_API :
Object | C-Short | Description |
---|---|---|
MqContextS | MQ_CTX | MqContextC - the class known as ctx or context is the application-handle of the application-server and also the main data-handle … |
MqDumpS | MQ_DMP | MqDumpC - the class known as dmp or dump is used to export a libmqmsgque data package as binary … |
MqFactoryS | MQ_FCT | MqFactoryC - the class known as fct or factory is used to provide an interface to create one or more new MqContextC … |
The libmqmsgque package add the following types into MkObjectC_C_API :
ABSTRACT: MkTypeSTT (TypeTypeType = type of a TypeType) | |- ABSTRACT: MqCtxTypeC_TT (TypeType = type of a Type) | | | |- MqContextC_T | |- ABSTRACT: MkSuperTypeSTT (TypeType = type of a Type) | |- MqFactoryST, MqDumpST
C-API: MqMsgque_Setup_C_API - MqMsgque PACKAGE - setup und cleanup the libmqmsgque …
For details about MqSetup and MqCleanup usage refer to MkKernel_Setup_libmkkernel_C_API
(static) void MqCleanup()
top cleanup libmqmsgque internal memory … → API: MqCleanup
MkCleanup can only be called once and will be ignored if not called in the same thread as MqSetup. after a call to MqSetup the call to MkCleanup is possible again.
(static) void MqSetup()
top setup libmqmsgque internal memory … → API: MqSetup
MqSetup can only be called once, additional call's will be ignored until a MqCleanup is called.
C-API: MqMsgque_Enum_C_API - MqMsgque PACKAGE - enum definition …
read more at: MkKernel_Enum_C_API
top identify the application using prefix (default) or factory … → API: MqIdentE
(static) enum MkErrorE MqIdentE_FromInt(MK_I32 const value, enum MqIdentE *value_out)
top return the MqIdentE from integer … → API: MqIdentE_FromInt
(static) MK_I32 MqIdentE_ToInt(enum MqIdentE value)
top return the MqIdentE as integer … → API: MqIdentE_ToInt
(static) MK_STRN MqIdentE_ToString(enum MqIdentE value)
top return the MqIdentE as string … → API: MqIdentE_ToString
top predefined slave-id for well known slaves … → API: MqSlaveE
(static) enum MkErrorE MqSlaveE_FromInt(MK_I32 const value, enum MqSlaveE *value_out)
top return the MqSlaveE from integer … → API: MqSlaveE_FromInt
(static) MK_I32 MqSlaveE_ToInt(enum MqSlaveE value)
top return the MqSlaveE as integer … → API: MqSlaveE_ToInt
(static) MK_STRN MqSlaveE_ToString(enum MqSlaveE value)
top return the MqSlaveE as string … → API: MqSlaveE_ToString
top User preferences on HOWTO start a new entity. → API: MqStartE
(static) enum MkErrorE MqStartE_FromInt(MK_I32 const value, enum MqStartE *value_out)
top return the MqStartE from integer … → API: MqStartE_FromInt
(static) MK_I32 MqStartE_ToInt(enum MqStartE value)
top return the MqStartE as integer … → API: MqStartE_ToInt
(static) MK_STRN MqStartE_ToString(enum MqStartE value)
top return the MqStartE as string … → API: MqStartE_ToString
top Information about how the context was created. → API: MqStatusIsEF
(static) enum MkErrorE MqStatusIsEF_FromInt(MK_I32 const value, enum MqStatusIsEF *value_out)
top return the MqStatusIsEF from integer … → API: MqStatusIsEF_FromInt
(static) MK_I32 MqStatusIsEF_ToInt(enum MqStatusIsEF value)
top return the MqStatusIsEF as integer … → API: MqStatusIsEF_ToInt
(static) MK_STRN MqStatusIsEF_ToString(enum MqStatusIsEF value)
top return the MqStatusIsEF as string … → API: MqStatusIsEF_ToString
top wait for an event? … → API: MqWaitOnEventE
(static) enum MkErrorE MqWaitOnEventE_FromInt(MK_I32 const value, enum MqWaitOnEventE *value_out)
top return the MqWaitOnEventE from integer … → API: MqWaitOnEventE_FromInt
(static) MK_I32 MqWaitOnEventE_ToInt(enum MqWaitOnEventE value)
top return the MqWaitOnEventE as integer … → API: MqWaitOnEventE_ToInt
(static) MK_STRN MqWaitOnEventE_ToString(enum MqWaitOnEventE value)
top return the MqWaitOnEventE as string … → API: MqWaitOnEventE_ToString
C-API: MqMsgque_Help_C_API - MqMsgque PACKAGE - access to a qualified help-message …
(static) MK_STR MqHelp(MK_STRN tool)
top write libmqmsgque specific user-help to stderr → API: MqHelp
tool | the name of the tool (e.g. argv[0]) or NULL. |
If tool != NULL, the function will display a header like:
tool [ARGUMENT]... syntax: aclient [OPTION]... @ tool [OPTION]... @...
on the help page.
(static) MK_STR MqHelpMsgque()
top return a page with the usage of all libmqmsgque specific options → API: MqHelpMsgque
C-API: MqMsgque_Init_C_API - MqMsgque PACKAGE - initialize the MqContextC startup and/or external-object-link …
(static) MK_BFL MqInitGetArg0()
top get the process startup-prefix argument → API: MqInitGetArg0
MK_NULL
pointer (static) MK_BFL MqInitResetArg0()
top Reset the process-startup-prefix argument to an empty list … → API: MqInitResetArg0
The startup-prefix have to be the name of the executable, found in the PATH
environment variable, and additional arguments like the script name or the required startup options. The startup-prefix is used for two different purpose:
MqStartAs
"--spawn" command-line option."... @ SELF ..."
with "... @ startup-prefix ..."
at LinkCreate.Every use of this function will free the data of the previous startup-prefix. By default the startup-prefix is set during application startup by libmqmsgque and have not to be initialized again.
Example from server.c
→ initialize the startup-prefix with the data read from service-args
static enum MkErrorE Ot_INIT ( MQ_SERVICE_CALL_ARGS ) { MqInitSetArg0 (MqReadALL_e (mqctx)); error: return MqSendRETURN (mqctx); }
(static) void MqInitSetArg0(MK_BAC bfl)
top set the process startup-prefix argument to bfl → API: MqInitSetArg0
The startup-prefix is the argument(s) required to start the application… this is minimal the binary-path for binaries (same as as used on command-line) or the interpreter+scriptFile for scripts.
[in] | bfl | the object will be merged into the startup-prefix, afterwords the bfl is empty and can be deleted |
(static,hide) void MqInitSetArg0VA(MK_STRN arg0, ...)
top set the process startup-prefix to a args → API: MqInitSetArg0VA
MK_NULL
item on end to signal… end-of-list (static,hide) void MqInitSetArg0VAL(MK_STRN arg0, va_list var_list)
top set the process startup-prefix to var_list → API: MqInitSetArg0VAL
C-API: MqMsgque_Main_C_API - MqMsgque PACKAGE - the package-main is a single piece of code evaluated only once at application startup …
Example from MyServer.c
→ The package-main configure the factory and start the server.
#include "common.h" // service to serve all incoming requests for token "HLWO" static enum MkErrorE MyFirstService ( MQ_SERVICE_CALL_ARGS ) { MqSendSTART_E (mqctx); MqSendV_E (mqctx, "%s World", MqReadSTR_e(mqctx)); error: return MqSendRETURN(mqctx); } // define a service as link between the token "HLWO" and the callback "MyFirstService" static enum MkErrorE ServerSetup ( MQ_SERVICE_CALL_ARGS ) { return MqServiceCreate(mqctx,"HLWO", MyFirstService, NULL, NULL, NULL); } // package-item enum MkErrorE MyServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { MQ_CTX const mqctx = *contextP = MqContextCreate(NULL,tmpl); MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); return MK_OK; } // package-main int main (int argc, MK_STRN argv[]) { MqRtSetup_NULL; // setup commandline arguments for later use MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; // create "MyServer" factory… and make it to the default. MqFactoryDefault( MqFactoryAdd_2(MyServerFactory, "MyServer")); // inspect commandline-argument for the "factory" to choose… and create a object MqFactoryNew_E (MqFactoryGetCalledL(largv), NULL, &mqctx); // start listen for incoming call's MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }
(static,hide) void MqMain(MK_PTR code)
top Main entrypoint - start the application → API: MqMain
Tcl has a special requirement, for every new server-thread a new interpreter is created and
this interpreter source the toplevel file for initialization. This file is set on library startup and
can be changed with MqInitResetArg0. The problem is the server startup code from the toplevel. For internal
purpose this code should only be executed on application-startup (like the C main function)
and not for every thread again.
MqContextC CLASS | |||
Define | MqContextC - low level definition, access and cast … | ||
Export | MqContextC - Export class functions … | ||
Introspection | MqContextC - Introspection class functions … | ||
Misc | MqContextC - Misc class functions … | ||
MqContextC TOR | |||
Create | create and initialize the MqContextC ... | ||
Delete | Destructor - delete a MqContextC instance … | ||
MqContextC CLASS API | MqContextC - access data related to the factory-type of the object … | ||
MqContextC CONFIG API | |||
Get | MqContextC - various function to 'get' the configuration-data from a context … | ||
Interface | MqContextC - various function to setup a interface for the context … | ||
Misc | MqContextC - various function to do 'misc' configuration … | ||
Set | MqContextC - various function to 'set' the configuration-data in a context … | ||
MqContextC ENV API | MqContextC - protect and restore the service-environment … | ||
MqContextC ERROR API | MqContextC - move and copy an error from a context … | ||
MqContextC HIGH API | MqContextC - User friendly replacement for the MqContextC_SendApi_C_API and the MqContextC_ReadApi_C_API … | ||
MqContextC LINK API | MqContextC - setup and manage a client-server-link … | ||
MqContextC LOG API | MqContextC - log the output to a string or a MkLogFileC … | ||
MqContextC MISC API | MqContextC - various functions to work on a context … | ||
MqContextC PROXY API | MqContextC - copy data from the read-data-package of the sourceCtx to the send-data-package of the targetCtx | ||
MqContextC READ API | |||
Atom | MqContextC - read a single-data-item outof a read-data-package … | ||
Block | MqContextC - read a block-of-data outof a read-data-package … | ||
Misc | MqContextC - various functions to work on a read-data-package … | ||
MqContextC ROUTE API | MqContextC - setup and manage a routing-link … | ||
MqContextC SEND API | |||
Atom | MqContextC - append a native PRIMITIVE TYPE value to the send-data-package … | ||
Basics | MqContextC - finish the send-data-block and call synchronous/asynchronous a remote-service … | ||
Block | MqContextC - a wrapper to send a list-block or a transaction-block … | ||
Return | MqContextC - finish the send-data-block on the server and optional return the results. … | ||
MqContextC SERVICE API | MqContextC - create and manage a service … | ||
MqContextC SLAVE API | MqContextC - create and manage a slave context … | ||
MqContextC STORAGE API | MqContextC - setup and manage a storage used to persist data-packages … |
C-API: MqContextC_C_API - MqContextC - the class known as ctx or context is the application-handle of the application-server and also the main data-handle …
The context is the package-item with the required features and created by the implementation-layer-programmer. The context can be a client or a server.
The client-context-creation is triggerd by the software-workflow on demand. The client is calling the MqLinkCreate to create a connection to the server using the connection-arguments to specify the target.
The life-cycle of a client is:
ContextCreate | create and initialize the MqContextC ... |
LinkCreate | make ctx to a parent-context and setup a new client-server-link … |
SendTT | MqContextC - append a native PRIMITIVE TYPE value to the send-data-package … |
ReadTT | read a PRIMITIVE TYPE from the read-data-package … |
LinkDelete | close the client-server-link … |
ContextDelete | Destructor - delete a MqContextC instance … |
Exit | delete the context and exit the current process or thread … |
The server-context-creation is always triggerd by the MqLinkCreate command of the client. The server is usually using a factory-constructor to call the MqContextCreate and finally to call the MqContextDelete.
The server-context is fully under control of the client.
The life-cycle of a server is:
SETUP | define a class and add the setup/cleanup code |
IServerSetup | define the server-setup-interface (callback) used on startup … |
ServiceCreate | create a link between a service-token and a service-callback … |
IServerCleanup | define the server-cleanup-interface (callback) used on cleanup … |
ServiceDelete | delete a service. … |
STARTUP | define the factory and start the listener |
FactoryAdd | add a new MqFactoryC identified by factory-identifier and defined by factory-constructor … |
FactoryNew | create a new MqContextC from a MqFactoryC … |
LinkCreate | make ctx to a parent-context and setup a new client-server-link … |
ProcessEvent | enter the event-loop and wait for an incoming service-request. … |
WORK | process the service-calls and exit on end |
ReadTT | read a PRIMITIVE TYPE from the read-data-package … |
SendTT | MqContextC - append a native PRIMITIVE TYPE value to the send-data-package … |
Exit | delete the context and exit the current process or thread … |
command | alias |
---|---|
(constructor,static,runtime) MQ_CTX MqContextCreate(MQ_CTX const tmpl) | no |
(destructor,runtime) void MqContextDelete(MQ_CTX ctx) | no |
Ctx | cast a unknown-object into an MqContextS pointer or NULL if not possible | ||
CtxCheck | check MqContextS -> MkObjectS::signature … | ||
CtxCheckO | check MqContextS -> MkObjectS::signature … | ||
CtxN | (const) cast a unknown-object into an MqContextS pointer or NULL if not possible |
HandleResolve | Handle-Resolve-Slot - return a MqContextC from netHdl or MK_NULL if invalid… | ||
HandleGet | Handle-Get-Slot - returns a export-hdl to the MqContextC useable for external storage |
MqContextC CLASS INTROSPECTION
Instances | get head-instance from linked-list of MqContextS type … | ||
Next | get next instance from linked-list of MqContextS type | ||
Prev | get previous instance from linked-list of MqContextS type |
GetNull | Null-Slot - return a MqContextC typed |
C-API: MqContextC_Class_C_API - MqContextC - define the class …
C-API: MqContextC_Class_Define_C_API - MqContextC - low level definition, access and cast …
(static,hide) MQ_CTX MqCtx(MK_MNG mng)
top cast a unknown-object into an MqContextS pointer or NULL if not possible → API: MqCtx
(static,hide) MK_BOOL MqCtxCheck(MK_MNGN mng)
top check MqContextS -> MkObjectS::signature … → API: MqCtxCheck
(static,hide) MK_BOOL MqCtxCheckO(MK_OBJN obj)
top check MqContextS -> MkObjectS::signature … → API: MqCtxCheckO
(static,hide) MQ_CTXN MqCtxN(MK_MNGN mng)
top (const) cast a unknown-object into an MqContextS pointer or NULL if not possible → API: MqCtxN
MqContextC - Export class functions …
(static,runtime) MQ_CTX MqContextHandleResolve(MK_HDL const netHdl)
top Handle-Resolve-Slot - return a MqContextC from netHdl or MK_NULL
if invalid… → API: MqContextHandleResolve_RT
The MqContextHandleResolve undo the MqContextHandleGet and is intended to export a unique identifer into external code not belonging to the Programming-Language-Micro-Kernel (PLMK).
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | netHdl | handle former exported with MqContextHandleGet |
MK_NULL
if netHdl is invalid (runtime) MK_HDL MqContextHandleGet(MQ_CTX const ctx)
top Handle-Get-Slot - returns a export-hdl to the MqContextC useable for external storage → API: MqContextHandleGet_RT
The export-hdl is a reference to an instance that can be stored in software and converted back into an instance using the MqContextHandleResolve.
The export-hdl is only valid until the Programming-Language-Micro-Kernel (PLMK) ends.
example: The export-hdl is used in rpc to identify an object across the network.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
MqContextC - Introspection class functions …
(static,runtime) MQ_CTX MqContextInstances()
top get head-instance from linked-list of MqContextS type … → API: MqContextInstances_RT
The head-instance is the last instance created.
MQ_CTX MqContextNext(MQ_CTX const ctx)
top get next instance from linked-list of MqContextS type → API: MqContextNext
MQ_CTX MqContextPrev(MQ_CTX const ctx)
top get previous instance from linked-list of MqContextS type → API: MqContextPrev
MqContextC - Misc class functions …
(static) MQ_CTX MqContextGetNull()
top Null-Slot - return a MqContextC typed NULL
instance … → API: MqContextGetNull
C-API: MqContextC_TOR_C_API - MqContextC - various functions to create, initialize and destroy a context …
(constructor,static,runtime) MQ_CTX MqContextCreate(MQ_CTX const tmpl)
top create and initialize the MqContextC ... → API: MqContextCreate_RT
This function is used to create a single new context… primary on the client. to create multiple new context on a server… a MqFactoryC is used.
The new instance belongs to the caller and may have to be released if necessary. A manual release using ContextDelete is always possible, but the instance can no longer be used afterwards.
Example from MyClient.c
→ create a context using the static libmqmsgque CTOR
#include "debug_mq.h" #include "msgque_mq.h" int main (int argc, MK_STRN argv[]) { MkRtSetup_NULL; struct MkBufferListS * largv = MkBufferListCreateVC(argc, argv); // create a context using the static libmqmsgque CTOR function "MqContextCreate" MQ_CTX ctx = MqContextCreate(NULL,NULL); MqConfigSetName(ctx, "MyClient"); MqLinkCreate_E (ctx, largv); MqCheckForLeftOverArguments_E (ctx, largv); MqSend_E (ctx, "W", "HLWO:C", "Hello"); fprintf(stdout,"%s\n", MqReadSTR_e (ctx)); fflush(stdout); error: MkBufferListDelete(largv); // delete the context using the libmqmsgque APPLICATION-DTOR function "MqExit_1" MqExit_1(ctx); }
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | type | type type of the object like MqContextC_T or a new type created with MkTypeDup2. (default: MK_NULL , reuse the MkTypeSTT from tmpl or use MqContextC_T if tmpl = MK_NULL ) |
[in] | tmpl | an other context-data-structure used as template to initialize the configuration data. This template is used for a child to get the configuration data from the parent. (default: MK_NULL , create an initial context) |
(destructor,runtime) void MqContextDelete(MQ_CTX ctx)
top Destructor - delete a MqContextC instance … → API: MqContextDelete_RT
Shutdown the client-server-link, free the memory and set the ctx to MK_NULL
. The context can not be reused.
Example from MyClient2.c
→ delete a application-context using the libmqmsgque DTOR
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
ClassFactoryGet | get the MqFactoryC used by the MqContextC | ||
ClassFactorySet | link the MqContextC to a new MqFactoryC | ||
ClassIdentGet | get the application-identification … | ||
ClassIdentSet | link the MqContextC to a new MqFactoryC identified by ident | ||
ClassOriginalIdentGet | get the MqFactoryS::originalIdent from the MqContextC |
C-API: MqContextC_ClassApi_C_API - MqContextC - access data related to the factory-type of the object …
The type of an object is related to the MqFactoryC. The factory decide which class a new created object has. The factory has two identifiers:
The relevance of the MqContextC CLASS API based type system, provided by MqFactoryC, decreased with the rise of the MANAGED OBJECT technology.
The MqContextC CLASS API based type system has more influence for target-languages without reflection, like C or C++.
The factory is something like a constructor but only support the application-context MqContextC .
The MqContextC ROUTE API using the MqClassIdentGet from MqFactoryC to identify an application from remote.
MQ_FCT MqClassFactoryGet(MQ_CTXN const ctx)
top get the MqFactoryC used by the MqContextC → API: MqClassFactoryGet
[in] | ctx | the MqContextC to extract the MqFactoryC from |
(runtime) enum MkErrorE MqClassFactorySet(MQ_CTX const ctx, MQ_FCT const item)
top link the MqContextC to a new MqFactoryC → API: MqClassFactorySet_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextC to be linked with the MqFactoryC |
[in] | item | the MqFactoryC to link with |
MK_STRN MqClassIdentGet(MQ_CTXN const ctx)
top get the application-identification … → API: MqClassIdentGet
[in] | ctx | the MqContextC to extract the ident from |
An application has TWO possible names:
The --ident-from prefix|factory value decide which on is used.
The application-identification is defined by MqConfigS::identFrom :
MqFactoryS::originalIdent | if ident == MQ_IDENT_FACTORY |
MqConfigS::prefix | if ident == MQ_IDENT_PREFIX (default) |
The MqFactoryS::originalIdent is the official name of the MqFactoryC and is defined by the application-programmer with MqFactoryAdd or MqFactoryDup2.
The MqConfigS::prefix is the official name of the MqContextC that startet first, usually the server-name, and is set by the application-user with --prefix string at startup or with the MqConfigSetPrefix at setup.
When the server starts, the MqClassIdentGet value is send from the server to the client and the client initializes the MqLinkS::targetIdent with this value. This value identifes the server from remote and is used by the MqContextC ROUTE API to select which server receive the routing-package.
The client usually get the factory and the idenfication from the: MqFactoryInitial.
Example: Change the factory-identifier of MqFactoryInitial to the value "TestClient" with:
C# | MqFactoryC.Get("initial").Dup2("TestClient").Initial() |
TCL | [[tclmsgque::MqFactoryC Get "initial"] Dup2 "TestClient"] Initial |
(runtime) enum MkErrorE MqClassIdentSet(MQ_CTX const ctx, MK_STRN ident)
top link the MqContextC to a new MqFactoryC identified by ident → API: MqClassIdentSet_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextC to set the ident |
[in] | ident | the MqFactoryS::originalIdent to link with |
MK_STRN MqClassOriginalIdentGet(MQ_CTXN const ctx)
top get the MqFactoryS::originalIdent from the MqContextC → API: MqClassOriginalIdentGet
[in] | ctx | the MqContextC to extract the original-ident from |
ConfigGetBuffersize | get the minimum of the read/send buffersize of the socket | ||
ConfigGetIdentFrom | get the MqConfigS::identFrom | ||
ConfigGetIoPipe | return the MqIoPipeConfigS | ||
ConfigGetIoTcp | get the configuration-data of the tcp-client-server-link … | ||
ConfigGetIoTcpL | get the configuration-data of the tcp-client-server-link as MkBufferListC … | ||
ConfigGetIoUds | return the MqIoUdsConfigS | ||
ConfigGetIsParent | does the context object is a parent ? An objext is a parent id the MqConfigS::parent attribute is MK_NULL | ||
ConfigGetIsServer | does the context object is a server ? | ||
ConfigGetIsString | does the context object is using the string-mode ? | ||
ConfigGetName | get the name of the context object | ||
ConfigGetPkgsize | get the maximun size of a BDY package | ||
ConfigGetPostfix | get the MqConfigS::postfix | ||
ConfigGetPrefix | get the MqConfigS::prefix | ||
ConfigGetStartAs | return the MqConfigS::startAs value | ||
ConfigGetStatusIs | return the MqContextS::statusIs value | ||
ConfigGetStorage | get the storage of the context object | ||
ConfigGetTimeout | get the timeout value of the context object | ||
ConfigSetConfigFile | set the config-file and parse for well-known config-items |
MqContextC CONFIG API INTERFACE
ConfigSetBgError | set the MqSetupS::BgError | ||
ConfigSetEvent | set the MqSetupS::Event | ||
ConfigSetServerCleanup | set the MqSetupS::ServerCleanup | ||
ConfigSetServerSetup | set the MqSetupS::ServerSetup |
ConfigReset | clean the MqContextS::config data | ||
SetupDup | copy the MqContextS::setup data … |
ConfigCheckStartAs | check if MqConfigS::startAs can be set to data | ||
ConfigSetAllDebug | set the MkRuntimeS::debug value | ||
ConfigSetBuffersize | set the MqIoConfigS::buffersize value | ||
ConfigSetDaemon | start the server-context as daemon … | ||
ConfigSetIdentFrom | set the MqConfigS::identFrom value | ||
ConfigSetIgnoreExit | set the MqSetupS::ignoreExit value | ||
ConfigSetIoPipe | set the pipe configuration data … | ||
ConfigSetIoTcp | configure a context to use a tcp-client-server-link … | ||
ConfigSetIoTcpL | configure a context to use a tcp-client-server-link … | ||
ConfigSetIoUds | configure a context to use a uds-client-server-link … | ||
ConfigSetIsServer | set the MqSetupS::isServer value | ||
ConfigSetIsString | set the MqConfigS::native value 'S'string or 'L'owEndian or 'B'igEndian | ||
ConfigSetName | set the MqConfigS::dispname value and cleanup old value | ||
ConfigSetPkgsize | set the MqIoConfigS::pkgsize value | ||
ConfigSetPostfix | set the client-part (2) of the application-identifer MqConfigS::dispname … | ||
ConfigSetPrefix | set the server-part (1) of the application-identifer MqConfigS::dispname … | ||
ConfigSetStartAs | set the MqConfigS::startAs value | ||
ConfigSetStartAsString | set the MqConfigS::startAs value using string default , thread , fork or spawn | ||
ConfigSetStorage | set the Storage value and cleanup old value | ||
ConfigSetTimeout | set the MqIoConfigS::timeout value |
C-API: MqContextC_ConfigApi_C_API - MqContextC - various functions to config a context …
The configuration is done persistent using config-api functions or on link-setup using command-line-arguments.
set: (runtime) enum MkErrorE MqConfigSetConfigFile(MQ_CTX const ctx, MK_STRN const filename)
add libconfig configuration file …
A config-file is used to add configuration-values to a libmqmsgque-application using a structured text-file.
A service-callback and "programming" is not supported. To "programm and modify" something use a scripting language like tcl or python.
libconfig is used to parse a config-file using the application … --config fileName …
option.
The following restrictions apply to the --config
option.
--config
option is parsed groupname : { ... }
( ":" or "=" is allowed ) MyClient … --XXX … --config YYY … --ZZZ …
MyClient
: XXX < YYY < ZZZ MyClient --AAA … --config BBB --CCC … @ Filter3 --name otto --DDD … @ MyServer --EEE …
application | groupname | option-parsing-order |
---|---|---|
MyClient | MyClient | AAA < BBB < CCC |
Filter3 | otto | DDD < BBB |
MyServer | MyServer | EEE < BBB |
--name
or --prefix
option from DDD
or EEE
change the group read from the config-file --config
option--config
option overwrite the options from the config-file groupname : { … filter : [ … ] }
) config-file-option define the server to start in a pipe and have to be an array of strings starting with the application-executable OR the factory-identifer 1. Example from MyClient.config
→ filter-pipeline with last server start in debug mode
2. Example from libconfig.test
→ filter-pipeline with last server connect by tcp/ip
attribute: MqConfigS::dispname, getter: MqConfigGetName, setter: MqConfigSetName
set the display-name of the context …
The display-name is used as:
C> (dispname) [2009-01-12:16-22-27] [4-0-sIoCheckArg]: option: io->com = PIPE
The dispname is initialized with:
(runtime) void MqConfigSetName(MQ_CTX const ctx, MK_STRN data)
, (runtime) void MqConfigSetPrefix(MQ_CTX const ctx, MK_STRN data)
, (runtime) void MqConfigSetPostfix(MQ_CTX const ctx, MK_STRN data)
function prefix | postfix | dispname |
---|---|---|
client | -1-1 | client-1-1 |
(runtime) void MqConfigSetName(MQ_CTX const ctx, MK_STRN data)
or --name stringattribute: MqConfigS::prefix, getter: MqConfigGetPrefix, setter: MqConfigSetPrefix
set the server-part (1) of the application-identifer MqConfigS::dispname …
The prefix is used for:
The prefix is initialize with:
(runtime) void MqConfigSetPrefix(MQ_CTX const ctx, MK_STRN data)
or the (runtime) void MqConfigSetName(MQ_CTX const ctx, MK_STRN data)
functionattribute: MqConfigS::postfix, getter: MqConfigGetPostfix, setter: MqConfigSetPostfix
set the client-part (2) of the application-identifer MqConfigS::dispname …
The postfix is used for:
The postfix is initialize with:
(runtime) void MqConfigSetPostfix(MQ_CTX const ctx, MK_STRN data)
functionattribute: MqConfigS::storage, getter: MqConfigGetStorage, setter: MqConfigSetStorage
attribute: MqConfigS::identFrom, getter: MqConfigGetIdentFrom, setter: MqConfigSetIdentFrom
select how to identify the application from remote …
An application has TWO possible names:
The --ident-from prefix|factory value decide which on is used.
The application-identification is defined by MqConfigS::identFrom :
MqFactoryS::originalIdent | if ident == MQ_IDENT_FACTORY |
MqConfigS::prefix | if ident == MQ_IDENT_PREFIX (default) |
The MqFactoryS::originalIdent is the official name of the MqFactoryC and is defined by the application-programmer with MqFactoryAdd or MqFactoryDup2.
The MqConfigS::prefix is the official name of the MqContextC that startet first, usually the server-name, and is set by the application-user with --prefix string at startup or with the MqConfigSetPrefix at setup.
When the server starts, the MqClassIdentGet value is send from the server to the client and the client initializes the MqLinkS::targetIdent with this value. This value identifes the server from remote and is used by the MqContextC ROUTE API to select which server receive the routing-package.
The client usually get the factory and the idenfication from the: MqFactoryInitial.
Example: Change the factory-identifier of MqFactoryInitial to the value "TestClient" with:
C# | MqFactoryC.Get("initial").Dup2("TestClient").Initial() |
TCL | [[tclmsgque::MqFactoryC Get "initial"] Dup2 "TestClient"] Initial |
attribute: MqIoTcpConfigS, getter: MqConfigGetIoTcp, setter: MqConfigSetIoTcp
configure a context to use a tcp-client-server-link …
[in] | host | client: name of the remote interface (default: localhost) server: name of the local interface (default: listen on all interfaces) |
[in] | port | client: name of the remote port server: name of the local port |
[in] | myhost | client: name of the local interface |
[in] | myport | client: name of the local port |
attribute: MqIoUdsConfigS, getter: MqConfigGetIoUds, setter: MqConfigSetIoUds
configure a context to use a uds-client-server-link …
The uds-socket (http://en.wikipedia.org/wiki/Unix_domain_socket) is usually 50% faster than a local tcp communication but only available on UNIX.
[in] | file | name of a uds-socket-file (default: MK_NULL ) |
attribute: MqIoPipeConfigS, getter: MqConfigGetIoPipe, setter: MqConfigSetIoPipe
configure a context to use a pipe-client-server-link …
The socket option is special because it is used only for internal purpose to submit the socket from the client to the server started as pipe by the client.
[in] | hdl | the file-descriptor-number (default: not set) |
attribute: MqConfigS::startAs, getter: MqConfigGetStartAs, setter: MqConfigSetStartAs
create a new application-context as thread, spawn or fork …
A new application-context is created if:
The allowed integer values for MqConfigS::startAs are:
(default: do not create a new application-context)
set: (runtime) enum MkErrorE MqConfigSetDaemon(MQ_CTX const ctx, MK_STRN pidfile)
This option is not available for libmqmsgque.
attribute: MkRuntimeS::logfile, getter: RMkRuntimeGetLogfile, setter: RMkRuntimeSetLogfile
attribute: MkRuntimeS::isSilent, getter: RMkRuntimeGetIsSilent, setter: RMkRuntimeSetIsSilent
attribute: MkRuntimeS::debug, getter: RMkRuntimeGetDebug, setter: RMkRuntimeSetDebug
attribute: MqIoConfigS::buffersize, getter: MqConfigGetBuffersize, setter: MqConfigSetBuffersize
set the OS specific value for the socket-operation-buffer (default: OS specific)
attribute: MqIoConfigS::pkgsize, getter: MqConfigGetPkgsize, setter: MqConfigSetPkgsize
set maximum package size (default: 10 KiB)
attribute: MqIoConfigS::timeout, getter: MqConfigGetTimeout, setter: MqConfigSetTimeout
user defined timeout to terminate a blocking function call (default: 90 sec)
attribute: MqConfigS::native, getter: MqConfigGetIsString, setter: MqConfigSetIsString
define if data is string or little or big endian …
define the server-setup-interface (callback) used on startup …
This interface is used to configure a new server-context-link, like a constructor, and is called at the end of MqLinkCreate or MqLinkCreateChild. This interface is called for every new incoming connection request and is used to define context specific services using MqServiceCreate or to initialize context-specific variables. As side-effect this interface set MqSetupS::isServer to MK_YES
.
IServerSetup
: callback signatureRead more about how to define a service-callback in theLink .
define the server-cleanup-interface (callback) used on cleanup …
This interface is used to cleanup an old server-context-link, like a destructor, and is called at the beginning of MqLinkDelete to free context-specific variables. As side-effect this interface set MqSetupS::isServer to MK_YES
.
IServerCleanup
: callback signatureRead more about how to define a service-callback in theLink .
define the background-error-interface …
A background error is an error without a link to an application-context and happen if an MqSendEND call fails or if an other asynchronous task fails. if the interface is not defined the error is printed to stderr and the application continue to work. if the interface is defined the context is set to error and the callback is called to process this error. Inside the callback the error is available using ErrorGetNum and ErrorGetText and can be cleared using ErrorReset.
IBgError
: callback signatureRead more about how to define a service-callback in theLink .
Create a link to the calling tool event-handling queue …
Event-Handling is used to process tasks in the background to give the tool-user the feeling of a non-blocking application. For example Tcl using the event-handling to update the Tk user-interface while the application is waiting for data. The event handling function is called on idle-time and is designed for a very short function execution time. Do only one action per function call. This function will be called with a ~10000 usec interval to guarantee a parallel like execution.
example/LANG/Filter4.EXT
IEvent
: callback signatureRead more about how to define a service-callback in theLink .
C-API: MqContextC_ConfigApi_Get_C_API - MqContextC - various function to 'get' the configuration-data from a context …
MK_I32 MqConfigGetBuffersize(MQ_CTXN const ctx)
top get the minimum of the read/send buffersize of the socket → API: MqConfigGetBuffersize
[in] | ctx | the MqContextS instance to work on |
context.config.buffersize
(R/S) value enum MqIdentE MqConfigGetIdentFrom(MQ_CTX const ctx)
top get the MqConfigS::identFrom → API: MqConfigGetIdentFrom
[in] | ctx | the MqContextS instance to work on |
prefix
or factory MQ_SOCK_HDL MqConfigGetIoPipe(MQ_CTX const ctx)
top return the MqIoPipeConfigS → API: MqConfigGetIoPipe
[in] | ctx | the MqContextS instance to work on |
enum MkErrorE MqConfigGetIoTcp(MQ_CTX const ctx, MK_STRN *host_out, MK_STRN *port_out, MK_STRN *myhost_out, MK_STRN *myport_out)
top get the configuration-data of the tcp-client-server-link … → API: MqConfigGetIoTcp
[in] | ctx | the MqContextS instance to work on |
[out] | host_out | client: name of the remote interface (default: localhost) server: name of the local interface (default: listen on all interfaces) |
[out] | port_out | client: name of the remote port server: name of the local port |
[out] | myhost_out | client: name of the local interface |
[out] | myport_out | client: name of the local port |
MK_NULL
MK_NULL
… nothing will be done enum MkErrorE MqConfigGetIoTcpL(MQ_CTX const ctx, MK_BFL *vals_out)
top get the configuration-data of the tcp-client-server-link as MkBufferListC … → API: MqConfigGetIoTcpL
host |
| ||||
port |
| ||||
myhost | name of the local interface | ||||
myport | name of the local port |
[in] | ctx | the MqContextS instance to work on |
[out] | vals_out | the contain host, port, myhost and myport data |
MK_STRN MqConfigGetIoUds(MQ_CTXN const ctx)
top return the MqIoUdsConfigS → API: MqConfigGetIoUds
[in] | ctx | the MqContextS instance to work on |
context.config.io.uds.file
value MK_BOOL MqConfigGetIsParent(MQ_CTX const ctx)
top does the context object is a parent ? An objext is a parent id the MqConfigS::parent attribute is MK_NULL
→ API: MqConfigGetIsParent
[in] | ctx | the MqContextS instance to work on |
(ctx->config.parent == NULL)
value MK_BOOL MqConfigGetIsServer(MQ_CTX const ctx)
top does the context object is a server ? → API: MqConfigGetIsServer
[in] | ctx | the MqContextS instance to work on |
(ctx->setup.isServer == true)
value MK_BOOL MqConfigGetIsString(MQ_CTX const ctx)
top does the context object is using the string-mode ? → API: MqConfigGetIsString
[in] | ctx | the MqContextS instance to work on |
(ctx->config.native == 'S')
value MK_STRN MqConfigGetName(MQ_CTXN const ctx)
top get the name of the context object → API: MqConfigGetName
[in] | ctx | the MqContextS instance to work on |
context.config.name
value MK_I32 MqConfigGetPkgsize(MQ_CTXN const ctx)
top get the maximun size of a BDY package → API: MqConfigGetPkgsize
[in] | ctx | the MqContextS instance to work on |
context.config.pkgsize
(R/S) value MK_STRN MqConfigGetPostfix(MQ_CTXN const ctx)
top get the MqConfigS::postfix → API: MqConfigGetPostfix
[in] | ctx | the MqContextS instance to work on |
MK_STRN MqConfigGetPrefix(MQ_CTXN const ctx)
top get the MqConfigS::prefix → API: MqConfigGetPrefix
[in] | ctx | the MqContextS instance to work on |
enum MqStartE MqConfigGetStartAs(MQ_CTX const ctx)
top return the MqConfigS::startAs value → API: MqConfigGetStartAs
enum MqStatusIsEF MqConfigGetStatusIs(MQ_CTX const ctx)
top return the MqContextS::statusIs value → API: MqConfigGetStatusIs
MK_STRN MqConfigGetStorage(MQ_CTXN const ctx)
top get the storage of the context object → API: MqConfigGetStorage
[in] | ctx | the MqContextS instance to work on |
context.config.storage
value MK_TIME_T MqConfigGetTimeout(MQ_CTXN const ctx)
top get the timeout value of the context object → API: MqConfigGetTimeout
[in] | ctx | the MqContextS instance to work on |
context.config.timeout
value (runtime) enum MkErrorE MqConfigSetConfigFile(MQ_CTX const ctx, MK_STRN const filename)
top set the config-file and parse for well-known config-items → API: MqConfigSetConfigFile_RT
Read more at MqConfigS::cfg
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | filename | name of the config-file for input |
C-API: MqContextC_ConfigApi_Interface_C_API - MqContextC - various function to setup a interface for the context …
The "Setup"-Callback is special because this callback have to be callable by the server child and/or the slave context.
To distinguish the server child and slave the following functions are used:
"if"
clause and the child/parent check"if"
clause and the master/slave check
"if"
clause and the server/child check(runtime) void MqConfigSetBgError(MQ_CTX const ctx, MqServiceCallbackF fCall, MK_CBP callback)
top set the MqSetupS::BgError → API: MqConfigSetBgError_RT
define the background-error-interface …
A background error is an error without a link to an application-context and happen if an MqSendEND call fails or if an other asynchronous task fails. if the interface is not defined the error is printed to stderr and the application continue to work. if the interface is defined the context is set to error and the callback is called to process this error. Inside the callback the error is available using ErrorGetNum and ErrorGetText and can be cleared using ErrorReset.
IBgError
: callback signatureThis function register a callback and is used to configure the application for a specific task.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fCall | function called with callback as argument to work on an specific task. |
[in] | callback | argument for fCall, for a target-language this is the target-language-callback-hdl. |
[in] | fFree | cleanup the callback, called at the destruction of ctx. |
[in] | fCopy | copy-constructor of the callback, used if the ctx is used to initialize an other newctx. |
(runtime) void MqConfigSetEvent(MQ_CTX const ctx, MqServiceCallbackF fCall, MK_CBP callback)
top set the MqSetupS::Event → API: MqConfigSetEvent_RT
Create a link to the calling tool event-handling queue …
Event-Handling is used to process tasks in the background to give the tool-user the feeling of a non-blocking application. For example Tcl using the event-handling to update the Tk user-interface while the application is waiting for data. The event handling function is called on idle-time and is designed for a very short function execution time. Do only one action per function call. This function will be called with a ~10000 usec interval to guarantee a parallel like execution.
example/LANG/Filter4.EXT
IEvent
: callback signatureThis function register a callback and is used to configure the application for a specific task.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fCall | function called with callback as argument to work on an specific task. |
[in] | callback | argument for fCall, for a target-language this is the target-language-callback-hdl. |
[in] | fFree | cleanup the callback, called at the destruction of ctx. |
[in] | fCopy | copy-constructor of the callback, used if the ctx is used to initialize an other newctx. |
(runtime) void MqConfigSetServerCleanup(MQ_CTX const ctx, MqServiceCallbackF fCall, MK_CBP callback)
top set the MqSetupS::ServerCleanup → API: MqConfigSetServerCleanup_RT
define the server-cleanup-interface (callback) used on cleanup …
This interface is used to cleanup an old server-context-link, like a destructor, and is called at the beginning of MqLinkDelete to free context-specific variables. As side-effect this interface set MqSetupS::isServer to MK_YES
.
IServerCleanup
: callback signatureThis function register a callback and is used to configure the application for a specific task.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fCall | function called with callback as argument to work on an specific task. |
[in] | callback | argument for fCall, for a target-language this is the target-language-callback-hdl. |
[in] | fFree | cleanup the callback, called at the destruction of ctx. |
[in] | fCopy | copy-constructor of the callback, used if the ctx is used to initialize an other newctx. |
(runtime) void MqConfigSetServerSetup(MQ_CTX const ctx, MqServiceCallbackF fCall, MK_CBP callback)
top set the MqSetupS::ServerSetup → API: MqConfigSetServerSetup_RT
define the server-cleanup-interface (callback) used on cleanup …
This interface is used to cleanup an old server-context-link, like a destructor, and is called at the beginning of MqLinkDelete to free context-specific variables. As side-effect this interface set MqSetupS::isServer to MK_YES
.
IServerCleanup
: callback signatureThis function register a callback and is used to configure the application for a specific task.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fCall | function called with callback as argument to work on an specific task. |
[in] | callback | argument for fCall, for a target-language this is the target-language-callback-hdl. |
[in] | fFree | cleanup the callback, called at the destruction of ctx. |
[in] | fCopy | copy-constructor of the callback, used if the ctx is used to initialize an other newctx. |
C-API: MqContextC_ConfigApi_Misc_C_API - MqContextC - various function to do 'misc' configuration …
(runtime) void MqConfigReset(MQ_CTX const ctx)
top clean the MqContextS::config data → API: MqConfigReset_RT
(runtime,hide) void MqSetupDup(MQ_CTX const to, MQ_CTXN const from)
top copy the MqContextS::setup data … → API: MqSetupDup_RT
MqSetupDup is an important function, because every new created object need to fill the MqSetupS data. The typical software flow is:
MqSetupDup has code to protect setup data filled in Object-Specific-Setup
C-API: MqContextC_ConfigApi_Set_C_API - MqContextC - various function to 'set' the configuration-data in a context …
MK_BOOL MqConfigCheckStartAs(MQ_CTX const ctx, enum MqStartE data)
top check if MqConfigS::startAs can be set to data → API: MqConfigCheckStartAs
(runtime) enum MkErrorE MqConfigSetAllDebug(MQ_CTX const ctx, MK_I32 const data)
top set the MkRuntimeS::debug value → API: MqConfigSetAllDebug_RT
set all childs and all slaves and the link target parter… too
void MqConfigSetBuffersize(MQ_CTX const ctx, MK_I32 data)
top set the MqIoConfigS::buffersize value → API: MqConfigSetBuffersize
(runtime) enum MkErrorE MqConfigSetDaemon(MQ_CTX const ctx, MK_STRN pidfile)
top start the server-context as daemon … → API: MqConfigSetDaemon_RT
A daemon is a server-process without any link to the parent-process. A daemon-process has closed all default IO (e.g stdout, stdin, stderr) and forked into the background. (default: no daemon)
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | pidfile | write the PID of the daemon into this file (default: NULL, do not start as daemon) |
void MqConfigSetIdentFrom(MQ_CTX const ctx, enum MqIdentE data)
top set the MqConfigS::identFrom value → API: MqConfigSetIdentFrom
void MqConfigSetIgnoreExit(MQ_CTX const ctx, MK_BOOL data)
top set the MqSetupS::ignoreExit value → API: MqConfigSetIgnoreExit
(runtime) enum MkErrorE MqConfigSetIoPipe(MQ_CTX const ctx, MQ_SOCK_HDL fh)
top set the pipe configuration data … → API: MqConfigSetIoPipe_RT
This is configuration option is only useful for a (x)inetd setup to use the stdin (socket=0) as send/recv communication socket
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fh | the name of the known socket |
(runtime) enum MkErrorE MqConfigSetIoTcp(MQ_CTX const ctx, MK_STRN host, MK_STRN port, MK_STRN myhost, MK_STRN myport)
top configure a context to use a tcp-client-server-link … → API: MqConfigSetIoTcp_RT
[in] | host | client: name of the remote interface (default: localhost) server: name of the local interface (default: listen on all interfaces) |
[in] | port | client: name of the remote port server: name of the local port |
[in] | myhost | client: name of the local interface |
[in] | myport | client: name of the local port |
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqConfigSetIoTcpL(MQ_CTX const ctx, MK_BFL const vals)
top configure a context to use a tcp-client-server-link … → API: MqConfigSetIoTcpL_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | vals | a list with host, port, myhost, myport |
(runtime) enum MkErrorE MqConfigSetIoUds(MQ_CTX const ctx, MK_STRN file)
top configure a context to use a uds-client-server-link … → API: MqConfigSetIoUds_RT
The uds-socket (http://en.wikipedia.org/wiki/Unix_domain_socket) is usually 50% faster than a local tcp communication but only available on UNIX.
[in] | file | name of a uds-socket-file (default: MK_NULL ) |
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
void MqConfigSetIsServer(MQ_CTX const ctx, MK_BOOL data)
top set the MqSetupS::isServer value → API: MqConfigSetIsServer
void MqConfigSetIsString(MQ_CTX const ctx, MK_BOOL data)
top set the MqConfigS::native value 'S'string or 'L'owEndian or 'B'igEndian → API: MqConfigSetIsString
(runtime) void MqConfigSetName(MQ_CTX const ctx, MK_STRN data)
top set the MqConfigS::dispname value and cleanup old value → API: MqConfigSetName_RT
void MqConfigSetPkgsize(MQ_CTX const ctx, MK_I32 data)
top set the MqIoConfigS::pkgsize value → API: MqConfigSetPkgsize
(runtime) void MqConfigSetPostfix(MQ_CTX const ctx, MK_STRN data)
top set the client-part (2) of the application-identifer MqConfigS::dispname … → API: MqConfigSetPostfix_RT
The postfix is used for:
The postfix is initialize with:
(runtime) void MqConfigSetPostfix(MQ_CTX const ctx, MK_STRN data)
function(runtime) void MqConfigSetPrefix(MQ_CTX const ctx, MK_STRN data)
top set the server-part (1) of the application-identifer MqConfigS::dispname … → API: MqConfigSetPrefix_RT
The prefix is used for:
The prefix is initialize with:
(runtime) void MqConfigSetPrefix(MQ_CTX const ctx, MK_STRN data)
or the (runtime) void MqConfigSetName(MQ_CTX const ctx, MK_STRN data)
function enum MkErrorE MqConfigSetStartAs(MQ_CTX const ctx, enum MqStartE data)
top set the MqConfigS::startAs value → API: MqConfigSetStartAs
enum MkErrorE MqConfigSetStartAsString(MQ_CTX const ctx, MK_STRN data)
top set the MqConfigS::startAs value using string default
, thread
, fork
or spawn
→ API: MqConfigSetStartAsString
(runtime) void MqConfigSetStorage(MQ_CTX const ctx, MK_STRN data)
top set the Storage value and cleanup old value → API: MqConfigSetStorage_RT
void MqConfigSetTimeout(MQ_CTX const ctx, MK_TIME_T data)
top set the MqIoConfigS::timeout value → API: MqConfigSetTimeout
EnvProtect | protect the service-environment | ||
EnvRestore | restore the service-environment |
C-API: MqContextC_EnvApi_C_API - MqContextC - protect and restore the service-environment …
The "Env" style functions are used to secure the service-environment (defined in MqEnvS)
and is required.. under special conditions... to proper answer the original service call at the
end of the service-processing.
By default libmqmsgque guarantee the proper management of the environment on behalf of the user.
Under normal conditions the user don't need these functions.
The folllowing design-goals were defined:
come-in == come-out
The two design-goals from above are in conflict and the both functions MqEnvProtect and MqEnvRestore are used to solve this conflict.
Example from server.c
→ protect the environment and import from database
// in a service call // PROTECT the original service-call MqEnvProtect(mqctx); // OVERWRITE the original service-call with data from the database MqDumpImport(dump,mqctx); // ... do some work ... MK_BFL ret = MqReadALL_e(mqctx); // RESTORE the original service-call MqEnvRestore(mqctx); // ANSWER the original service-call MqSend_E(mqctx, "R", "L", ret);
(runtime) void MqEnvProtect(MQ_CTX ctx)
top protect the service-environment → API: MqEnvProtect_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
void MqEnvRestore(MQ_CTX ctx)
top restore the service-environment → API: MqEnvRestore
[in] | ctx | the MqContextS instance to work on |
ErrorCopy | copy a MkErrorS from the sourceCtx to the targetCtx … | ||
ErrorFORMAT | helper used to access MkErrorDEFAULT from MqContextC | ||
ErrorMove | move a MkErrorS from the sourceCtx to the targetCtx … |
C-API: MqContextC_ErrorApi_C_API - MqContextC - move and copy an error from a context …
(runtime) enum MkErrorE MqContextErrorCopy(MQ_CTXN const targetCtx, MQ_CTXN const sourceCtx)
top copy a MkErrorS from the sourceCtx to the targetCtx … → API: MqContextErrorCopy_RT
In libmqmsgque the a MkRuntimeC is only one error-object per thread but this error-object has also addiitional attributes to identify the source of the error. In addition the libmqmsgque has also an extended-error-object MqErrorS which also has error-specific-attributes. The MqContextErrorCopy is used to copy an error frome sourceCtx to targetCtx and keep the additional attributes in sync.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
targetCtx | the MqContextC object and the target of the error | |
sourceCtx | the MqContextC object and the source of the error |
MK_ERR MqContextErrorFORMAT(MQ_CTXN const fmtobj)
top helper used to access MkErrorDEFAULT from MqContextC → API: MqContextErrorFORMAT
(runtime) enum MkErrorE MqContextErrorMove(MQ_CTXN const targetCtx, MQ_CTXN const sourceCtx)
top move a MkErrorS from the sourceCtx to the targetCtx … → API: MqContextErrorMove_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
targetCtx | the MqContextC object and the target of the error | |
sourceCtx | the MqContextC object and the source of the error and cleared |
Send | user friendly replacement for the MqContextC_SendApi_C_API … | ||
SendVL2 | A version of MqSend with va_list support … |
C-API: MqContextC_HighApi_C_API - MqContextC - User friendly replacement for the MqContextC_SendApi_C_API and the MqContextC_ReadApi_C_API …
User Friendly mean, replacing many lines of code by a single line of code.
The basic idea is, to use a format-signature to identify the additional command-line-arguments (args…).
The pseudo syntax is:
The following parts from the MqContextC_SendApi_C_API will be replaced by the MqContextC_HighApi_C_API
API Function | Usage |
---|---|
MqSendSTART | -> start a service call or a answer |
SendATOM | -> write a single argument into the data-package |
SendEND | -> send the service-call to the receiver |
ReadATOM | -> read a single argument from the data-package |
SendRETURN | -> answer a service call |
The replacement is defined by two parts, a High_CALL_SIGNATURE and a High_TOKEN_SIGNATURE. Both parts are strings and descripe a type or an action of a vararg argument.
Example: a typical code replacement in C looks like
and replaces the following commands...
The Call-Signature is a string of call-signature-char (CFC) starting with "E", "W", "C", "S" or "R" followed optional with "t"
CFC | Required | Reference | call-args | Default | Usage |
---|---|---|---|---|---|
E | yes | once | no | yes | MqSendEND |
W | yes | once | no | no | MqSendEND_AND_WAIT |
C | yes | once | function or service | no | MqSendEND_AND_CALLBACK |
S | yes | once | function or service | no | MqSendEND_AND_SUB |
T | yes | once | service-ident | no | MqSendEND_AND_TRANSACTION |
R | yes | once | no | no | MqSendRETURN |
t | no | W,S,T | seconds | MK_TIMEOUT_USER | set the TIMEOUT |
"service-ident : send-signature @ read-signature"
and is used to identify the target-service and the required arguments.
[:] and the send-signature.ASC | MkTypeE | Usage | Number of arguments required |
---|---|---|---|
"Y" | MK_I8 | MkBufferAtomU.I8 | 1 |
"O" | MK_BOL | MkBufferAtomU.BOL | 1 |
"S" | MK_I16 | MkBufferAtomU.I16 | 1 |
"I" | MK_I32 | MkBufferAtomU.I32 | 1 |
"F" | MK_FLT | MkBufferAtomU.FLT | 1 |
"W" | MK_I64 | MkBufferAtomU.I64 | 1 |
"D" | MK_DBL | MkBufferAtomU.DBL | 1 |
"G" | MK_LONG | 32bit=I, 64bit=W | 1 |
"B" | MK_BIN | MkBufferU.B | 1 -> MkBinaryR reference |
"C" | MK_STR | MkBufferU.C | 1 |
"U" | MK_BUF | MkBufferC . | 1 -> typeless Buffer able to hold every kind of data |
"L" | MK_BFL | MkBufferListC . | 1 -> list of MkBufferC . |
"." | MK_BUF | MkBufferC . | 1 -> READ ONLY - like 'U' but return the Buffer-Value and not the MkBufferC . |
"*" | MK_BFL | MkBufferListC . | 1 -> READ ONLY - like 'L' but collect ALL remaining data as ONE MkBufferListC . |
"[" | MqSendL_START | 0 -> Start of List | |
"]" | MqSendL_END | 0 -> End of List | |
"(" | MqSendT_START | 0 -> Start of Transaction Object, only as FIRST parameter | |
")" | MqSendT_END | 0 -> End of Transaction Object, only ONE supported | |
":" | END of SERVICE-IDENT | * -> next SEND_SIGNATURE | |
"@" | END of SEND-SIGN. | * -> next READ-SIGNATURE |
Example from server.c
→ in a service-call send the server-configuratien back to the client
static enum MkErrorE Ot_CNFG ( MQ_SERVICE_CALL_ARGS ) { MqSendSTART_E (mqctx); MqSendBOL_E (mqctx,MqConfigGetIsServer(mqctx)); MqSendBOL_E (mqctx,MqLinkIsParent(mqctx)); MqSendBOL_E (mqctx,MqSlaveIs(mqctx)); MqSendBOL_E (mqctx,MqConfigGetIsString(mqctx)); MqSendBOL_E (mqctx,MkRuntimeGetIsSilent()); MqSendBOL_E (mqctx,MqLinkIsConnected(mqctx)); MqSendSTR_E (mqctx,MqConfigGetName(mqctx)); MqSendI32_E (mqctx,MkRuntimeGetDebug()); MqSendI32_E (mqctx,(MK_I32)MqLinkGetCtxId(mqctx)); MqSendSTR_E (mqctx,MqServiceTokenGet(mqctx)); error: return MqSendRETURN (mqctx); }
(runtime,hide) enum MkErrorE MqSend(MQ_CTX const ctx, MK_STRN cstr, ...)
top user friendly replacement for the MqContextC_SendApi_C_API … → API: MqSend_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | cstr | the High_CALL_SIGNATURE |
(runtime,hide) enum MkErrorE MqSendVL2(MQ_CTX const ctx, MK_STRN cstr, va_list var_list)
top A version of MqSend with va_list support … → API: MqSendVL2_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | cstr | the doc_mq_c_High_CALL_SIGNATURE |
[in] | var_list | a variable argument list object |
LinkConnect | re-connect a client-server-link after a server crash or a network downtime … | ||
LinkCreate | make ctx to a parent-context and setup a new client-server-link … | ||
LinkCreateChild | make a context to a child-context on-top of an existing parent-client-server-link … | ||
LinkDefault | callback as wrapper for MqLinkCreate or MqLinkCreateChild with additional error-check code … | ||
LinkDelete | close the client-server-link … | ||
LinkGetCtxId | get an identifier which is unique per parent-or-child-context … | ||
LinkGetParent | get the initial parent-context from a client/server link … | ||
LinkGetTargetIdent | get the ident of the link-target … | ||
LinkIsConnected | is the context connected? … | ||
LinkIsParent | is the context a parent-context? … | ||
LinkShutdown | shutdown the communication with a server |
C-API: MqContextC_LinkApi_C_API - MqContextC - setup and manage a client-server-link …
The client-server-link connect two context, a client-parent-context and a server-parent-context. The link can be local (connect two context on the same host) or can be remote (connect two context on different hosts). On-Top the parent-context multiple child-context are allowed.
!on remote host! !on local host! server1---------x x----------server2 | | | | | child-context-1 child-context-2 | | | | | server parent-context-1-----x x-----parent-context-2 | | (MqConfigS::server) (example: MqConfigS::server --fork --uds … --file …) | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | (--tcp) (--pipe, --uds, --tcp) | | parent-context-1-----x x-----parent-context-2 | | | | client | child-context-1 child-context-2 | | | | | x------------x--------client-------x-------------x !on local host!
Definition of a "client-context"
Definition of a "server-context"
Definition of a "parent-context"
Definition of a "child-context"
(runtime) enum MkErrorE MqLinkConnect(MQ_CTX const ctx)
top re-connect a client-server-link after a server crash or a network downtime … → API: MqLinkConnect_RT
Do nothing if the client-server-link is already connected. This function is only useful in an event-function (IEvent) if the link-disconnect (ErrorIsEXIT) is ignored (ErrorReset). Read more from the: /example/c/Filter4.c
example.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqLinkCreate(MQ_CTX const ctx, MK_BAC args)
top make ctx to a parent-context and setup a new client-server-link … → API: MqLinkCreate_RT
The goal of the MqLinkCreate is to setup a link to a new server-context on the SERVER.
The link is created with MqIoComE to a server started with MqStartE.
The argument args is a list of command-line-arguments to configure the client-server-link including the @ item to add server-command-line-arguments.
The following special-keyword as first argument after @ is recognized:
"@ SELF arg1…"
will be "@ executable factory-name arg1…"
"@ WORKER arg1…"
will be "@ executable arg1…"
The executable is defined by (static) void MqInitSetArg0(MK_BAC bfl)
and will be automatical set for a non C / C++ language.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | args | command-line-arguments to configure the client-server-link |
(runtime) enum MkErrorE MqLinkCreateChild(MQ_CTX const ctx, MQ_CTX const parent, MK_BAC const args)
top make a context to a child-context on-top of an existing parent-client-server-link … → API: MqLinkCreateChild_RT
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.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | parent | the parent-context defined with MqLinkCreate |
[in] | args | command-line-arguments to configure the client-server-link without the "@" item. |
(runtime,hide) enum MkErrorE MqLinkDefault(MQ_CTX const ctx, MK_BAC const args)
top callback as wrapper for MqLinkCreate or MqLinkCreateChild with additional error-check code … → API: MqLinkDefault_RT
The function have to be used as argument to MqCtxTypeS::Child or MqCtxTypeS::Parent as default context-create function. Return an error if an unknown command-line-argument was found.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | args | command-line-arguments to configure the client-server-link with or without the "@" item. |
(runtime) void MqLinkDelete(MQ_CTX const ctx)
top close the client-server-link … → API: MqLinkDelete_RT
On a client the context will be set to not-connected and the function MqLinkIsConnected will return MK_NO
. On a server the context will be deleted but only if MqSetupS::ignoreExit is not set to MK_YES
. If the link is already not-connected nothing will happen.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
MK_NUM MqLinkGetCtxId(MQ_CTX const ctx)
top get an identifier which is unique per parent-or-child-context … → API: MqLinkGetCtxId
The context-identifier is a number and is used in the protocol to link a data-package to a context-pointer. This is necessary because the communication interface is shared between the parent-context and the child-context. This number is unique.
[in] | ctx | the MqContextS instance to work on |
MQ_CTX MqLinkGetParent(MQ_CTX const ctx)
top get the initial parent-context from a client/server link … → API: MqLinkGetParent
[in] | ctx | the MqContextS instance to work on |
MK_NULL
if ctx is MK_NULL
MK_STRN MqLinkGetTargetIdent(MQ_CTX const ctx)
top get the ident of the link-target … → API: MqLinkGetTargetIdent
This function is only useful if the link is up and running.
[in] | ctx | the MqContextS instance to work on |
MK_NULL
if not connected MK_BOOL MqLinkIsConnected(MQ_CTX const ctx)
top is the context connected? … → API: MqLinkIsConnected
A context is connected if the MqLinkCreate command was successful. A context is not connected if:
[in] | ctx | the MqContextS instance to work on |
MK_YES
or MK_NO
MK_BOOL MqLinkIsParent(MQ_CTX const ctx)
top is the context a parent-context? … → API: MqLinkIsParent
A context is a parent-context if it was created with MqLinkCreate
[in] | ctx | the MqContextS instance to work on |
MK_YES
or MK_NO
(runtime) enum MkErrorE MqLinkShutdown(MQ_CTX const ctx)
top shutdown the communication with a server → API: MqLinkShutdown_RT
The following tasks are performend:
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
Log | log the MqContextC … | ||
LogConfig | log the MqContextC part MqConfigS … | ||
LogEnv | log the MqContextC part MqEnvS … | ||
LogLink | log the MqContextC part MqLinkS … | ||
LogSetup | log the MqContextC part MqSetupS … | ||
LogShort | log the MqContextC with less info then MqContextLog … | ||
LogType | log the MqContextC part MkTypeS … | ||
LogParentOrChild | is ctx a PARENT or a CHILD ? … | ||
LogServerOrClient | is ctx a SERVER or a CLIENT ? … |
C-API: MqContextC_LogApi_C_API - MqContextC - log the output to a string or a MkLogFileC …
Logging is an important part of the debugging and validation task.
The logging target is set with MkRuntimeSetLogfile wich accepts a filename or the special token stdout or stderr.
Many logging functions have common parameters:
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
(runtime) void MqContextLog(MQ_CTXN const ctx, MK_OBJN fmtobj, MK_DBG const debug, MK_STRN const callfunc, MK_I32 const lvl)
top log the MqContextC … → API: MqContextLog_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | lvl | a user-defined prefix starting with "" for lvl=0 and increase with " " for lvl+1 (default=0 ) |
(runtime) void MqContextLogConfig(MQ_CTXN const ctx, MK_OBJN fmtobj, MK_DBG const debug, MK_STRN const callfunc, MK_I32 const lvl)
top log the MqContextC part MqConfigS … → API: MqContextLogConfig_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | lvl | a user-defined prefix starting with "" for lvl=0 and increase with " " for lvl+1 (default=0 ) |
(runtime) void MqContextLogEnv(MQ_CTX const ctx, MK_OBJ const fmtobj, MK_DBG const debug, MK_STRN const callfunc, MK_I32 const lvl)
top log the MqContextC part MqEnvS … → API: MqContextLogEnv_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | lvl | a user-defined prefix starting with "" for lvl=0 and increase with " " for lvl+1 (default=0 ) |
(runtime) void MqContextLogLink(MQ_CTXN ctx, MK_OBJN const fmtobj, MK_DBG const debug, MK_STRN const callfunc, MK_I32 const lvl)
top log the MqContextC part MqLinkS … → API: MqContextLogLink_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | lvl | a user-defined prefix starting with "" for lvl=0 and increase with " " for lvl+1 (default=0 ) |
(runtime) void MqContextLogSetup(MQ_CTXN const ctx, MK_OBJN fmtobj, MK_DBG const debug, MK_STRN const callfunc, MK_I32 const lvl)
top log the MqContextC part MqSetupS … → API: MqContextLogSetup_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | lvl | a user-defined prefix starting with "" for lvl=0 and increase with " " for lvl+1 (default=0 ) |
(runtime) void MqContextLogShort(MQ_CTXN const ctx, MK_OBJN fmtobj, MK_DBG const debug, MK_STRN const callfunc, MK_I32 const lvl, MK_STRN const label)
top log the MqContextC with less info then MqContextLog … → API: MqContextLogShort_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | label | a string to identify a task or object |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | lvl | a user-defined prefix starting with "" for lvl=0 and increase with " " for lvl+1 (default=0 ) |
(runtime) void MqContextLogType(MQ_CTX const ctx, MK_OBJ fmtobj, MK_DBG const debug, MK_STRN const callfunc, MK_I32 const lvl)
top log the MqContextC part MkTypeS … → API: MqContextLogType_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | lvl | a user-defined prefix starting with "" for lvl=0 and increase with " " for lvl+1 (default=0 ) |
MK_STRN MqLogParentOrChild(MQ_CTXN ctx)
top is ctx a PARENT or a CHILD ? … → API: MqLogParentOrChild
[in] | ctx | the MqContextS instance to work on |
MK_STRN MqLogServerOrClient(MQ_CTXN const ctx)
top is ctx a SERVER or a CLIENT ? … → API: MqLogServerOrClient
[in] | ctx | the MqContextS instance to work on |
CheckForLeftOverArguments | check for left over arguments from parameter args of MqLinkCreate … | ||
GetBuffer | get the MqContextS::ctxbuf object | ||
ToString | String-Slot - returns the string representation of the inst … | ||
Exit | delete the context and exit the current process or thread … | ||
GetRoot | get the Root (toplevel initial context) | ||
ProcessEvent | enter the event-loop and wait for an incoming service-request. … |
C-API: MqContextC_MiscApi_C_API - MqContextC - various functions to work on a context …
(runtime,hide) enum MkErrorE MqCheckForLeftOverArguments(MQ_CTX const ctx, MK_BFLN args)
top check for left over arguments from parameter args of MqLinkCreate … → API: MqCheckForLeftOverArguments_RT
This code is not part of MqLinkCreate because sometimes it is necessary to check for left over arguments after MqLinkCreate was called and after the calling function was able to process function specific arguments. By Default MqLinkCreate will delete all arguments belonging to libmqmsgque from the args object. If the calling function does not expect additional arguments or arguments were added with spelling errors, a call to MqCheckForLeftOverArguments will detect this.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in,out] | args | the argument-list to check for left-over arguments |
(runtime) MK_BUF MqContextGetBuffer(MQ_CTX const ctx)
top get the MqContextS::ctxbuf object → API: MqContextGetBuffer_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
context->ctxbuf
objectMK_NULL
for a non-error result.(runtime) MK_STRN MqContextToString(MQ_CTXN const ctx)
top String-Slot - returns the string representation of the inst … → API: MqContextToString_RT
The string is a human-readable form of the data stored in the object.
ToString
function by default.[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
"MK_NULL"
on error MK_NULL
for a non-error result.(runtime) void MqExit(MQ_CTX const ctx, MK_STRN const callfunc, MK_STRN const callfile, MK_I32 const callline)
top delete the context and exit the current process or thread … → API: MqExit_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | callfile | the name of the file the call take place (e.g. FILE) |
[in] | callline | the number of the line the call take place (e.g. LINE) |
To delete an application is a difficult task because the link-target have to be informed. This information is send as shutdown-event and finally as socket-exit after application-exit. This library tries to perform this two steps even if the default exit function is called. This is no problem because the second step (socket-exit) is enough to signal a link-down. It is not secure to depend only on socket-exit for application exit because sometimes the sockets stop working or the link-target does not get a socket-exit. For example the pipe-link on windows. The client can not exit and create a socket-exit error on the server because the server is still running without receiving a shutdown-event. A second argument for using the MqExit function is, that it can be used for process and thread exit. A thread, started by libmqmsgque, does exit but the process continue to work. To make it short use MqExit to exit your application.
The following steps are performed:
MQ_CTX MqGetRoot(MQ_CTX ctx)
top get the Root (toplevel initial context) → API: MqGetRoot
(runtime) enum MkErrorE MqProcessEvent(MQ_CTX const ctx, enum MqWaitOnEventE const wait, MK_TIME_T timeout)
top enter the event-loop and wait for an incoming service-request. … → API: MqProcessEvent_RT
This function is used to enter the event-loop and start listen on open file-handles and to call IEvent on idle.
This function is mostly used on a server to enter the event-loop and wait for an incoming service request or on a client/server with all functions which exchange data like MqContextC SEND API, MqLinkConnect etc.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) | ||||||||||||
[in] | ctx | the MqContextS instance to work on | ||||||||||||
[in] | wait | the operation-mode used to define the behaviour, possible values are:
| ||||||||||||
[in] | timeout | in seconds until a timeout-error is raised, possible values are:
|
ProxyForward | send the entire read-data-package-data to the link-target … | ||
ProxyItem | Copy a single-data-item from the sourceCtx to the targetCtx. |
C-API: MqContextC_ProxyApi_C_API - MqContextC - copy data from the read-data-package of the sourceCtx to the send-data-package of the targetCtx
The proxy-feature is used in a filter-setup to process-and-forward incoming data.
Example: A typical proxy-setup in pseudo C++ code
(runtime) enum MkErrorE MqProxyForward(MQ_CTX const sourceCtx, MQ_CTX const targetCtx, MQ_DMP const dump, MK_TIME_T const timeout)
top send the entire read-data-package-data to the link-target … → API: MqProxyForward_RT
The goal of this function is to link two context, typically a master and a slave (filter). This function is typically used in a service or and event callback to send the entire package and wait for the answer.
Example of a typical usage in pseudo c++
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | sourceCtx | the source of the copy |
[in,out] | targetCtx | the target of the copy |
[in] | dump | if not MK_NULL , the value is the source of the copy, dump is the return from MqDumpExport, |
[in] | timeout | in seconds until a timeout-error is raised (possible values like ProcessEvent) (MK_TIMEOUT_DEFAULT=MK_TIMEOUT_USER ) |
(runtime) enum MkErrorE MqProxyItem(MQ_CTX const sourceCtx, MQ_CTX const targetCtx)
top Copy a single-data-item from the sourceCtx to the targetCtx. → API: MqProxyItem_RT
MqContextC - copy data from the read-data-package of the sourceCtx to the send-data-package of the targetCtx
The proxy-feature is used in a filter-setup to process-and-forward incoming data.
Example: A typical proxy-setup in pseudo C++ code
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | sourceCtx | the source of the copy |
[in,out] | targetCtx | the target of the copy |
ReadTT | read a PRIMITIVE TYPE from the read-data-package … | ||
ReadALL | get a temporary MkBufferListC from all data in the read-data-package … | ||
ReadBFL | get a temporary MkBufferListC from next list-item in the read-data-package … | ||
ReadBinaryR | read a MkBinaryR from the read-data-package … | ||
ReadBUF | get a temporary MkBufferC from the read-data-package … | ||
ReadHDL | read the handle from the read-data-package | ||
ReadLIST | get all arguments as native list … | ||
ReadLONG | read the long native object from the read-data-package | ||
ReadNEXT | get the next argument as native object … | ||
ReadStringR | read a MkStringR from the read-data-package … |
ReadL_END | finish to extract a list-items from the read-data-package. … | ||
ReadL_START | start to extract a list-items from the read-data-package. … | ||
ReadT_END | finish to extract a longterm-transaction-item from the read-data-package. … | ||
ReadT_START | start to extract a longterm-transaction-item from the read-data-package. … |
ReadGetNextType | get the type (MkTypeE) of the next Item in the read-data-buffer or "0" if not available | ||
ReadGetNumItems | get the number of items left in the read-data-package … | ||
ReadItemExists | check if an item exists in the read-data-package … | ||
ReadUndo | undo the last MqContextC READ API function call … |
C-API: MqContextC_ReadApi_C_API - MqContextC - extract data from an incoming read-data-package …
A data-package is read in two different scenarios:
Reading data is a passive-task and the opposite of sending data, which is an active-task. Passive means that the reading process is triggered by an incoming-data-package and not by the software workflow or by the user.
There is a read function and some help functions for each basic type defined in MkBufferS .
Example from server.c
→ read-safety: Make a nested service-call
static enum MkErrorE Ot_CSV1 ( MQ_SERVICE_CALL_ARGS ) { // read the input-data from the CSV1-service-call // client → server MK_I32 retI, inI = MqReadI32_e(mqctx) + 1; // call the CSV2-service at the client, wait 10sec for timeout // server → client → server MqSend_E(mqctx, "Wt", 10, "CSV2:I@I", inI, &retI); // answer the CSV1-service-call with the result from the CSV2-service-call // server → client error: return MqSend(mqctx, "R", "I", retI+1); }
C-API: MqContextC_ReadApi_Atom_C_API - MqContextC - read a single-data-item outof a read-data-package …
(runtime) enum MkErrorE MqReadALL(MQ_CTX const ctx, MK_BFL const val_inout)
top get a temporary MkBufferListC from all data in the read-data-package … → API: MqReadALL_RT
If the val_inout is MK_NULL
than a temporary MkBufferListC is returned. If the val_inout is not MK_NULL
than the memory of the val_inout is reused.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_inout | the MkBufferListC - the storage of the input is reused |
MK_NULL
for a non-error result.(runtime) enum MkErrorE MqReadBFL(MQ_CTX const ctx, MK_BFL *const val_out)
top get a temporary MkBufferListC from next list-item in the read-data-package … → API: MqReadBFL_RT
If the next item in the read-data-package is a list-item, (created with MqReadL_START and (runtime) enum MkErrorE MqReadL_END(MQ_CTX const ctx)
), only return this item. If the next item in the read-data-package is not a list-item than return an error. If you require all data in the read-data-package returned as single MkBufferListC than use MqReadALL.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_out | the MkBufferListC as return-value |
MK_NULL
for a non-error result.(runtime) enum MkErrorE MqReadBinaryR(MQ_CTX const ctx, MkBinaryR *const val_out)
top read a MkBinaryR from the read-data-package … → API: MqReadBinaryR_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_out | the MkBinaryR to return |
(runtime) enum MkErrorE MqReadBUF(MQ_CTX const ctx, MK_BUF *const val_out)
top get a temporary MkBufferC from the read-data-package … → API: MqReadBUF_RT
Return a temporary-data-item from the read-data-package. The lifetime of the MkBufferC is only the current callback up to the next read operation in the same parent-context. This object is owned by LibMqMsgque and must not be freed.
Example from server.c
→ read and update a MkBufferC
// START - ReadBUF - Example, read a buffer-object and append a string MK_BUF buf; MqReadBUF_E (mqctx,&buf); MkBufferAppendSTR(buf,"- a really log text to overwrite the already allocated space"); MqSendBUF_E (mqctx,buf); MqReadI32_E (mqctx,&i); MqSendI32_E (mqctx,i+1); // END - ReadBUF - Example
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_out | The out-value of type MkBufferC. 1) It is an error if the out-value is MK_NULL , 2. If there is an error, the out-value remains unchanged. |
MK_NULL
MK_NULL
for a non-error result.(runtime) enum MkErrorE MqReadHDL(MQ_CTX const ctx, MK_HDL *const val_out)
top read the handle from the read-data-package → API: MqReadHDL_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_out | the handle-object to read |
(runtime) enum MkErrorE MqReadLIST(MQ_CTX const ctx, MK_NAT_LIST *const val_out)
top get all arguments as native list … → API: MqReadLIST_RT
The MqReadLIST is a function what interacts with the Target-Programming-Language (TPL) list-object.
There is no guarantee that a list-object will be available. Therefore, this function is an add-on and will only be implemented when possible.
Example from example/tcl/server.tcl
→ start a WORKER using all arguments from the service-call.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_out | the native list as return |
(runtime) enum MkErrorE MqReadLONG(MQ_CTX const ctx, MK_LONG *const val_out)
top read the long native object from the read-data-package → API: MqReadLONG_RT
on 64bit use a MqReadI64 and on 32bit use a MqReadI32
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_out | the native long object to read |
(runtime) enum MkErrorE MqReadNEXT(MQ_CTX const ctx, MK_NAT_OBJECT *const val_out)
top get the next argument as native object … → API: MqReadNEXT_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_out | the native object as return |
(runtime) enum MkErrorE MqReadStringR(MQ_CTX const ctx, MkStringR *const val_out)
top read a MkStringR from the read-data-package … → API: MqReadStringR_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_out | the MkStringR to return |
((runtime)) enum MkErrorE MqReadTT(MQ_CTX const ctx, MK_TT *const val_out)
The ReadTT provide a single function for every PRIMITIVE TYPE
attribute | return | command | C-API : |
---|---|---|---|
(runtime) | enum MkErrorE | MqReadI8(MQ_CTX const ctx, MK_I8 *const val_out) | MqReadI8_RT |
(runtime) | enum MkErrorE | MqReadI16(MQ_CTX const ctx, MK_I16 *const val_out) | MqReadI16_RT |
(runtime) | enum MkErrorE | MqReadI32(MQ_CTX const ctx, MK_I32 *const val_out) | MqReadI32_RT |
(runtime) | enum MkErrorE | MqReadI64(MQ_CTX const ctx, MK_I64 *const val_out) | MqReadI64_RT |
(runtime) | enum MkErrorE | MqReadSTR(MQ_CTX const ctx, MK_STRN *const val_out) | MqReadSTR_RT |
(runtime) | enum MkErrorE | MqReadBIN(MQ_CTX const ctx, MkBinaryR *const val_out) | MqReadBIN_RT |
(runtime) | enum MkErrorE | MqReadBOL(MQ_CTX const ctx, MK_BOL *const val_out) | MqReadBOL_RT |
(runtime) | enum MkErrorE | MqReadFLT(MQ_CTX const ctx, MK_FLT *const val_out) | MqReadFLT_RT |
(runtime) | enum MkErrorE | MqReadDBL(MQ_CTX const ctx, MK_DBL *const val_out) |
read a PRIMITIVE TYPE from the read-data-package …
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | val_out | the value to read |
C-API: MqContextC_ReadApi_Block_C_API - MqContextC - read a block-of-data outof a read-data-package …
(runtime) enum MkErrorE MqReadL_END(MQ_CTX const ctx)
top finish to extract a list-items from the read-data-package. … → API: MqReadL_END_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqReadL_START(MQ_CTX const ctx, MK_BUF buf)
top start to extract a list-items from the read-data-package. … → API: MqReadL_START_RT
Initialize the read with the current body-item or an optional MkBufferC. This command requires a final (runtime) enum MkErrorE MqReadL_END(MQ_CTX const ctx)
to finish the read.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | buf | an optional MkBufferC as result from a previous RMqReadBUF call or MK_NULL to use the next item from the read-data-package. |
(runtime) enum MkErrorE MqReadT_END(MQ_CTX const ctx)
top finish to extract a longterm-transaction-item from the read-data-package. … → API: MqReadT_END_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqReadT_START(MQ_CTX const ctx)
top start to extract a longterm-transaction-item from the read-data-package. … → API: MqReadT_START_RT
Initialize the read with the current-item or an optional MkBufferC. The current-item have to be the first item in the read-data-package. This command requires a final (runtime) enum MkErrorE MqReadL_END(MQ_CTX const ctx)
to finish the read.
Example from server.c
→ read the results from a service-call with transaction-support
static enum MkErrorE Ot_TRN2 ( MQ_SERVICE_CALL_ARGS ) { struct ServerCtxS *srvctx = (struct ServerCtxS*) mqctx; MqReadT_START_E (mqctx); MqReadI32_E (mqctx, &srvctx->i); MqReadT_END_E (mqctx); MqReadI32_E (mqctx, &srvctx->j); return MK_OK; error: return MkErrorStack_1X (mqctx); }
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
C-API: MqContextC_ReadApi_Misc_C_API - MqContextC - various functions to work on a read-data-package …
enum MkTypeE MqReadGetNextType(MQ_CTX const ctx)
top get the type (MkTypeE) of the next Item in the read-data-buffer or "0" if not available → API: MqReadGetNextType
[in] | ctx | the MqContextS instance to work on |
MK_NUM MqReadGetNumItems(MQ_CTX const ctx)
top get the number of items left in the read-data-package … → API: MqReadGetNumItems
[in] | ctx | the MqContextS instance to work on |
MK_BOOL MqReadItemExists(MQ_CTX const ctx)
top check if an item exists in the read-data-package … → API: MqReadItemExists
[in] | ctx | the MqContextS instance to work on |
MK_YES
or MK_NO
(runtime) enum MkErrorE MqReadUndo(MQ_CTX const ctx)
top undo the last MqContextC READ API function call … → API: MqReadUndo_RT
Put the internal position-pointer to the start of the last read body-item. The next read function call will extract the same item again. Only one undo level is supported.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
RouteCreate | create/delete a routing-link between context an a service using route | ||
RouteDelete | delete a routing-link created with MqRouteCreate | ||
RouteGetPath | return the absolut route-connection-string up to the current ctx … | ||
RouteGetTree | create an overview about all available routing-target and services … | ||
RouteResolve | return a list of all context belonging to ident … | ||
RouteTraverse | traverse a tree down and call service if available. |
C-API: MqContextC_RouteApi_C_API - MqContextC - setup and manage a routing-link …
A routing-link is the connection of two context, the route-source and the route-target, with a unspecifiend number of hub-context in between using a specific service-token.
A single context is identified by the context-identifier as returned by MqClassIdentGet.
A routing-link can be created using Service-Level-Routing or Package-Level-Routing.
The difference between Service-Level-Routing and Package-Level-Routing is the public versa private behaviour.
Summary:
(runtime) enum MkErrorE MqRouteCreate(MQ_CTX ctx, MK_STRN route, MK_STRN service, MK_BOOL overwrite)
using a route-connection-string and a service-token. The TCP/IP model define the following layers (from: https://www.geeksforgeeks.org/tcp-ip-model/) :
The libmqmsgque layer model is an extension to the TCP/IP layer model.
protocoll_mq.h
→ this is the "syntax" of the protocol. This layer provide the MqContextC-ServiceApi ontop of the Application Layer.
The master-slave-link is used to create a mesh of nodes defined by different parent-context. The master control the slave.
The master-slave-link is used to perform the following tasks:
In difference to the client-server-link the master-slave-link connect two independent parent-context in the same process or thread (e.g. node). This leads to the restriction that only the master-context can be a server-context because only one server-context per node is possible.
node-0 | node-1/2 | node-3/4/5 =================================================================== | <- client/server link -> | <- client/server link -> | | <-- master/slave link --> | |- client1-0 -|- server3 ... |- server1 -| | |- client1-1 -|- server4 ... client0-0 -| |- server2 -|- client1-2 -|- server5 ...
Definition of the "master-context"
Definition of the "slave-context"
0
.Definition of the "worker-context"
0
./etc/services
0
slave-id | value | definition |
---|---|---|
MQ_SLAVE_MAX | 1024 | internal: the maximum slave-id … . |
MQ_SLAVE_USER | 10 | internal: start of user-defined-slave-id . |
MQ_SLAVE_LOOPBACK | 0 | internal: the loopback-slave-id, (call my own services) . |
MQ_SLAVE_FILTER | 1 | internal: the filter-slave-id, (on a master get the filter-slave) . |
MQ_SLAVE_MASTER | 1 | internal: the master-slave-id, (on a slave get the master) . |
MQ_SLAVE_OTHER | 1 | internal: on the master-ctx get the slave-ctx and on the slave-ctx get the master-ctx . |
range | definition |
---|---|
0 <= slave-id < MQ_SLAVE_MAX | range of valid slave-id's |
0 <= slave-id < MQ_SLAVE_USER | internale usage |
MQ_SLAVE_USER <= slave-id < MQ_SLAVE_MAX | external usage |
Definition of the "LOOPBACK" (0) slave
client | server | =========================================== | <--- client/server ---> | <-- loop --> | | <------ master/slave -----> | client -- | -- server -- | -- client -- # == == # server -- | -- client -- #
slave-id = 0
. MyLoopServer.c
→ create a new loop-server #include "common.h" // [MyLoopServerC_Define] typedef struct MyLoopServerS { struct MqContextS mqctx; ///< link to the \libmqmsgque object #define mydata_size 30 char mydata[mydata_size]; ///< define the "mydata" attribute } MyLoopServerC; // [MyLoopServerC_Define] // the MyLoopServerC class-type static MkThreadLocal MK_TYP MyLoopServerCTT = NULL; // service to serve all EXTERNAL requests for token "HLWO" static enum MkErrorE HLWO_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "loopback" context MQ_CTX loop = MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK); // call the LOOP service on the SAME server MqSend_E(loop,"W","LOOP"); // answer HLWO with string-return from LOOP MqSend_E(mqctx, "R", "C", MqReadSTR_e(loop)); return MK_OK; error: return MqSendRETURN(mqctx); } // service to serve all INTERNAL requests for token "LOOP static enum MkErrorE LOOP_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "master" context MyLoopServerC* master = (MyLoopServerC*)MqSlaveGetMaster(mqctx); // answer LOOP with data from MASTER->mydata attribute return MqSend(mqctx, "R", "C", master->mydata); } // define a service as link between the token "HLWO" and the callback "HLWO_srv" static enum MkErrorE ServerSetup ( MQ_SERVICE_CALL_ARGS ) { // EXTERNAL: link the "HLWO" service with "HLWO_srv" MqServiceCreate_E(mqctx, "HLWO", HLWO_srv, NULL, NULL, NULL); // INTERNAL: link the "LOOP" service with "LOOP_srv" MqServiceCreate_E(MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK), "LOOP", LOOP_srv, NULL, NULL, NULL); return MK_OK; error: return MkErrorStack_1X(mqctx); } // [MyLoopServerC_Create] enum MkErrorE MyLoopServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { // create new instance using the MyLoopServerCTT class-type MQ_CTX const mqctx = *contextP = MqContextCreate(MyLoopServerCTT,tmpl); // initialize the new context MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); // cast the libmqmsgque-context into the MyLoopServerC-context MyLoopServerC* mqctxC = (MyLoopServerC*)mqctx; // initialize the "mydata" attribute strncpy(mqctxC->mydata,"Hello World",mydata_size); mqctxC->mydata[mydata_size-1] = '\0'; return MK_OK; } // [MyLoopServerC_Create] int main (int argc, MK_STRN argv[]) { MqRtSetup_NULL; // [MyLoopServerC_Init] // initialize the MyLoopServer class-type with existing MqContextC_TT class-type MyLoopServerCTT = MkTypeDup2(MqContextC_TT,"MyLoopServerC"); MyLoopServerCTT->objsize = sizeof(struct MyLoopServerS); // [MyLoopServerC_Init] // setup commandline arguments for later use MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; // create "MyLoopServer" factory… and make it to the default. MqFactoryDefault(MqFactoryAdd_2(MyLoopServerFactory,"MyLoopServer")); // inspect commandline-argument for the "factory" to choose… and create a object MqFactoryNew_E (MqFactoryGetCalledL(largv), NULL, &mqctx); // start listen for incoming call's MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }
Performance analyse
Nhi1Exec perfclient.c --parent --wrk ? @ perfserver.c
Nhi1Exec -r=uds perfserver.c --spawn|fork|thread
Nhi1Exec -r=uds perfclient.c --parent --wrk ?
perfclient worker perfserver ========== ====== ========== | |- loop --wrk x |- MqSlaveWorker(...) -> worker[1] |- MqSend(worker[1],"E","STR0..") -> PerfWorker_I160(...) |- loop endless |- MqContextCreate(...) |- MqLinkCreate(...) <-> MqContextCreate(...) |- MqContextDelete(...) <-> MqContextDelete(...) |- sleep x sec |- loop --wrk x |- MqSend(worker[1],"C"..,"END0") -> PerfWorker_END0(...) | |- stop loop |- "callback" - add number to all <- |- return #context
setup | –wrk | # worker-context | performance | info |
---|---|---|---|---|
pipe | 1 | 2500 | 1000 | the pipe start a new worker-context with spawn |
spawn | 1 | 2500 | <1000 | same as pipe but use network-protocoll |
fork | 1 | 3800 | 4000 | the fork is faster than spawn |
thread | 1 | 16500 | 9000 | the thread is faster than fork |
pipe | 4 | 8000 | 4500 | the worker scale linear up to number of processors |
spawn | 4 | 7600 | <4500 | - |
fork | 4 | 23200 | 11500 | - |
thread | 4 | 55500 | 27500 | - |
pipe | 8 | 10000 | 5500 | the additional scaling up to the max hyper-threading does not really help |
spawn | 8 | 9100 | <5500 | - |
fork | 8 | 23200 | 11500 | - |
thread | 8 | 55500 | 27500 | - |
A client-server connection is defined with the route-connection-string as a composition of "identifier" and is build like a UNIX directory tree with the initial client as root.
Example: GUI/Data Frontend
With --ident-from prefix|factory the identifier is defined as prefix-identifier or factory-identifer.
A route-connection-string is the path between TWO locations in the tree using the UNIX syntax:
short | syntax | direction |
---|---|---|
dot | . | current-context |
double-dot | .. | previous-context |
slash | / | root-context (the client) |
"string" | xxx | next-context with name xxx |
path between "DB" and "header"
relative: ctx.RouteCreate("../GUI/header",service)
absolute: ctx.RouteCreate("/frontend/GUI/header",service)
path between "footer" and "DB"
relative: ctx.RouteCreate("../../DB",service)
absolute: ctx.RouteCreate("/frontend/DB",service)
path between "frontend" and "footer"
relative: ctx.RouteCreate("GUI/footer",service)
absolute: ctx.RouteCreate("/frontend/GUI/footer",service)
The LibMqMsgque-Service-Layer-Routing create proxy-services (MqServiceProxyRoundRobin ...) between frontend and footer. (example c++)
The MqRouteCreate will take the following action:
Attention:
overwrite=true
to guarantee that a route is available....
(runtime) enum MkErrorE MqRouteCreate(MQ_CTX ctx, MK_STRN route, MK_STRN service, MK_BOOL overwrite)
top create/delete a routing-link between context an a service using route → API: MqRouteCreate_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | route | the absolute or relative path to the target-context, if NULL or '\0' the current context is returned. |
[in] | service | the service token on the target context |
[in] | overwrite | if overwrite=false an error is raised if the service already exists. |
(runtime) enum MkErrorE MqRouteDelete(MQ_CTX ctx, MK_STRN route, MK_STRN service, MK_BOOL overwrite)
top delete a routing-link created with MqRouteCreate → API: MqRouteDelete_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | route | the absolute or relative path to the target-context, if NULL or '\0' the current context is returned. |
[in] | service | the service token on the target context |
[in] | overwrite | if overwrite=false an error is raised if the service already exists. |
(runtime) enum MkErrorE MqRouteGetPath(MQ_CTX const ctx, MK_STRN *path_out)
top return the absolut route-connection-string up to the current ctx … → API: MqRouteGetPath_RT
The absolut route-connection-string is the route starting at root (e.g. "/").
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | path_out | the return path or MK_NULL on error |
(runtime) enum MkErrorE MqRouteGetTree(MQ_CTX const ctx, MK_BFL *treeP_out)
top create an overview about all available routing-target and services … → API: MqRouteGetTree_RT
The data returned is a list of "ROUTE|IDENT|SERVICE,..."
string items.
ROUTE
is the route-connection-string used in (runtime) enum MkErrorE MqRouteCreate(MQ_CTX ctx, MK_STRN route, MK_STRN service, MK_BOOL overwrite)
. IDENT
is the MqClassIdentGet and usually the final part of the route-connection-string. SERVICE
is the list of services available at IDENT
.Example from MyWorker.c
→ get the "Tree" as service
void TREE () { Send("R", "L", RouteGetTree()); }
Example from tests/route2.test -> route2-1-0
/cl-0/sv-0/svWO2-11/svWO3-11|svWO3-11-0-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-11/svWO3-11|svWO3-11-1-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-11/svWO3-11|svWO3-11-2-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-11/svWO3-12|svWO3-12-0-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-11/svWO3-12|svWO3-12-1-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-11/svWO3-12|svWO3-12-2-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-11|svWO2-11-0-2|FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-11|svWO2-11-1-2|FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-11|svWO2-11-2-2|FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-12/svWO3-11|svWO3-11-0-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-12/svWO3-11|svWO3-11-1-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-12/svWO3-11|svWO3-11-2-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-12/svWO3-12|svWO3-12-0-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-12/svWO3-12|svWO3-12-1-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-12/svWO3-12|svWO3-12-2-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-12|svWO2-12-0-2|FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-12|svWO2-12-1-2|FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-12|svWO2-12-2-2|FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0|sv-0-0-2|FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0|sv-0-1-2|FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0|sv-0-2-2|FOID,HLWO,HLWS,PATH,TREE /cl-0|cl-0-0-2|HLWO,HLWS /cl-0|cl-0-1-2|HLWO,HLWS /cl-0|cl-0-2-2|HLWO,HLWS /cl-0/sv-0/svWO2-11/svWO3-11|svWO3-11-0-2|FINL,FOID,HLWO,HLWS,PATH,TREE /cl-0/sv-0/svWO2-11/svWO3-11|svWO3-11-1-2|FINL,FOID,HLWO,HLWS,PATH,TREE
The following information is available:
cl-0
cl-0
, are reachable: cl-0-
.... sv
... [in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | treeP_out | the tree-object with the results… |
(runtime) MQ_CTX_A MqRouteResolve(MQ_CTX const ctx, MK_STRN const ident, MK_NUM const retnum)
top return a list of all context belonging to ident … → API: MqRouteResolve_RT
This api-proc is used to return all context with MqLinkS::targetIdent == ident
.
In addition the following special ident are recognized:
MK_NULL
or DOT=. or ClassIdentGet -> The loopback-slave Example from server.c
→ in a service call return all connected targets
MK_STRN rmtIdent = MqReadSTR_e (mqctx); for (MQ_CTX* ret=MqRouteResolve(mqctx,rmtIdent,-1).data; *ret != NULL; ret++) { MqSendSTR_E (mqctx, MqLinkGetTargetIdent(*ret)); }
MK_NULL
for a non-error result.MK_NULL
.[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | ident | The identifer to search the context for |
[in] | retnum | The maximum number-of-items accepted in the result-array, if <0 than MQ_ROUTE_CTX_MAX is used. |
MK_NULL
. (runtime) enum MkErrorE MqRouteTraverse(MQ_CTX ctx, MK_STRN service, MK_BAC args)
top traverse a tree down and call service if available. → API: MqRouteTraverse_RT
The MqRouteTraverse is intended to call a service on all-routes "*"
starting from ctx.
This is a tool to be used to do maintenance work, sometimes a service is changed (e.g MqRouteCreate) or an internal status need to be reset.
The following internal tasks are performed ( C notation ) :
"*"
to get all routes starting from the ctx up to MQ_ROUTE_CTX_MAX routes : sRouteTool_CB
set the flag[i]
to 1
to signal done.[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | service | the service token to be called |
[in] | args | command-line-arguments passed as arguments to the service call |
SendTT | MqContextC - append a native PRIMITIVE TYPE value to the send-data-package … | ||
SendBFL | append a MkBufferListC object to the send-data-package object … | ||
SendBinaryR | append a MkBinaryR object to the send-data-package. … | ||
SendBUF | append a MkBufferC object to the send-data-package object … | ||
SendBUS_FLAT | append a MkBufferStreamC object to the send-data-package object … | ||
SendHDL | send the handle to the send-data-package | ||
SendL_FLAT | append a MkBufferListC object as flat list of items to the send-data-package object … | ||
SendLONG | send the long native object to the send-data-package | ||
SendStringR | MqContextC - append a native PRIMITIVE TYPE value to the send-data-package … | ||
SendV | append a vararg string to the send-data-package object … | ||
SendVL | append a vararg string as va_list to the send-data-package object … |
SendEND | MqContextC - finish the send-data-block and call synchronous/asynchronous a remote-service … | ||
SendEND_AND_CALLBACK | finish the send-data-block, call the remote service, do not-wait for the result but expect the result on a callback … | ||
SendEND_AND_SUB | finish the send-data-block, call the remote service, do wait for the result and expect multiple sub-results on a callback … | ||
SendEND_AND_TRANSACTION | finish the send-data-block, call the remote service to do a longterm-transaction-call … | ||
SendEND_AND_WAIT | finish the send-data-block, call the remote service and wait for result… | ||
SendSTART | initialize the send-data-package. … | ||
SendSYNC | garantee that all pending asynchronous-service-calls are processed. … |
SendL_END | finish to append an embedded body-list-item to the send-data-package. … | ||
SendL_START | start to append an embedded body-list-item to the send-data-package. … | ||
SendT_END | closed a longterm-transaction-item … | ||
SendT_START | open a longterm-transaction-item … |
SendERROR | send the data from the MkErrorC to the link target . … | ||
SendRETURN | MqContextC - finish the send-data-block on the server and optional return the results. … | ||
SendRETURN_SUB | return Sub-Data-Blocks required by MqSendEND_AND_SUB … |
C-API: MqContextC_SendApi_C_API - MqContextC - construct an outgoing send-data-package …
A data-package is send in two different scenarios:
Sending data is an active task and the opposite of reading data, which is a passive task. Active means that the send process is triggered by the software workflow or by the user.
For each basic type defined in MkBufferS, there is a send function and some help functions.
If timeout != 0 is used, the application enters the event loop and waits in the current process or thread for timeout seconds until the service call is finished.
While waiting for a result, the application can continue to work on other events that are in the same or in a different process or thread.
Example-1: a service call, send and read a data-package
On a client: perform a service call
send the service-call | MqSendSTART → SendTT... → MqSendEND_AND_WAIT |
read the result package | ReadTT... → ... |
on a server: answer a service call
read the service-call | ReadTT... → ... |
send the result package | MqSendSTART → SendTT... → MqSendRETURN |
Important in the code from above is the last command MqSendEND_AND_WAIT because this is just one of five possibilities:
command | synchron | database | result |
---|---|---|---|
MqSendEND | no | no | no |
MqSendEND_AND_WAIT | yes | no | single return data |
MqSendEND_AND_SUB | yes | no | multiple return data |
MqSendEND_AND_CALLBACK | no | no | single return data |
MqSendEND_AND_TRANSACTION | no | yes | two return data |
To send a data-package is one task, to send it to the right receiver is an other one. The right receiver is identified using the token parameter argument. This parameter have to be a 4 character string. You'll probably ask "why 4?" the answer is that this string should be "human" readable and easy to "compare". As solution this string is mapped to a 4 byte integer used to find the proper key/value entry in the service-hash-table on the server. (in short: to search an integer is much faster as to search a string)
Example-2: (in C) At the client, calling the service and wait for an answer
... or using the MqContextC HIGH API
Example-3: (in C) At the server, answer the service call
... or using the MqContextC HIGH API
C-API: MqContextC_SendApi_Atom_C_API - MqContextC - append a native PRIMITIVE TYPE value to the send-data-package …
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the value to appending |
(runtime) enum MkErrorE MqSendBFL(MQ_CTX const ctx, MK_BFLN const val)
top append a MkBufferListC object to the send-data-package object … → API: MqSendBFL_RT
The items of the list are send as list using MqSendL_START and MqSendL_END.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the pointer to an MkBufferListC object to send |
(runtime) enum MkErrorE MqSendBinaryR(MQ_CTX const ctx, MkBinaryR const val)
top append a MkBinaryR object to the send-data-package. … → API: MqSendBinaryR_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the value to appending |
[]) will be send. (runtime) enum MkErrorE MqSendBUF(MQ_CTX const ctx, MK_BUFN const val)
top append a MkBufferC object to the send-data-package object … → API: MqSendBUF_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the value to appending |
(runtime) enum MkErrorE MqSendBUS_FLAT(MQ_CTX const ctx, MK_BUSN const val)
top append a MkBufferStreamC object to the send-data-package object … → API: MqSendBUS_FLAT_RT
The items of the stream are send flast as the stream is appended to the send-data-package.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the pointer to an MkBufferStreamC object to send |
(runtime) enum MkErrorE MqSendHDL(MQ_CTX const ctx, MK_HDL const val)
top send the handle to the send-data-package → API: MqSendHDL_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the handle-object to send |
(runtime) enum MkErrorE MqSendL_FLAT(MQ_CTX const ctx, MK_BFLN const val)
top append a MkBufferListC object as flat list of items to the send-data-package object … → API: MqSendL_FLAT_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the pointer to an MkBufferListC object to send |
(runtime) enum MkErrorE MqSendLONG(MQ_CTX const ctx, MK_LONG const val)
top send the long native object to the send-data-package → API: MqSendLONG_RT
on 64bit use a MqSendI64 and on 32bit use a MqSendI32
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the native long object to send |
(runtime) enum MkErrorE MqSendStringR(MQ_CTX const ctx, MkStringR const val)
top MqContextC - append a native PRIMITIVE TYPE value to the send-data-package … → API: MqSendStringR_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the value to appending |
"MK_NULL"
will be send.(runtime,hide) enum MkErrorE MqSendV(MQ_CTX const ctx, MK_FST const printfmt, ...)
top append a vararg string to the send-data-package object … → API: MqSendV_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | printfmt | is a c-string used as printf like format string |
(runtime,hide) enum MkErrorE MqSendVL(MQ_CTX const ctx, MK_FST const printfmt, va_list var_list)
top append a vararg string as va_list to the send-data-package object … → API: MqSendVL_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | printfmt | is a c-string used as printf like format string |
[in] | var_list | a variable argument list object |
((runtime)) enum MkErrorE MqSendTT(MQ_CTX const ctx, MK_TT const val)
The SendTT provide a single function for every PRIMITIVE TYPE
attribute | return | command | C-API : |
---|---|---|---|
(runtime) | enum MkErrorE | MqSendI8(MQ_CTX const ctx, MK_I8 const val) | MqSendI8_RT |
(runtime) | enum MkErrorE | MqSendI16(MQ_CTX const ctx, MK_I16 const val) | MqSendI16_RT |
(runtime) | enum MkErrorE | MqSendI32(MQ_CTX const ctx, MK_I32 const val) | MqSendI32_RT |
(runtime) | enum MkErrorE | MqSendI64(MQ_CTX const ctx, MK_I64 const val) | MqSendI64_RT |
(runtime) | enum MkErrorE | MqSendSTR(MQ_CTX const ctx, MK_STRN const val) | MqSendSTR_RT |
(runtime) | enum MkErrorE | MqSendBIN(MQ_CTX const ctx, MkBinaryR const val) | MqSendBIN_RT |
(runtime) | enum MkErrorE | MqSendBOL(MQ_CTX const ctx, MK_BOL const val) | MqSendBOL_RT |
(runtime) | enum MkErrorE | MqSendFLT(MQ_CTX const ctx, MK_FLT const val) | MqSendFLT_RT |
(runtime) | enum MkErrorE | MqSendDBL(MQ_CTX const ctx, MK_DBL const val) |
MqContextC - append a native PRIMITIVE TYPE value to the send-data-package …
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | val | the value to appending |
C-API: MqContextC_SendApi_Basics_C_API - MqContextC - finish the send-data-block and call synchronous/asynchronous a remote-service …
calling a remote service and wait timeout seconds for an result. If timeout == 0
it is an asynchronous-service-call and if the timeout > 0
it is a synchronous-service-call.
service-call | blocking | timeout |
---|---|---|
synchronous | yes | timeout > 0 |
asynchronous | no | timeout == 0 |
blocking mean waiting max timeout seconds to finishing the service-call:
If an error was raised on the server during the service-processing… the following error-handling will be available
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
[in] | timeout | in seconds until a timeout-error is raised (possible values like ProcessEvent) (MK_TIMEOUT_DEFAULT=0 ) |
(runtime) enum MkErrorE MqSendEND(MQ_CTX const ctx, MQ_TOK const token, MK_TIME_T timeout)
top MqContextC - finish the send-data-block and call synchronous/asynchronous a remote-service … → API: MqSendEND_RT
calling a remote service and wait timeout seconds for an result. If timeout == 0
it is an asynchronous-service-call and if the timeout > 0
it is a synchronous-service-call.
service-call | blocking | timeout |
---|---|---|
synchronous | yes | timeout > 0 |
asynchronous | no | timeout == 0 |
blocking mean waiting max timeout seconds to finishing the service-call:
If an error was raised on the server during the service-processing… the following error-handling will be available
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
[in] | timeout | in seconds until a timeout-error is raised (possible values like ProcessEvent) (MK_TIMEOUT_DEFAULT=0 ) |
(runtime) enum MkErrorE MqSendEND_AND_CALLBACK(MQ_CTX const ctx, MQ_TOK const token, MqServiceCallbackF const fCall, MK_CBP callback, MK_TIME_T const timeout)
top finish the send-data-block, call the remote service, do not-wait for the result but expect the result on a callback … → API: MqSendEND_AND_CALLBACK_RT
This function will never block and return immediately. Usually multiple MqSendEND_AND_CALLBACK are send and finally multiple MqProcessEvent are called to wait for the results.
Example from route_mq.c
→ (C) call a service using a callback
Be aware of the followig limitatitions if multiple MqSendEND_AND_CALLBACK are called with different ctx:
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
[in] | fCall | the function to process the service-call results |
[in] | callback | a user defined additional data-argument for the callback function (C-API only) |
[in] | fFree | the function to free the data-argument after use (C-API only) |
[in] | timeout | in seconds until a timeout-error is raised (possible values like ProcessEvent) (MK_TIMEOUT_DEFAULT= 0) |
pTransSetResultCB
on return !! MqSendEND_AND_CALLBACK
: callback signature(runtime) enum MkErrorE MqSendEND_AND_SUB(MQ_CTX const ctx, MQ_TOK const token, MqServiceCallbackF const fCall, MK_CBP callback, MK_TIME_T timeout)
top finish the send-data-block, call the remote service, do wait for the result and expect multiple sub-results on a callback … → API: MqSendEND_AND_SUB_RT
The goal of this service-call is, to split a big data-block into multiple pieces. A typical solution would be a database-application doing a select and sending EVERY row as a (runtime) enum MkErrorE MqSendRETURN_SUB(MQ_CTX const ctx)
. At the end ONE final and EMPTY (runtime) enum MkErrorE MqSendRETURN(MQ_CTX const ctx)
is used to delete the open transaction and finish the service call.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
[in] | fCall | the function to process the service-call results |
[in] | callback | a user defined additional data-argument for the callback function (C-API only) |
[in] | fFree | the function to free the data-argument after use (C-API only) |
[in] | timeout | in seconds until a timeout-error is raised (possible values like ProcessEvent) (MK_TIMEOUT_DEFAULT=MK_TIMEOUT_USER ) |
(runtime) enum MkErrorE MqSendRETURN(MQ_CTX const ctx)
) is only called if the packet contains a data-item or on an error. If the packet is empty, only the transaction is closed.MqSendEND_AND_SUB
: callback signature(runtime) enum MkErrorE MqSendEND_AND_TRANSACTION(MQ_CTX const ctx, MQ_TOK const token, MQ_TOK const callback, MK_TIME_T timeout)
top finish the send-data-block, call the remote service to do a longterm-transaction-call … → API: MqSendEND_AND_TRANSACTION_RT
A longterm-transaction is a service-call with guaranteed delivery. guaranteed mean that the transaction is using the MqContextC STORAGE API to keep every step persistent being able to recover a step if something unexpected happen.
To link the result with the calling-environment a private transaction-item is used to save the calling-environment to the local-storage. If the local-storage is persistent, the calling-environment will even survive an application restart.
If the result from the public service-call arrives, the transaction-item will be extracted from the result and the private calling-environment will be initialized from the local-storage.
To create a persistent-transaction the MqContextC STORAGE API have to be setup as persistent. By default, an in-memory MqContextC STORAGE API is used.
The longterm-transaction-call has TWO results…
In difference to MqSendEND_AND_WAIT and MqSendEND_AND_CALLBACK a longterm-transaction-call have to survive an application restart. To achieve this goal… two features have to be available to process the results:
The transaction-item is the entry-id from the local internal database and is the public handle of the private data. If the transaction-item-private-data should be persistent (survive an application restart) the internal database have to be persistent using the Storage option.
The transaction-item-private-data requires a MqSendT_START … MqSendT_END at the beginning of the send-data-package.
The list of data-items in the transaction-item-private-data have to be provided by the programmer and is used to initialise the environment in the callback (for example an external database-entry-id).
In the transaction-callback the transaction-item-private-data have to be extracted with MqReadT_START … MqReadT_END at the beginning of the read-data-package.
The transaction-callback have to be a MqContextC_ServiceApi_Identifer defined with MqServiceCreate in the application setup code (like IServerSetup) and have to be available after an application restart.
If an error is raised on the server during the database-insert the function will return this error immediately. During waiting for the return the event-loop is used to process other events. Use IEvent to add your tasks into the event loop.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
[in] | callback | the MqContextC_ServiceApi_Identifer of the MqContextC_ServiceApi_Callback |
[in] | timeout | in seconds until a timeout-error is raised (possible values like ProcessEvent) (MK_TIMEOUT_DEFAULT=MK_TIMEOUT_USER ) |
Example from MyTransaction.c
→ make a logterm-transaction-call using the LOW and the HIGH api
#include "msgque_mq.h" static enum MkErrorE callback( MQ_SERVICE_CALL_ARGS ) { MqReadT_START_E(mqctx); MK_STRN myPrivateHandle = MqReadSTR_e(mqctx); MqReadT_END(mqctx); MK_I32 myServiceResult = MqReadI32_e(mqctx); fprintf(stdout,"myPrivateHandle=%s, myServiceResult=%d\n", myPrivateHandle, myServiceResult); fflush(stdout); error: return MkErrorStack_1M_Check(mqctx); } int main (int argc, MK_STRN argv[]) { MkRtSetup_NULL; MQ_CTX ctx = MqContextCreate(NULL,NULL); MqConfigSetName(ctx, "MyTransaction"); // setup commandline arguments used for parsing MK_BFL args = MkBufferListCreateVC(argc, argv); // check if the '--token' option is available, default "SRVC" MK_STRN token = MkBufferListCheckOptionSTR_e(args, "--token", "SRVC", true); // connect to the server MqLinkCreate_E(ctx, args); // register callback MqServiceCreate_E(ctx, "CLB1", callback, NULL, NULL, NULL); // send block using the LOW-Api MqSendSTART_E(ctx); MqSendT_START_E(ctx); MqSendSTR_E(ctx, "Privat_Data_1"); MqSendT_END_E(ctx); MqSendI32_E(ctx, 11111); MqSendEND_AND_TRANSACTION_E(ctx, token, "CLB1", MK_TIMEOUT_DEFAULT); // send block using the HIGN-Api -> same as above, but shorter char buffer[30]; sprintf(buffer, "%s:(C)I",token); MqSend_E(ctx, "T", "CLB1", buffer, "Privat_Data_2", 22222); // now we wait for exact ONE result of the "ctx" MqProcessEvent_E(ctx, MQ_WAIT_OWN, MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(args); // delete the context using the libmqmsgque APPLICATION-DTOR function "MqExit_1" MqExit_1(ctx); }
(runtime) enum MkErrorE MqSendEND_AND_WAIT(MQ_CTX const ctx, MQ_TOK const token, MK_TIME_T timeout)
top finish the send-data-block, call the remote service and wait for result… → API: MqSendEND_AND_WAIT_RT
If an error is raised on the server during the service-processing the function will return this error immediately. During waiting for the return the event-loop is used to process other events. Use IEvent to add your tasks into the event loop.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
[in] | timeout | in seconds until a timeout-error is raised (possible values like ProcessEvent) (MK_TIMEOUT_DEFAULT=MK_TIMEOUT_USER ) |
(runtime) enum MkErrorE MqSendSTART(MQ_CTX const ctx)
top initialize the send-data-package. … → API: MqSendSTART_RT
This function must be the first statement in a send-data-block.
If the socket is closed or failed, the connection is established with a MqLinkConnect.
Note that during MqLinkConnect the event-loop is called and your read-data-package may be invalid.
It is recommended to perform all READ operations first and then all SEND operations.
From MqSendSTART to MqSendEND is a send-data-block and no event-loop action is allowed between them.
The event-loop could modify the already started send-data-package and corrupt the data.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqSendSYNC(MQ_CTX const ctx)
top garantee that all pending asynchronous-service-calls are processed. … → API: MqSendSYNC_RT
The asynchronous-service-call is defined at: MqContextC_ServiceApi_C_API.
All service-calls to a specific ctx are queued in a service-call-pipeleine. The synchronous-service-call is blocking the service-call-pipeleine until the synchronous-service-call is finished. The asynchronous-service-call does NOT blocking the pipeline and so all asynchronous-service-call are processed in parallel. The MqSendSYNC is used if multiple asynchronous-service-calls are done to a single ctx and this ctx should be blocked until all asynchronous-service-calls are finished. The MqSendSYNC is just an normal blocking synchronous-service-call which is only finished after all asynchronous-service-calls are finished.
Example from perfclient.c
→ sending a bulk of asynchronous-sevice-requests
The last MqSendSYNC garantee the all previous asynchronous-service-calls are finished.
C-API: MqContextC_SendApi_Block_C_API - MqContextC - a wrapper to send a list-block or a transaction-block …
start to append an embedded body-list-item to the send-data-package. …
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqSendL_END(MQ_CTX const ctx)
top finish to append an embedded body-list-item to the send-data-package. … → API: MqSendL_END_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqSendL_START(MQ_CTX const ctx)
top start to append an embedded body-list-item to the send-data-package. … → API: MqSendL_START_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqSendT_END(MQ_CTX const ctx)
top closed a longterm-transaction-item … → API: MqSendT_END_RT
finish a setup-block started with MqSendT_START. read more at MqSendEND_AND_TRANSACTION.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqSendT_START(MQ_CTX const ctx)
top open a longterm-transaction-item … → API: MqSendT_START_RT
Every longterm-transaction-item have to be closed with MqSendT_END. Between MqSendT_START and MqSendT_END, a non specified number of other items can be added. These items are saved in a local database (in-memory or file-based) and the rowid is send as transaction-id to the link-target. By Default only the in-memory-database is used. To switch to a file-based database use the MqStorageOpen function.
Example from server.c
→ make a service-call with transaction-support
static enum MkErrorE Ot_TRNS ( MQ_SERVICE_CALL_ARGS ) { struct ServerCtxS *srvctx = (struct ServerCtxS*) mqctx; MK_I32 i; MqSendSTART_E (mqctx); MqSendT_START_E (mqctx); MqSendI32_E (mqctx, 9876); MqSendT_END_E (mqctx); MqReadI32_E (mqctx, &i); MqSendI32_E (mqctx, i); MqSendEND_AND_TRANSACTION_E (mqctx, "ECOI", "TRN2", MK_TIMEOUT_USER); MqProcessEvent_E (mqctx, MQ_WAIT_ONCE, 10); MqSendSTART_E (mqctx); MqSendI32_E (mqctx, srvctx->i); MqSendI32_E (mqctx, srvctx->j); error: return MqSendRETURN (mqctx); }
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
C-API: MqContextC_SendApi_Return_C_API - MqContextC - finish the send-data-block on the server and optional return the results. …
Every service-handler have to use this function at the end to return the results or the error. If an error is returned the local MkErrorC is reset. The following behaviour is used:
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqSendERROR(MQ_CTX const ctx)
top send the data from the MkErrorC to the link target . … → API: MqSendERROR_RT
If an error is available the error-number and the error-text is send to the link target. After send the error is reset. This function only raise an error if the sending self fails or the MkErrorDEFAULT is set and the ctx is a client-context.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqSendRETURN(MQ_CTX const ctx)
top MqContextC - finish the send-data-block on the server and optional return the results. … → API: MqSendRETURN_RT
Every service-handler have to use this function at the end to return the results or the error. If an error is returned the local MkErrorC is reset. The following behaviour is used:
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqSendRETURN_SUB(MQ_CTX const ctx)
top return Sub-Data-Blocks required by MqSendEND_AND_SUB … → API: MqSendRETURN_SUB_RT
Every service-handler CAN use this function at the end of a data block if the caller used MqSendEND_AND_SUB to initiate the service call. MqSendEND_AND_SUB will block until ithe final (runtime) enum MkErrorE MqSendRETURN(MQ_CTX const ctx)
was send.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
ServiceCreate | create a link between a service-token and a service-callback … | ||
ServiceDelete | delete a service. … | ||
ServiceIsTransaction | check if the ongoing-service-call belongs to a transaction … | ||
ServiceProxy | create a service to link a master-context with a slave-context. … | ||
ServiceProxyCtx | same as MqServiceProxy but use an MqContextC as input. | ||
ServiceProxyCtxExists | check if service who belongs to token is a proxy-service | ||
ServiceProxyRoundRobin | create a proxy-service using Round-Robin as load-balancer … | ||
ServiceStorage | setup a service listen on a MqContextC_ServiceApi_Identifer and save all read-data-package into the STORAGE … | ||
ServiceTokenCheck | in an ongoing-service-call check if the current MqContextC_ServiceApi_Identifer is token … | ||
ServiceTokenExists | check if the MqContextC_ServiceApi_Identifer token is defined as ctx service … | ||
ServiceTokenGet | in an ongoing-service-call get the current MqContextC_ServiceApi_Identifer … |
C-API: MqContextC_ServiceApi_C_API - MqContextC - create and manage a service …
To provide a service is the main purpose of a server and the main-purpose of a client/server connection is to call a service and to process the result.
A service can be defined on the server or on the client. On the server a service can be initial setup with IServerSetup method and finally cleanup with IServerCleanup.
A service is created with the MqServiceCreate and deleted with the MqServiceDelete.
A service can be created and deleted during the entire life-cycle of the server or the client. If the server/client-context is deleted all services of the are deleted also.
A MqServiceDelete is not required.
Creating or deleting a service is like granting or revoking the right to access a single feature.
eventloop
callback
Example from MyServer.c
→ define the service SRV1 on the server-link-setup
#include "common.h" // service to serve all incoming requests for token "HLWO" static enum MkErrorE MyFirstService ( MQ_SERVICE_CALL_ARGS ) { MqSendSTART_E (mqctx); MqSendV_E (mqctx, "%s World", MqReadSTR_e(mqctx)); error: return MqSendRETURN(mqctx); } // define a service as link between the token "HLWO" and the callback "MyFirstService" static enum MkErrorE ServerSetup ( MQ_SERVICE_CALL_ARGS ) { return MqServiceCreate(mqctx,"HLWO", MyFirstService, NULL, NULL, NULL); } // package-item enum MkErrorE MyServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { MQ_CTX const mqctx = *contextP = MqContextCreate(NULL,tmpl); MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); return MK_OK; } // package-main int main (int argc, MK_STRN argv[]) { MqRtSetup_NULL; // setup commandline arguments for later use MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; // create "MyServer" factory… and make it to the default. MqFactoryDefault( MqFactoryAdd_2(MyServerFactory, "MyServer")); // inspect commandline-argument for the "factory" to choose… and create a object MqFactoryNew_E (MqFactoryGetCalledL(largv), NULL, &mqctx); // start listen for incoming call's MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }
(runtime) enum MkErrorE MqServiceCreate(MQ_CTX const ctx, MQ_TOK const token, MqServiceCallbackF const fCall, MK_CBP callback)
top create a link between a service-token and a service-callback … → API: MqServiceCreate_RT
The servive-token (e.g. MqContextC_ServiceApi_Identifer) have to be unique but the service-callback (e.g. MqServiceCallbackF) not. If a service-callback is not unique than this is called an alias, use MQ_TOK MqServiceTokenGet(MQ_CTX const ctx)
to get the current token for an incoming-service-call.
The service-callback have to be callable by the server and/or by the child and/or the slave context. A static-callback is a good choice to achive this goal.
The filter, a slave-context, is setup with the initial factory using the initial-class (MqContextC) usually different from the server-class (MyServer…). The filter need the service-callback, usually shared with the server, to report a filter-message to the server.
To distinguish the server and the filter the following functions are used
(all function cann be called as either server or filter context):
ctx.SlaveGet(MASTER)
for the server ctx.SlaveGet(FILTER)
for the filter "if"
clause and the server check"if"
clause and the slave check
Example from Filter6.c
→ setup the services for server and filter
MqServiceCreate_E (mqctx, "LOGF", LOGF, NULL, NULL, NULL); MqServiceCreate_E (mqctx, "EXIT", EXIT, NULL, NULL, NULL); MqServiceCreate_E (mqctx, "SOEX", SOEX, NULL, NULL, NULL); MqServiceStorage_E (mqctx, "PRNT"); MqServiceStorage_E (mqctx, "PRN2"); MqServiceCreate_E (mqctx, "+ALL", FiIn, NULL, NULL, NULL); MqServiceCreate_E (ftr, "WRIT", WRIT, NULL, NULL, NULL); MqServiceCreate_E (mqctx, "WRIT", WRIT, NULL, NULL, NULL); MqServiceCreate_E (mqctx, "CLTI", CLTI, NULL, NULL, NULL); MqServiceProxy_E (ftr, "WRT2", MQ_SLAVE_MASTER);
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
[in] | fCall | the C-function to process the incoming service-request (C-API only) |
[in] | callback | the user defined callback as data-argument for the C-function fCall |
[in] | fFree | the function to free the data-argument after use (C-API only) |
[in] | fMark | the function to mark the data-argument during garbage-collection (C-API only) |
MqServiceCreate
: callback signature(runtime) enum MkErrorE MqServiceDelete(MQ_CTX const ctx, MQ_TOK const token)
top delete a service. … → API: MqServiceDelete_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
MK_BOOL MqServiceIsTransaction(MQ_CTX const ctx)
top check if the ongoing-service-call belongs to a transaction … → API: MqServiceIsTransaction
A service-call can be with-transaction (return MK_YES
if the package was send with MqSendEND_AND_WAIT or MqSendEND_AND_CALLBACK) or can be without-transaction (return MK_NO
if the package was send with MqSendEND)
[in] | ctx | the MqContextS instance to work on |
MK_YES
or MK_NO
(runtime) enum MkErrorE MqServiceProxy(MQ_CTX const ctx, MQ_TOK const token, MQ_SLAVE_ID const id)
top create a service to link a master-context with a slave-context. … → API: MqServiceProxy_RT
This function is used to create a proxy-service to forward the body-data from the read-data-package of the master to the send-data-package of the slave. The data is not changed. This function support the reverse-operation also. If the ctx is a master-context than the data is send to slave identified by id. If the ctx is a slave-context than the data is send to the master of the slave.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
[in] | id | the SlaveId to unique identify the master/slave link, the id < MQ_SLAVE_USER is internal. |
(runtime) enum MkErrorE MqServiceProxyCtx(MQ_CTX const ctx, MQ_TOK const token, MQ_CTX const target)
top same as MqServiceProxy but use an MqContextC as input. → API: MqServiceProxyCtx_RT
MK_BOOL MqServiceProxyCtxExists(MQ_CTX const ctx, MQ_TOK const token, MQ_CTX const target)
top check if service who belongs to token is a proxy-service → API: MqServiceProxyCtxExists
This is used for route (MqRouteDelete) to identify the service-usage
(runtime) enum MkErrorE MqServiceProxyRoundRobin(MQ_CTX const ctx, MQ_TOK const token, MK_STRN const ident)
top create a proxy-service using Round-Robin as load-balancer … → API: MqServiceProxyRoundRobin_RT
This function is used to create a proxy-service to forward the body-data from the read-data-package of the master-context to the send-data-package of the slave-context. The data is not changed. This function support the reverse-operation also. If the ctx is a master-context than the data is send to one of the slave-context identified by ident. If the ctx is a slave-context than the data is send to the master-context of the slave.
The Round-Robin-Load-Balancer is only used for the direction from the master-context to the slave-context if the name-resolution return multiple target-context for the single ident.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
[in] | ident | the targetIdent used to select a list slave-Context for the Round-Robin |
(runtime) enum MkErrorE MqServiceStorage(MQ_CTX const ctx, MQ_TOK const token)
top setup a service listen on a MqContextC_ServiceApi_Identifer and save all read-data-package into the STORAGE … → API: MqServiceStorage_RT
In a shortterm-transaction-synchronous-service-call the service will return an empty data package. In a longterm-transaction-synchronous-service-call the data will return as normal.
Example from Filter6.c
→ using MqServiceStorage to store all packages from service PRNT
and PRN2
into database
MqServiceCreate_E (mqctx, "LOGF", LOGF, NULL, NULL, NULL); MqServiceCreate_E (mqctx, "EXIT", EXIT, NULL, NULL, NULL); MqServiceCreate_E (mqctx, "SOEX", SOEX, NULL, NULL, NULL); MqServiceStorage_E (mqctx, "PRNT"); MqServiceStorage_E (mqctx, "PRN2"); MqServiceCreate_E (mqctx, "+ALL", FiIn, NULL, NULL, NULL); MqServiceCreate_E (ftr, "WRIT", WRIT, NULL, NULL, NULL); MqServiceCreate_E (mqctx, "WRIT", WRIT, NULL, NULL, NULL); MqServiceCreate_E (mqctx, "CLTI", CLTI, NULL, NULL, NULL); MqServiceProxy_E (ftr, "WRT2", MQ_SLAVE_MASTER);
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
MK_BOOL MqServiceTokenCheck(MQ_CTX const ctx, MQ_TOK const token)
top in an ongoing-service-call check if the current MqContextC_ServiceApi_Identifer is token … → API: MqServiceTokenCheck
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
MK_YES
or MK_NO
MK_BOOL MqServiceTokenExists(MQ_CTX const ctx, MQ_TOK const token)
top check if the MqContextC_ServiceApi_Identifer token is defined as ctx service … → API: MqServiceTokenExists
This code is used to detect if a service with identifer token exists.
[in] | ctx | the MqContextS instance to work on |
[in] | token | the MqContextC SERVICE API to identify the service |
MK_YES
or MK_NO
MQ_TOK MqServiceTokenGet(MQ_CTX const ctx)
top in an ongoing-service-call get the current MqContextC_ServiceApi_Identifer … → API: MqServiceTokenGet
This function is needed on the server to process a service-request defined as +ALL
or as an alias to extract the current MqContextC_ServiceApi_Identifer.
[in] | ctx | the MqContextS instance to work on |
SlaveCheck | check if slave-id is valid | ||
SlaveCreate | create a master/slave link between the master-parent-context and the slave-parent-context … | ||
SlaveDelete | Delete a slave object from a master/slave link identified by id. … | ||
SlaveGet | get the slave-context from a master-context … | ||
SlaveGetFilter | get the filter-ctx or the master-ctx … | ||
SlaveGetMaster | opposite function of MqSlaveGetFilter | ||
SlaveGetProxy | on slave return the master and on master return the slave identified by id. | ||
SlaveIs | is the context a slave-context ? … | ||
SlaveWorker | create a master/slave link using the image of the ctx object self. … |
C-API: MqContextC_SlaveApi_C_API - MqContextC - create and manage a slave context …
The master-slave-link is used to create a mesh of nodes defined by different parent-context. The master control the slave.
The master-slave-link is used to perform the following tasks:
In difference to the client-server-link the master-slave-link connect two independent parent-context in the same process or thread (e.g. node). This leads to the restriction that only the master-context can be a server-context because only one server-context per node is possible.
node-0 | node-1/2 | node-3/4/5 =================================================================== | <- client/server link -> | <- client/server link -> | | <-- master/slave link --> | |- client1-0 -|- server3 ... |- server1 -| | |- client1-1 -|- server4 ... client0-0 -| |- server2 -|- client1-2 -|- server5 ...
Definition of the "master-context"
Definition of the "slave-context"
0
.Definition of the "worker-context"
0
./etc/services
0
slave-id | value | definition |
---|---|---|
MQ_SLAVE_MAX | 1024 | internal: the maximum slave-id … . |
MQ_SLAVE_USER | 10 | internal: start of user-defined-slave-id . |
MQ_SLAVE_LOOPBACK | 0 | internal: the loopback-slave-id, (call my own services) . |
MQ_SLAVE_FILTER | 1 | internal: the filter-slave-id, (on a master get the filter-slave) . |
MQ_SLAVE_MASTER | 1 | internal: the master-slave-id, (on a slave get the master) . |
MQ_SLAVE_OTHER | 1 | internal: on the master-ctx get the slave-ctx and on the slave-ctx get the master-ctx . |
range | definition |
---|---|
0 <= slave-id < MQ_SLAVE_MAX | range of valid slave-id's |
0 <= slave-id < MQ_SLAVE_USER | internale usage |
MQ_SLAVE_USER <= slave-id < MQ_SLAVE_MAX | external usage |
Definition of the "LOOPBACK" (0) slave
client | server | =========================================== | <--- client/server ---> | <-- loop --> | | <------ master/slave -----> | client -- | -- server -- | -- client -- # == == # server -- | -- client -- #
slave-id = 0
. MyLoopServer.c
→ create a new loop-server #include "common.h" // [MyLoopServerC_Define] typedef struct MyLoopServerS { struct MqContextS mqctx; ///< link to the \libmqmsgque object #define mydata_size 30 char mydata[mydata_size]; ///< define the "mydata" attribute } MyLoopServerC; // [MyLoopServerC_Define] // the MyLoopServerC class-type static MkThreadLocal MK_TYP MyLoopServerCTT = NULL; // service to serve all EXTERNAL requests for token "HLWO" static enum MkErrorE HLWO_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "loopback" context MQ_CTX loop = MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK); // call the LOOP service on the SAME server MqSend_E(loop,"W","LOOP"); // answer HLWO with string-return from LOOP MqSend_E(mqctx, "R", "C", MqReadSTR_e(loop)); return MK_OK; error: return MqSendRETURN(mqctx); } // service to serve all INTERNAL requests for token "LOOP static enum MkErrorE LOOP_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "master" context MyLoopServerC* master = (MyLoopServerC*)MqSlaveGetMaster(mqctx); // answer LOOP with data from MASTER->mydata attribute return MqSend(mqctx, "R", "C", master->mydata); } // define a service as link between the token "HLWO" and the callback "HLWO_srv" static enum MkErrorE ServerSetup ( MQ_SERVICE_CALL_ARGS ) { // EXTERNAL: link the "HLWO" service with "HLWO_srv" MqServiceCreate_E(mqctx, "HLWO", HLWO_srv, NULL, NULL, NULL); // INTERNAL: link the "LOOP" service with "LOOP_srv" MqServiceCreate_E(MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK), "LOOP", LOOP_srv, NULL, NULL, NULL); return MK_OK; error: return MkErrorStack_1X(mqctx); } // [MyLoopServerC_Create] enum MkErrorE MyLoopServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { // create new instance using the MyLoopServerCTT class-type MQ_CTX const mqctx = *contextP = MqContextCreate(MyLoopServerCTT,tmpl); // initialize the new context MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); // cast the libmqmsgque-context into the MyLoopServerC-context MyLoopServerC* mqctxC = (MyLoopServerC*)mqctx; // initialize the "mydata" attribute strncpy(mqctxC->mydata,"Hello World",mydata_size); mqctxC->mydata[mydata_size-1] = '\0'; return MK_OK; } // [MyLoopServerC_Create] int main (int argc, MK_STRN argv[]) { MqRtSetup_NULL; // [MyLoopServerC_Init] // initialize the MyLoopServer class-type with existing MqContextC_TT class-type MyLoopServerCTT = MkTypeDup2(MqContextC_TT,"MyLoopServerC"); MyLoopServerCTT->objsize = sizeof(struct MyLoopServerS); // [MyLoopServerC_Init] // setup commandline arguments for later use MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; // create "MyLoopServer" factory… and make it to the default. MqFactoryDefault(MqFactoryAdd_2(MyLoopServerFactory,"MyLoopServer")); // inspect commandline-argument for the "factory" to choose… and create a object MqFactoryNew_E (MqFactoryGetCalledL(largv), NULL, &mqctx); // start listen for incoming call's MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }
Performance analyse
Nhi1Exec perfclient.c --parent --wrk ? @ perfserver.c
Nhi1Exec -r=uds perfserver.c --spawn|fork|thread
Nhi1Exec -r=uds perfclient.c --parent --wrk ?
perfclient worker perfserver ========== ====== ========== | |- loop --wrk x |- MqSlaveWorker(...) -> worker[1] |- MqSend(worker[1],"E","STR0..") -> PerfWorker_I160(...) |- loop endless |- MqContextCreate(...) |- MqLinkCreate(...) <-> MqContextCreate(...) |- MqContextDelete(...) <-> MqContextDelete(...) |- sleep x sec |- loop --wrk x |- MqSend(worker[1],"C"..,"END0") -> PerfWorker_END0(...) | |- stop loop |- "callback" - add number to all <- |- return #context
setup | –wrk | # worker-context | performance | info |
---|---|---|---|---|
pipe | 1 | 2500 | 1000 | the pipe start a new worker-context with spawn |
spawn | 1 | 2500 | <1000 | same as pipe but use network-protocoll |
fork | 1 | 3800 | 4000 | the fork is faster than spawn |
thread | 1 | 16500 | 9000 | the thread is faster than fork |
pipe | 4 | 8000 | 4500 | the worker scale linear up to number of processors |
spawn | 4 | 7600 | <4500 | - |
fork | 4 | 23200 | 11500 | - |
thread | 4 | 55500 | 27500 | - |
pipe | 8 | 10000 | 5500 | the additional scaling up to the max hyper-threading does not really help |
spawn | 8 | 9100 | <5500 | - |
fork | 8 | 23200 | 11500 | - |
thread | 8 | 55500 | 27500 | - |
MK_BOOL MqSlaveCheck(MQ_CTXN const ctx, MQ_SLAVE_ID const id)
top check if slave-id is valid → API: MqSlaveCheck
[in] | ctx | the master-context as PARENT or CHILD |
[in] | id | the SlaveId to unique identify the master/slave link, the id < MQ_SLAVE_USER is internal. |
true
= valid or false
= invalid (runtime) enum MkErrorE MqSlaveCreate(MQ_CTX const ctx, MQ_SLAVE_ID const id, MQ_CTX const slave)
top create a master/slave link between the master-parent-context and the slave-parent-context … → API: MqSlaveCreate_RT
The slave-context have to be a sub-class of MqContextC and is owned by the master-context. Owned mean that no other external references should be used.
The slave-context will be deleted if the master-context is deleted and the slave-context will create a child-context if the master-context create a child context.
Example from server.cs
→ with reflection support... only the class is required :
Example from server.cc
→ without reflection support... the factory is required :
and the factory is used to create the object :
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the master context object as PARENT without a CHILD |
[in] | id | the SlaveId to unique identify the master/slave link, the id < MQ_SLAVE_USER is internal. |
[in] | slave | the slave context object as CLIENT-PARENT without a CHILD |
(runtime) enum MkErrorE MqSlaveDelete(MQ_CTX const ctx, MQ_SLAVE_ID const id)
top Delete a slave object from a master/slave link identified by id. … → API: MqSlaveDelete_RT
By default the slave-context object will be deleted if the master-context is deleted. Use this function to delete the parent-slave-context explicit and brake the master/slave link. If id is invalid nothing will happen. It is an error to delete a child-slave-context.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the master context object as PARENT without a CHILD |
[in] | id | the SlaveId to unique identify the master/slave link, the id < MQ_SLAVE_USER is internal. |
(runtime) enum MkErrorE MqSlaveGet(MQ_CTX const ctx, MQ_SLAVE_ID const id, MQ_CTX *ctx_out)
top get the slave-context from a master-context … → API: MqSlaveGet_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the master-context as PARENT or CHILD |
[in] | id | the SlaveId to unique identify the master/slave link, the id < MQ_SLAVE_USER is internal. |
[out] | ctx_out | the slave-context or MK_NULL on error |
(runtime) enum MkErrorE MqSlaveGetFilter(MQ_CTX const ctx, MQ_CTX *ctx_out)
top get the filter-ctx or the master-ctx … → API: MqSlaveGetFilter_RT
The functions MqSlaveGetFilter, MqSlaveGetMaster and MqSlaveGetProxy have the same purpose. A filter-pipeline has two ctx, one on the left and one on the right. The left-ctx is linked with the master-ctx and the right-ctx is linked to the slave-ctx. This function return the ctx wanted or an error if NOT available. The search is done using the following order:
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | ctx_out | the ctx or MK_NULL on error |
MQ_CTX MqSlaveGetMaster(MQ_CTX const ctx)
top opposite function of MqSlaveGetFilter → API: MqSlaveGetMaster
MK_NULL
is returned (runtime) enum MkErrorE MqSlaveGetProxy(MQ_CTX const ctx, MQ_SLAVE_ID const id, MQ_CTX *ctx_out)
top on slave return the master and on master return the slave identified by id. → API: MqSlaveGetProxy_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the master or slave-context as PARENT or CHILD |
[in] | id | the SlaveId to unique identify the master/slave link, the id < MQ_SLAVE_USER is internal. |
[out] | ctx_out | the other-context or MK_NULL on error |
MK_BOOL MqSlaveIs(MQ_CTXN const ctx)
top is the context a slave-context ? … → API: MqSlaveIs
[in] | ctx | the MqContextS instance to work on |
MK_YES
or MK_NO
(runtime) enum MkErrorE MqSlaveWorker(MQ_CTX const ctx, MQ_SLAVE_ID const id, MK_STRN fct, MK_BAC args)
top create a master/slave link using the image of the ctx object self. … → API: MqSlaveWorker_RT
The slave-context is started as an independent process or thread based on the StartAs argument.
The start of a "worker" can be done at:
Example from server.c
→ create a worker in a service-callback reading arguments from the service
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the master context object as PARENT without a CHILD |
[in] | id | the SlaveId to unique identify the master/slave link, the id < MQ_SLAVE_USER is internal. |
[in] | fct | the MqFactoryS::originalIdent or MK_NULL or '\0' or "WORKER" . if ident is MK_NULL or '\0' or WORKER the factory of ctx will be used if ident is MqFactoryS::originalIdent the factory defined will be used |
[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: --debug 5 --name hello @ --name myserver |
StorageClose | close the storage. … | ||
StorageCount | count the number of storage-rows … | ||
StorageDecrRef | decrease the internal refCount lock of the database-entry | ||
StorageDelete | delete the storage-row identified by the transLIdP_inout … | ||
StorageErrCnt | increment and return the database row-error-count for the row defined with transLId | ||
StorageExport | export the read-data-package into the STORAGE … | ||
StorageImport | import the storage-package into the read-data-package … | ||
StorageIncrRef | increase the internal refCount lock of the database-entry | ||
StorageLog | log the storage the status of the open transactions | ||
StorageOpen | switch to a file-based-transaction-database … | ||
StorageResolve | extract the |
C-API: MqContextC_StorageApi_C_API - MqContextC - setup and manage a storage used to persist data-packages …
The storage is divided into: INTERNAL and EXTERNAL storage. Only the read-data-package can be stored or dumped into the storage.
The read-data-package is saved into the storage using:
ServiceStorage | setup a service listen on a MqContextC_ServiceApi_Identifer and save all read-data-package into the STORAGE … |
StorageExport | export the read-data-package into the STORAGE … |
The read-data-package is restored from the storage using:
StorageImport | import the storage-package into the read-data-package … |
ProxyForward | send the entire read-data-package-data to the link-target … |
All this usually happen in an Event Handler |
Some important facts of the storage-feature:
The following internal storages are supported:
Performance analyse:
Nhi1Exec perfclient.c --all --storage VALUE @ perfserver.c
.database | performance | host crash | application crash | info |
---|---|---|---|---|
memdb | 30.000 | data lost | data lost | non persistent |
tempdb | < 30.000 | data lost | data lost | uses memory and/or temporary file |
filedb (mem) | 10.000 | data lost | data safe | in memory filesystem |
filedb (disc) | 50 | data safe | data safe | disc-speed is the key factor |
(runtime) enum MkErrorE MqStorageClose(MQ_CTX const ctx)
top close the storage. … → API: MqStorageClose_RT
the next storage request will open the storage again with the location from Storage
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
(runtime) enum MkErrorE MqStorageCount(MQ_CTX const ctx, MQ_LTR *cnt_out)
top count the number of storage-rows … → API: MqStorageCount_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | cnt_out | number of rows, OLL if nothing is available |
(runtime) enum MkErrorE MqStorageDecrRef(MQ_CTX const ctx, MQ_LTR transLId)
top decrease the internal refCount lock of the database-entry → API: MqStorageDecrRef_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | transLId | storage-id … return from MqStorageImport |
(runtime) enum MkErrorE MqStorageDelete(MQ_CTX const ctx, MQ_LTR *transLIdP_inout)
top delete the storage-row identified by the transLIdP_inout … → API: MqStorageDelete_RT
The transLIdP_inout is the value returned by a previous MqStorageImport. If transLIdP_inout is MK_NULL
than OLL
is used. MqStorageImport and MqStorageDelete work together link an transaction and every successfull transcation have to delete the transLIdP_inout out of the storage. After sucessfull delete the transLIdP_inout is set to 0LL
, on error the initial value is unchanged.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in,out] | transLIdP_inout | pointer to storage-id to delete, will be 0LL on success |
(runtime) enum MkErrorE MqStorageErrCnt(MQ_CTX const ctx, MQ_LTR transLId, MK_I32 *cnt_out)
top increment and return the database row-error-count for the row defined with transLId → API: MqStorageErrCnt_RT
The storage is typical used in the following workflow:
<----- AT CALLING CLIENT ----->|<----- AT RECEIVING SERVER -----> | *setup transaction | make service-request --> *start service-handler | save request into storage wait for confirmation <-- confirm data receiving | *stop service-handler ==================== enter event loop ===================== | *start event-handler | load reqest from storage | process data *start transaction <-- send result-data process result-data | *stop event-handler *stop transaction |
Example Filter6 - store incoming packages into storage
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | transLId | storage-id … return from MqStorageImport |
[out] | cnt_out | the new value or -1 on error |
(runtime) enum MkErrorE MqStorageExport(MQ_CTX const ctx, MQ_LTR *ltid_out)
top export the read-data-package into the STORAGE … → API: MqStorageExport_RT
The export include all data required to setup a read-data-package later again. After import with MqStorageImport the read-data-package and the environment will be set as it was on MqStorageExport
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | ltid_out | if ltid_out != NULL return the storage-id |
(runtime) enum MkErrorE MqStorageImport(MQ_CTX const ctx, MQ_LTR *transLIdP_inout)
top import the storage-package into the read-data-package … → API: MqStorageImport_RT
Select the read-data-package from the database using the transLIdP. Only a package with refCount = 0
will be selected.
After selection the refCount is incremented and the next call to MqStorageImport using the same transLId will fail.
MqStorageImport is used together with MqStorageDelete or MqStorageDecrRef to delete the selected package from database or to undo the select.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) | ||||||||||
[in] | ctx | the MqContextS instance to work on | ||||||||||
[in,out] | transLIdP_inout | storage-id or MK_NULL or 0 … return from MqStorageExport
|
refCount=0
) with the smallest transLId
is read.refCount
is not reset or the package is not deleted, then the package remains locked and a subsequent call to MqStorageImport will read the next free package.(runtime) enum MkErrorE MqStorageIncrRef(MQ_CTX const ctx, MQ_LTR transLId)
top increase the internal refCount lock of the database-entry → API: MqStorageIncrRef_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | transLId | storage-id … return from MqStorageImport |
(runtime) enum MkErrorE MqStorageLog(MQ_CTX const ctx, MK_STRN const callfunc)
top log the storage the status of the open transactions → API: MqStorageLog_RT
(runtime) enum MkErrorE MqStorageOpen(MQ_CTX const ctx, MK_STRN const storageFile)
top switch to a file-based-transaction-database … → API: MqStorageOpen_RT
the value can also be set using the --storage
commandline option.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[in] | storageFile | the file used to create the transaction-database. Allowed values are:
|
(runtime) enum MkErrorE MqStorageResolve(MQ_CTX const ctx, MQ_CTX *otherCtxP_out, MQ_LTR *otherLIdP_out)
top extract the context->link.protect.rmtTransLId
entry from the database → API: MqStorageResolve_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the MqContextS instance to work on |
[out] | otherCtxP_out | the ctx of the resolve |
[out] | otherLIdP_out | the transLId of the resolve |
libmqmsgque is using a class-attribute as instance-storage.
To create a new instance-storage 3 steps are reqired:
typedef struct MyLoopServerS { struct MqContextS mqctx; ///< link to the \libmqmsgque object #define mydata_size 30 char mydata[mydata_size]; ///< define the "mydata" attribute } MyLoopServerC;
// initialize the MyLoopServer class-type with existing MqContextC_TT class-type MyLoopServerCTT = MkTypeDup2(MqContextC_TT,"MyLoopServerC"); MyLoopServerCTT->objsize = sizeof(struct MyLoopServerS);
enum MkErrorE MyLoopServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { // create new instance using the MyLoopServerCTT class-type MQ_CTX const mqctx = *contextP = MqContextCreate(MyLoopServerCTT,tmpl); // initialize the new context MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); // cast the libmqmsgque-context into the MyLoopServerC-context MyLoopServerC* mqctxC = (MyLoopServerC*)mqctx; // initialize the "mydata" attribute strncpy(mqctxC->mydata,"Hello World",mydata_size); mqctxC->mydata[mydata_size-1] = '\0'; return MK_OK; }
Example from MyLoopServer.c
→ create and access class-attribute mydata as instance-storage
#include "common.h" // [MyLoopServerC_Define] typedef struct MyLoopServerS { struct MqContextS mqctx; ///< link to the \libmqmsgque object #define mydata_size 30 char mydata[mydata_size]; ///< define the "mydata" attribute } MyLoopServerC; // [MyLoopServerC_Define] // the MyLoopServerC class-type static MkThreadLocal MK_TYP MyLoopServerCTT = NULL; // service to serve all EXTERNAL requests for token "HLWO" static enum MkErrorE HLWO_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "loopback" context MQ_CTX loop = MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK); // call the LOOP service on the SAME server MqSend_E(loop,"W","LOOP"); // answer HLWO with string-return from LOOP MqSend_E(mqctx, "R", "C", MqReadSTR_e(loop)); return MK_OK; error: return MqSendRETURN(mqctx); } // service to serve all INTERNAL requests for token "LOOP static enum MkErrorE LOOP_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "master" context MyLoopServerC* master = (MyLoopServerC*)MqSlaveGetMaster(mqctx); // answer LOOP with data from MASTER->mydata attribute return MqSend(mqctx, "R", "C", master->mydata); } // define a service as link between the token "HLWO" and the callback "HLWO_srv" static enum MkErrorE ServerSetup ( MQ_SERVICE_CALL_ARGS ) { // EXTERNAL: link the "HLWO" service with "HLWO_srv" MqServiceCreate_E(mqctx, "HLWO", HLWO_srv, NULL, NULL, NULL); // INTERNAL: link the "LOOP" service with "LOOP_srv" MqServiceCreate_E(MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK), "LOOP", LOOP_srv, NULL, NULL, NULL); return MK_OK; error: return MkErrorStack_1X(mqctx); } // [MyLoopServerC_Create] enum MkErrorE MyLoopServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { // create new instance using the MyLoopServerCTT class-type MQ_CTX const mqctx = *contextP = MqContextCreate(MyLoopServerCTT,tmpl); // initialize the new context MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); // cast the libmqmsgque-context into the MyLoopServerC-context MyLoopServerC* mqctxC = (MyLoopServerC*)mqctx; // initialize the "mydata" attribute strncpy(mqctxC->mydata,"Hello World",mydata_size); mqctxC->mydata[mydata_size-1] = '\0'; return MK_OK; } // [MyLoopServerC_Create] int main (int argc, MK_STRN argv[]) { MqRtSetup_NULL; // [MyLoopServerC_Init] // initialize the MyLoopServer class-type with existing MqContextC_TT class-type MyLoopServerCTT = MkTypeDup2(MqContextC_TT,"MyLoopServerC"); MyLoopServerCTT->objsize = sizeof(struct MyLoopServerS); // [MyLoopServerC_Init] // setup commandline arguments for later use MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; // create "MyLoopServer" factory… and make it to the default. MqFactoryDefault(MqFactoryAdd_2(MyLoopServerFactory,"MyLoopServer")); // inspect commandline-argument for the "factory" to choose… and create a object MqFactoryNew_E (MqFactoryGetCalledL(largv), NULL, &mqctx); // start listen for incoming call's MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }
MqDumpC CLASS | |||
Define | MqDumpC - low level definition, access and cast … | ||
Export | MqDumpC - Export class functions … | ||
Introspection | MqDumpC - Introspection class functions … | ||
Misc | MqDumpC - Misc class functions … | ||
MqDumpC TOR | |||
Export | create a MqDumpC as export of the ctx-read-data-package … | ||
BinSet | create an MqDumpS object from binary data | ||
Error | export the context->error into the dump-package … | ||
Delete | Destructor - delete a MqDumpC instance … | ||
BinGet | export the binary data from an MqDumpS object | ||
Import | import the dump-package into the ctx-read-data-package … | ||
MqDumpC MISC | |||
Log | log the MqDumpC … | ||
SizeGet | report the binary data size from an MqDumpS object | ||
TokenGet | return the MqContextC_ServiceApi_Identifer … |
C-API: MqDumpC_C_API - MqDumpC - the class known as dmp or dump is used to export a libmqmsgque data package as binary …
The dump is used to exchange data with external counterparts such as a database or a user-specific infrastructure.
There are 3 different function that deal with a dump:
Dmp | cast a unknown-object into an MqDumpS pointer or NULL if not possible | ||
DmpCheck | check MqDumpS -> MkObjectS::signature … | ||
DmpCheckO | check MqDumpS -> MkObjectS::signature … | ||
DmpN | (const) cast a unknown-object into an MqDumpS pointer or NULL if not possible |
HandleResolve | Handle-Resolve-Slot - return a MqDumpC from netHdl or MK_NULL if invalid… | ||
HandleGet | Handle-Get-Slot - returns a export-hdl to the MqDumpC useable for external storage |
Instances | get head-instance from linked-list of MqDumpS type … | ||
Next | get next instance from linked-list of MqDumpS type | ||
Prev | get previous instance from linked-list of MqDumpS type |
GetNull | Null-Slot - return a MqDumpC typed |
C-API: MqDumpC_Class_C_API - MqDumpC - define the class …
C-API: MqDumpC_Class_Define_C_API - MqDumpC - low level definition, access and cast …
(static,hide) MQ_DMP MqDmp(MK_MNG mng)
top cast a unknown-object into an MqDumpS pointer or NULL if not possible → API: MqDmp
(static,hide) MK_BOOL MqDmpCheck(MK_MNGN mng)
top check MqDumpS -> MkObjectS::signature … → API: MqDmpCheck
(static,hide) MK_BOOL MqDmpCheckO(MK_OBJN obj)
top check MqDumpS -> MkObjectS::signature … → API: MqDmpCheckO
(static,hide) MQ_DMPN MqDmpN(MK_MNGN mng)
top (const) cast a unknown-object into an MqDumpS pointer or NULL if not possible → API: MqDmpN
MqDumpC - Export class functions …
(static,runtime) MQ_DMP MqDumpHandleResolve(MK_HDL const netHdl)
top Handle-Resolve-Slot - return a MqDumpC from netHdl or MK_NULL
if invalid… → API: MqDumpHandleResolve_RT
The MqDumpHandleResolve undo the MqDumpHandleGet and is intended to export a unique identifer into external code not belonging to the Programming-Language-Micro-Kernel (PLMK).
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | netHdl | handle former exported with MqDumpHandleGet |
MK_NULL
if netHdl is invalid (runtime) MK_HDL MqDumpHandleGet(MQ_DMP const dmp)
top Handle-Get-Slot - returns a export-hdl to the MqDumpC useable for external storage → API: MqDumpHandleGet_RT
The export-hdl is a reference to an instance that can be stored in software and converted back into an instance using the MqDumpHandleResolve.
The export-hdl is only valid until the Programming-Language-Micro-Kernel (PLMK) ends.
example: The export-hdl is used in rpc to identify an object across the network.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | dmp | the MqDumpS instance to work on |
MqDumpC - Introspection class functions …
(static,runtime) MQ_DMP MqDumpInstances()
top get head-instance from linked-list of MqDumpS type … → API: MqDumpInstances_RT
The head-instance is the last instance created.
MQ_DMP MqDumpNext(MQ_DMP const dmp)
top get next instance from linked-list of MqDumpS type → API: MqDumpNext
MQ_DMP MqDumpPrev(MQ_DMP const dmp)
top get previous instance from linked-list of MqDumpS type → API: MqDumpPrev
MqDumpC - Misc class functions …
(static) MQ_DMP MqDumpGetNull()
top Null-Slot - return a MqDumpC typed NULL
instance … → API: MqDumpGetNull
C-API: MqDumpC_TOR_C_API - MqDumpC - various functions to create, initialize and destroy a dump …
(constructor,static,runtime) enum MkErrorE MqDumpExport(MQ_CTX const ctx, MQ_DMP const dumpP_inout)
top create a MqDumpC as export of the ctx-read-data-package … → API: MqDumpExport_RT
The new instance belongs to the caller and may have to be released if necessary. A manual release using DumpDelete is always possible, but the instance can no longer be used afterwards.
The export include all data required to setup a read-data-package again later. After import with MqDumpImport the read-data-package and the environment will be set as it was on MqDumpExport The export can be saved into an external storage or be used in a network-tunnel (example: the aguard tool).
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | ctx | the context to be exported into the dump-package-data |
[in,out] | dumpP_inout | returns |
MK_NULL
or a result of a previous MqDumpExport or MqDumpError.MK_NULL
or garbage … new memory will be allocated… If the dump memory will NOT be reused… free the memory with (6.)(constructor,static,runtime) enum MkErrorE MqDumpBinSet(MkBinaryR data, MQ_DMP *dmp_out)
top create an MqDumpS
object from binary data → API: MqDumpBinSet_RT
Check the MqDumpC_SIGNATURE and set the refCount to 0
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | data | the binary data |
[out] | dmp_out | the new MqDumpC |
MqDumpS
object is an pointer object… this mean the original data is still required and must NOT be freed.(constructor,static,runtime) enum MkErrorE MqDumpError(MQ_CTX const error, MQ_DMP const dumpP_inout)
top export the context->error into the dump-package … → API: MqDumpError_RT
The export include all data required to setup a read-data-package later again. After import with MqDumpImport the read-data-package and the environment will be set as it was on MqDumpExport The export can be saved into an external storage or be used in a network-tunnel (example: the agurad tool).
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | error | the error-context to be exported into the dump-package-data |
[in,out] | dumpP_inout | the dump-error-package-data to save |
(destructor,runtime) void MqDumpDelete(MQ_DMP dmp)
top Destructor - delete a MqDumpC instance … → API: MqDumpDelete_RT
MkBinaryR MqDumpBinGet(MQ_DMPN const dump)
top export the binary data from an MqDumpS
object → API: MqDumpBinGet
[in] | dump | the source object |
MqDumpS
object… do NOT free.(runtime) enum MkErrorE MqDumpImport(MQ_DMP const dump, MQ_CTX const ctx)
top import the dump-package into the ctx-read-data-package … → API: MqDumpImport_RT
The dump is the result of a previous MqDumpExport function call. After the load an package is suitable for all kind of MqContextC READ API function. To just forward the package use the MqProxyForward function.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | dump | the dump-package to be imported |
[in] | ctx | the context in wich the dump-package is imported |
MK_NULL
for a non-error result.C-API: MqDumpC_Misc_C_API - MqDumpC - various functions to work on a dump …
(runtime) void MqDumpLog(MQ_DMP const dmp, MK_OBJ fmtobj, MK_I32 const debug, MK_STRN const callfunc, MK_I32 const lvl)
top log the MqDumpC … → API: MqDumpLog_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | dmp | the MqDumpS instance to work on |
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | lvl | a user-defined prefix starting with "" for lvl=0 and increase with " " for lvl+1 (default=0 ) |
MK_SIZE MqDumpSizeGet(MQ_DMPN const dump)
top report the binary data size from an MqDumpS
object → API: MqDumpSizeGet
[in] | dump | the source object |
MK_STRN MqDumpTokenGet(MQ_DMPN const dump)
top return the MqContextC_ServiceApi_Identifer … → API: MqDumpTokenGet
MqFactoryC CLASS | |||
Define | MqFactoryC - low level definition, access and cast … | ||
Export | MqFactoryC - Export class functions … | ||
Introspection | MqFactoryC - Introspection class functions … | ||
Misc | MqFactoryC - Misc class functions … | ||
MqFactoryC TOR | |||
Add | add a new MqFactoryC identified by factory-identifier and defined by factory-constructor … | ||
Delete | Destructor - delete a MqFactoryC instance … | ||
Dup2 | create a duplicate of the singleton object MqFactoryC using a new factory-identifer | ||
Free | free internal factory memory and call MqFactoryDTorS::fFree + MqFactoryCTorS::fFree | ||
MqFactoryC GET | |||
Get | return the MqFactoryC | ||
GetCalled | returns the MqFactoryC identified by ident … | ||
GetCalledL | returns the MqFactoryC identified as first argument in the largs MkBufferListC … | ||
GetOriginalIdent | helper function to return MqFactoryS::originalIdent | ||
ItemGetCreateData | helper function to return MqFactoryS::Create::data | ||
MqFactoryC MISC | |||
DefaultIdent | return the factory-identifier of the default MqFactoryC | ||
InitialIdent | return the factory-identifier of the initial MqFactoryC | ||
LogAll | log all "factories" to stderr | ||
Default | set the default-attribute to the factory … | ||
Initial | set the initial-attribut to fct … | ||
Log | log the MqFactoryC … | ||
New | create a new MqContextC from a MqFactoryC … |
C-API: MqFactoryC_C_API - MqFactoryC - the class known as fct or factory is used to provide an interface to create one or more new MqContextC …
The factory is an important part of the object management and has the following basic features:
Without a factory only the pipe-feature without the child-feature is guaranteed to work. Other features may work, this depends of the "flexibility" of the programming-language.
The link between the MqFactoryS-identifier and the MqFactoryC is important for the future development of libmqmsgque. Message-Routing, Service-Location and Persistent-Transactions depend on this feature.
The relationship between the MqFactoryC and the MqContextC is the same as the relationship between a type (MqFactoryS) and an object (MqContextS) of a regular programming language. The MqFactoryC define the type of the server and the MqContextC define a single object of the server process or thread.
Application |-------------------------------------------------------------------------------------| |--------------- physical host 1 -----------------------|------ physical host 2 ------| |-------- process-1 --------|-------- process-2 --------|-- process-3 --|---- … ------| thread-1 thread-2… thread-1… thread-2… thread-1… thread-… factory-A factory-X factory-Y… factory-Z… object-1 object-1 object-… … object-2 object-2 … object-3 object-3 … …
A server has a single MqFactoryC object per thread or process but multiple MqFactoryC objects per application. Decreasing the size and the complexity of a MqContextC object will improve the server performance. In future more fields, defined in the MqSetupS attribute of the the MqContextC object, will move into MqFactoryC object.
Fct | cast a unknown-object into an MqFactoryS pointer or NULL if not possible | ||
FctCheck | check MqFactoryS -> MkObjectS::signature … | ||
FctCheckO | check MqFactoryS -> MkObjectS::signature … | ||
FctN | (const) cast a unknown-object into an MqFactoryS pointer or NULL if not possible |
HandleResolve | Handle-Resolve-Slot - return a MqFactoryC from netHdl or MK_NULL if invalid… | ||
HandleGet | Handle-Get-Slot - returns a export-hdl to the MqFactoryC useable for external storage |
MqFactoryC CLASS INTROSPECTION
Instances | get head-instance from linked-list of MqFactoryS type … | ||
Next | get next instance from linked-list of MqFactoryS type | ||
Prev | get previous instance from linked-list of MqFactoryS type |
GetNull | Null-Slot - return a MqFactoryC typed |
C-API: MqFactoryC_Class_C_API - MqFactoryC - define the class …
C-API: MqFactoryC_Class_Define_C_API - MqFactoryC - low level definition, access and cast …
(static,hide) MQ_FCT MqFct(MK_MNG mng)
top cast a unknown-object into an MqFactoryS pointer or NULL if not possible → API: MqFct
(static,hide) MK_BOOL MqFctCheck(MK_MNGN mng)
top check MqFactoryS -> MkObjectS::signature … → API: MqFctCheck
(static,hide) MK_BOOL MqFctCheckO(MK_OBJN obj)
top check MqFactoryS -> MkObjectS::signature … → API: MqFctCheckO
(static,hide) MQ_FCTN MqFctN(MK_MNGN mng)
top (const) cast a unknown-object into an MqFactoryS pointer or NULL if not possible → API: MqFctN
MqFactoryC - Export class functions …
(static,runtime) MQ_FCT MqFactoryHandleResolve(MK_HDL const netHdl)
top Handle-Resolve-Slot - return a MqFactoryC from netHdl or MK_NULL
if invalid… → API: MqFactoryHandleResolve_RT
The MqFactoryHandleResolve undo the MqFactoryHandleGet and is intended to export a unique identifer into external code not belonging to the Programming-Language-Micro-Kernel (PLMK).
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | netHdl | handle former exported with MqFactoryHandleGet |
MK_NULL
if netHdl is invalid (runtime) MK_HDL MqFactoryHandleGet(MQ_FCT const fct)
top Handle-Get-Slot - returns a export-hdl to the MqFactoryC useable for external storage → API: MqFactoryHandleGet_RT
The export-hdl is a reference to an instance that can be stored in software and converted back into an instance using the MqFactoryHandleResolve.
The export-hdl is only valid until the Programming-Language-Micro-Kernel (PLMK) ends.
example: The export-hdl is used in rpc to identify an object across the network.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | fct | the MqFactoryS instance to work on |
MqFactoryC - Introspection class functions …
(static,runtime) MQ_FCT MqFactoryInstances()
top get head-instance from linked-list of MqFactoryS type … → API: MqFactoryInstances_RT
The head-instance is the last instance created.
MQ_FCT MqFactoryNext(MQ_FCT const fct)
top get next instance from linked-list of MqFactoryS type → API: MqFactoryNext
MQ_FCT MqFactoryPrev(MQ_FCT const fct)
top get previous instance from linked-list of MqFactoryS type → API: MqFactoryPrev
MqFactoryC - Misc class functions …
(static) MQ_FCT MqFactoryGetNull()
top Null-Slot - return a MqFactoryC typed NULL
instance … → API: MqFactoryGetNull
C-API: MqFactoryC_TOR_C_API - MqFactoryC - various functions to create, initialize and destroy a factory …
(constructor,static,runtime) MQ_FCT MqFactoryAdd(MK_CCP const constructor, MK_STRN const ident)
top add a new MqFactoryC identified by factory-identifier and defined by factory-constructor … → API: MqFactoryAdd_RT
The factory is required to get all libmqmsgque features.
The constructor have to be a c-function.
Example from Filter5.c
→ create a new context using factory F1; F2 or F3 read from the commandline
int main (int argc, MK_STRN argv[]) { MqRtSetup_NULL; // create buffer-list of the application arguments MK_BFL largs = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; // init the libmqmsgque global applications starter MqInitSetArg0VA(argv[0], NULL); // add factories MqFactoryAdd (MK_ERROR_PANIC, F1New, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "F1"); MqFactoryAdd (MK_ERROR_PANIC, F2New, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "F2"); MqFactoryAdd (MK_ERROR_PANIC, F3New, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "F3"); //M0 //printXULS(largs,largs) // call factory using the !second! application argument, // first argument is the executable self MqFactoryNew_E (MqFactoryGetCalledL (largs), NULL, &mqctx); //printXULS(mqctx,largs) // configure and start the server MqLinkCreate_E (mqctx, largs); // report all arguments NOT consumed !! MqCheckForLeftOverArguments_E (mqctx, largs); // start event-loop and wait forever MqProcessEvent_E (mqctx, MQ_WAIT_FOREVER, MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largs); MqExit_1(mqctx); }
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | error | (C-API) flag to signal how to report an error. valid values are: MK_ERROR_PANIC, MK_ERROR_PRINT, MK_ERROR_IGNORE or an other MqContextC |
[in] | ident | the factory-identifier, if MK_NULL or EMPTY the class-name is used. The ident is the public identifier (name) of the factory and is used in logging-output (MqLog...) , name-resolution (MqFactoryGet...) and an first parameter in the executable-call: myserver ident ... . |
[in] | createCallF | (C-API) object constructor function |
[in] | constructor | object (class) constructor data |
[in] | createDataFreeF | (C-API) object constructor data free function |
[in] | createDataCopyF | (C-API) object copy-constructor data free function |
[in] | deleteCallF | (C-API) object destructor function |
[in] | destructor | object (class) destructor data |
[in] | deleteDataFreeF | (C-API) object destructor data free function |
[in] | deleteDataCopyF | (C-API) object copy-constructor data free function |
MK_NULL
on error(destructor,runtime) void MqFactoryDelete(MQ_FCT fct)
top Destructor - delete a MqFactoryC instance … → API: MqFactoryDelete_RT
The factory-delete is more a pseudo-delete because a factory is always in-duty:
(constructor,runtime) MQ_FCT MqFactoryDup2(MQ_FCTN const fct, MK_STRN const ident)
top create a duplicate of the singleton object MqFactoryC using a new factory-identifer → API: MqFactoryDup2_RT
(runtime,hide) void MqFactoryFree(MQ_FCT const fct)
top free internal factory memory and call MqFactoryDTorS::fFree + MqFactoryCTorS::fFree → API: MqFactoryFree_RT
C-API: MqFactoryC_Get_C_API - MqFactoryC - various functions to 'get' data out of a factory …
(static) MQ_FCT MqFactoryGet(MK_STRN const ident)
top return the MqFactoryC → API: MqFactoryGet
The ident is the factory-name used with MqFactoryAdd - usually the class-name.
The following ident are also supported:
"initial" | belongs to the factory with MqFactoryInitial |
"default" or "" | belongs to the factory with MqFactoryDefault |
[in] | ident | the factory-identifier to search for |
MK_NULL
if ident was not found (static) MQ_FCT MqFactoryGetCalled(MK_STRN const ident)
top returns the MqFactoryC identified by ident … → API: MqFactoryGetCalled
If multiple factories (MqFactoryAdd) are available the startup code have to choose which factory to use.
The selection is done by the factory-identifer and is taken from the ident or from the first argument of the commandline-arguments-list.
[in] | ident | the factory-identifier or "" for the default MqFactoryC |
MK_NULL
if nothing was found (static,runtime) MQ_FCT MqFactoryGetCalledL(MK_BFLN largs)
top returns the MqFactoryC identified as first argument in the largs MkBufferListC … → API: MqFactoryGetCalledL_RT
Like MqFactoryGetCalled but the ident is taken from the MkBufferListC object that was created from the commandline-arguments-list.
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | largs | the command-line-args or "" for the default MqFactoryC |
MK_NULL
if nothing was found MK_STRN MqFactoryGetOriginalIdent(MQ_FCTN const fct)
top helper function to return MqFactoryS::originalIdent → API: MqFactoryGetOriginalIdent
(hide) MK_PTR MqFactoryItemGetCreateData(MQ_FCTN const fct)
top helper function to return MqFactoryS::Create::data → API: MqFactoryItemGetCreateData
C-API: MqFactoryC_Misc_C_API - MqFactoryC - various functions to work on a factory …
(static) MK_STRN MqFactoryDefaultIdent()
top return the factory-identifier of the default MqFactoryC → API: MqFactoryDefaultIdent
(static) MK_STRN MqFactoryInitialIdent()
top return the factory-identifier of the initial MqFactoryC → API: MqFactoryInitialIdent
(static,runtime) void MqFactoryLogAll(MK_STRN const callfunc)
top log all "factories" to stderr → API: MqFactoryLogAll_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
MQ_FCT MqFactoryDefault(MQ_FCT const fct)
top set the default-attribute to the factory … → API: MqFactoryDefault
The default-factory is used to create an MqFactoryC if MqFactoryGetCalled was not able to find a specific factory object. This is designed for a scenario with multiple factories included into a single binary and the first commandline parameter after the executable name… (position 0=executable, position 1=factory-selector)… is not related to a factory-ident… added with MqFactoryAdd.
[in] | fct | the new default MqFactoryC |
Example: from example/c/server.cs
MQ_FCT MqFactoryInitial(MQ_FCT const fct)
top set the initial-attribut to fct
… → API: MqFactoryInitial
The factory with "Initial"-attribute is always used for an object that should only be created with the MqContextC base class, but for which no other factory has been specified.
Use this attribute with care because you are firmly linking a factory. In a programming language with class-support, such as C++ or C#, this class is used for every new MqContextC object.
Where "Reflection" is available, this attribute has less meaning since the class is primarily determined from the parent object by means of "Reflection".
The "Initial" attribute is otherwise used for the "Loopback" and the "Filter" capability.
Example from Filter4.c
→ set Initial attribute to a Factory
int main ( const int argc, MK_STRN argv[] ) { MqRtSetup_NULL; // new types are created per-runtime Filter4TT = MkTypeDup2(MqContextC_TT,"Filter4"); Filter4TT->objsize = sizeof(struct FilterCtxS); // the parent-context MK_BFL args = MkBufferListCreateVC (argc, argv); // create the factory and set the "initial" attribute. // with "initial" set every new context get the "Filter4Factory" as factory. MqFactoryInitial( MqFactoryAdd(MK_ERROR_PANIC, Filter4Factory, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Filter4") ); // instance created WITHOUT "MqFactoryNew" but "initial" from above garantee the right "factory-aware" setup. // WITHOUT "initial" from above there is NO link between the new instance and the "Filter4Factory". MQ_CTX mqctx = Filter4Create( MK_RT_CALL NULL); // create the link MqLinkCreate_E (mqctx, args); // start event-loop and wait forever MqProcessEvent_E (mqctx, MQ_WAIT_FOREVER, MK_TIMEOUT_USER); // finish and exit error: MkBufferListDelete(args); MqExit_1 (mqctx); }
[in] | fct | the new initial MqFactoryC |
(runtime) void MqFactoryLog(MQ_FCTN const fct, MK_OBJN fmtobj, MK_DBG const debug, MK_STRN const callfunc, MK_I32 const lvl)
top log the MqFactoryC … → API: MqFactoryLog_RT
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | fct | the MqFactoryS instance to work on |
[in] | fmtobj | managed object used to format the log-message (default=MK_NULL → use default-format) |
[in] | debug | the debug level from MkRuntimeS::debug, use 0 <= debug <= 9 (default=0 ) |
[in] | callfunc | a user-defined postfix to identify the calling function or the environment (default=name-of-function ) |
[in] | lvl | a user-defined prefix starting with "" for lvl=0 and increase with " " for lvl+1 (default=0 ) |
(runtime) enum MkErrorE MqFactoryNew(MQ_FCT const fct, MQ_CTX *const val_out)
top create a new MqContextC from a MqFactoryC … → API: MqFactoryNew_RT
this create only the initial-server-object… all other server-objects will be created on behalf of the client-request.
Example from MyServer.c
→ create a new server context
#include "common.h" // service to serve all incoming requests for token "HLWO" static enum MkErrorE MyFirstService ( MQ_SERVICE_CALL_ARGS ) { MqSendSTART_E (mqctx); MqSendV_E (mqctx, "%s World", MqReadSTR_e(mqctx)); error: return MqSendRETURN(mqctx); } // define a service as link between the token "HLWO" and the callback "MyFirstService" static enum MkErrorE ServerSetup ( MQ_SERVICE_CALL_ARGS ) { return MqServiceCreate(mqctx,"HLWO", MyFirstService, NULL, NULL, NULL); } // package-item enum MkErrorE MyServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { MQ_CTX const mqctx = *contextP = MqContextCreate(NULL,tmpl); MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); return MK_OK; } // package-main int main (int argc, MK_STRN argv[]) { MqRtSetup_NULL; // setup commandline arguments for later use MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; // create "MyServer" factory… and make it to the default. MqFactoryDefault( MqFactoryAdd_2(MyServerFactory, "MyServer")); // inspect commandline-argument for the "factory" to choose… and create a object MqFactoryNew_E (MqFactoryGetCalledL(largv), NULL, &mqctx); // start listen for incoming call's MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }
[in] | mkrt | the MkRuntimeS instance to work on - the runtime argument, used by MK_RT_CALL (C-only) |
[in] | fct | a MqFactoryC used to create a MqContextC |
[in] | tmpl | (C-API only) template for context intialization |
[out] | val_out | the new context object as return or MK_NULL on error |
MK_NULL
pointer C-API: MqContextC_FilterApi_C_API - MqContextC - modify the data using the filter-technology …
The filter mode is related to a special usage of the libmqmsgque software called a command pipeline. To define a filter create a server with:
Every filter has two context one belongs to the left command and one belongs to the right command:
<-- left cmd --> <------- filter -------> <-- right cmd --> <-- left --><- right --> <- server -><- client -> <- master -><- slave --> <-context1-><-context2-> ... command1 @ filter @ command2 ...
The left context is created on application startup and the right context is created as slave of the left context.
client @ filter @ server
<------------ host-1 -------------> <-- network --> <---------- host-2 -----------> <---- client arguments ----> <--- server arguments --> <-- filter arg. --> <--- options ---> client @ filter @ --tcp --port 7777 ........... server --tcp --port 7777 --fork
A bi-directional filter allow a data-flow in both directions and is used in a classical client/server application:
client ... <--> ... server
as a feature enhancement like a protocol-tunnelling:
client @ mq2tunnel ... <--> ... tunnel2mq @ server
or to convert the protocol into an other protocol:
client @ mq2soap ... <--> ... soap-server
To define a bi-directional filter a couple of commands provide support:
aguard
)aguard
), or to save the body in a persistent storage for later use MqDumpImport.A one-directional filter is a special form of a bi-directional filter and allow a data-flow from the left to the right.
This filter is well known from the unix shell to link different commands together:
command1 | command2 | command3
A libmqmsgque command pipeline is created with the special character "@" instead of "|" :
msgcmd1 @ msgcmd2 @ msgcmd3
To define a libmqmsgque filter... create a service handle with MqServiceCreate or MqServiceProxy ... using the token +FTR and +EOF
token | description |
---|---|
+FTR | required 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 to the following filter-command as +FTR service request |
+EOF | required to act on End-Of-Filter data and is called after all +FTR data was send. Sometimes the filter data can not be served as +FTR 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+EOF token is used to continue send +FTR data rows. |
and send every data item with MqSendEND_AND_WAIT .
This library is actively developed and tested on x86_64 Linux (opensuse), older versions have also been successful tested on FreeBSD, WindowsXP/7, MacOSX and Solaris using x86_64, i686, ppc and sparc processor.
mulserver.c
→ #include "common.h" static enum MkErrorE MMUL( MQ_SERVICE_CALL_ARGS ) { MK_DBL d1,d2; MqSendSTART_E (mqctx); MqReadDBL_E (mqctx, &d1); MqReadDBL_E (mqctx, &d2); MqSendDBL_E (mqctx, d1*d2); error: return MqSendRETURN(mqctx); } static enum MkErrorE ServerSetup ( MQ_SERVICE_CALL_ARGS ) { return MqServiceCreate(mqctx,"MMUL", MMUL, NULL, NULL, NULL); } static enum MkErrorE MulServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { MQ_CTX const mqctx = *contextP = MqContextCreate(NULL,tmpl); MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); return MK_OK; } int main (int argc, MK_STRN argv[]) { MqRtSetup_NULL; MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; MQ_FCT fct = MqFactoryAdd (MK_ERROR_PANIC, MulServerFactory, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "mulserver" ); MqFactoryNew_E (fct, NULL, &mqctx); MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }
mulclient.c
→ #include "common.h" int main (int argc, MK_STRN argv[]) { MkRtSetup_NULL; struct MkBufferListS * largv = MkBufferListCreateVC(argc, argv); MQ_CTX ctx = MqContextCreate(NULL,NULL); MK_DBL d; MqConfigSetName (ctx, "MyMul"); MqLinkCreate_E (ctx, largv); MqCheckForLeftOverArguments_E (ctx, largv); MqSendSTART_E (ctx); MqSendDBL_E (ctx,3.67); MqSendDBL_E (ctx,22.3); MqSendEND_AND_WAIT_E (ctx, "MMUL", 10); MqReadDBL_E (ctx, &d); fprintf(stdout,"%f\n", d); fflush(stdout); error: MkBufferListDelete(largv); MqExit_1(ctx); }
MyLoopServer.c
→ #include "common.h" // [MyLoopServerC_Define] typedef struct MyLoopServerS { struct MqContextS mqctx; ///< link to the \libmqmsgque object #define mydata_size 30 char mydata[mydata_size]; ///< define the "mydata" attribute } MyLoopServerC; // [MyLoopServerC_Define] // the MyLoopServerC class-type static MkThreadLocal MK_TYP MyLoopServerCTT = NULL; // service to serve all EXTERNAL requests for token "HLWO" static enum MkErrorE HLWO_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "loopback" context MQ_CTX loop = MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK); // call the LOOP service on the SAME server MqSend_E(loop,"W","LOOP"); // answer HLWO with string-return from LOOP MqSend_E(mqctx, "R", "C", MqReadSTR_e(loop)); return MK_OK; error: return MqSendRETURN(mqctx); } // service to serve all INTERNAL requests for token "LOOP static enum MkErrorE LOOP_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "master" context MyLoopServerC* master = (MyLoopServerC*)MqSlaveGetMaster(mqctx); // answer LOOP with data from MASTER->mydata attribute return MqSend(mqctx, "R", "C", master->mydata); } // define a service as link between the token "HLWO" and the callback "HLWO_srv" static enum MkErrorE ServerSetup ( MQ_SERVICE_CALL_ARGS ) { // EXTERNAL: link the "HLWO" service with "HLWO_srv" MqServiceCreate_E(mqctx, "HLWO", HLWO_srv, NULL, NULL, NULL); // INTERNAL: link the "LOOP" service with "LOOP_srv" MqServiceCreate_E(MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK), "LOOP", LOOP_srv, NULL, NULL, NULL); return MK_OK; error: return MkErrorStack_1X(mqctx); } // [MyLoopServerC_Create] enum MkErrorE MyLoopServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { // create new instance using the MyLoopServerCTT class-type MQ_CTX const mqctx = *contextP = MqContextCreate(MyLoopServerCTT,tmpl); // initialize the new context MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); // cast the libmqmsgque-context into the MyLoopServerC-context MyLoopServerC* mqctxC = (MyLoopServerC*)mqctx; // initialize the "mydata" attribute strncpy(mqctxC->mydata,"Hello World",mydata_size); mqctxC->mydata[mydata_size-1] = '\0'; return MK_OK; } // [MyLoopServerC_Create] int main (int argc, MK_STRN argv[]) { MqRtSetup_NULL; // [MyLoopServerC_Init] // initialize the MyLoopServer class-type with existing MqContextC_TT class-type MyLoopServerCTT = MkTypeDup2(MqContextC_TT,"MyLoopServerC"); MyLoopServerCTT->objsize = sizeof(struct MyLoopServerS); // [MyLoopServerC_Init] // setup commandline arguments for later use MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; // create "MyLoopServer" factory… and make it to the default. MqFactoryDefault(MqFactoryAdd_2(MyLoopServerFactory,"MyLoopServer")); // inspect commandline-argument for the "factory" to choose… and create a object MqFactoryNew_E (MqFactoryGetCalledL(largv), NULL, &mqctx); // start listen for incoming call's MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }
MyClient.c
→ #include "debug_mq.h" #include "msgque_mq.h" int main (int argc, MK_STRN argv[]) { MkRtSetup_NULL; struct MkBufferListS * largv = MkBufferListCreateVC(argc, argv); // create a context using the static libmqmsgque CTOR function "MqContextCreate" MQ_CTX ctx = MqContextCreate(NULL,NULL); MqConfigSetName(ctx, "MyClient"); MqLinkCreate_E (ctx, largv); MqCheckForLeftOverArguments_E (ctx, largv); MqSend_E (ctx, "W", "HLWO:C", "Hello"); fprintf(stdout,"%s\n", MqReadSTR_e (ctx)); fflush(stdout); error: MkBufferListDelete(largv); // delete the context using the libmqmsgque APPLICATION-DTOR function "MqExit_1" MqExit_1(ctx); }
Example from manfilter.c
→
#include "common.h" static enum MkErrorE FTR( MQ_SERVICE_CALL_ARGS ) { MK_STRN str; MQ_CTX ftr; MqSlaveGetFilter_E (mqctx, &ftr); MqSendSTART_E (ftr); while (MqReadItemExists(mqctx)) { MqReadSTR_E (mqctx, &str); MkBufferSetV(MkBUF(&mqctx->ctxbuf),"<%s>", str); MqSendBUF_E (ftr, MkBUF(&mqctx->ctxbuf)); } MqSendEND_AND_WAIT_E (ftr, "+FTR", MK_TIMEOUT_USER); error: return MqSendRETURN (mqctx); } int main (int argc, MK_STRN argv[]) { MkRtSetup_NULL; struct MkBufferListS * largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = MqContextCreate(NULL,NULL); MqConfigSetName (mqctx, "ManFilter"); MqConfigSetIsServer (mqctx, true); MqLinkCreate_E (mqctx, largv); MqServiceCreate_E (mqctx, "+FTR", FTR, NULL, NULL, NULL); MqServiceProxy_E (mqctx, "+EOF", MQ_SLAVE_FILTER); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }
Use manfilter in a libmqmsgque command pipeline:
libmqmsgque, ccmqmsgque, csmqmsgque, javamqmsgque, gomqmsgque, pymqmsgque, rbmqmsgque, tclmqmsgque, perlmqmsgque, phpmqmsgque
C, unix, socket, message, msgque