MqContextC - setup and manage a routing-link … More...
Collaboration diagram for MqContextC_Route_JV_API:Functions | |
| native MkBufferListC | jvmqmsgque.MqContextC.RouteGetTree () |
Java: → C-API create an overview about all available routing-target and services … | |
| native void | jvmqmsgque.MqContextC.RouteCreate (String route, String service, boolean overwrite) |
Java: → C-API create/delete a routing-link between context an a service using route | |
| void | jvmqmsgque.MqContextC.RouteCreate (String route, String service) |
Java: → C-API create/delete a routing-link between context an a service using route | |
| native void | jvmqmsgque.MqContextC.RouteDelete (String route, String service, boolean overwrite) |
Java: → C-API delete a routing-link created with MqRouteCreate | |
| void | jvmqmsgque.MqContextC.RouteDelete (String route, String service) |
Java: → C-API delete a routing-link created with MqRouteCreate | |
| native MqContextC[] | jvmqmsgque.MqContextC.RouteResolve (String ident, int retnum) |
Java: → C-API return a list of all context belonging to ident … | |
| MqContextC[] | jvmqmsgque.MqContextC.RouteResolve (String ident) |
Java: → C-API return a list of all context belonging to ident … | |
| native void | jvmqmsgque.MqContextC.RouteTraverse (String service, MkBufferListC args) |
Java: → C-API traverse a tree down and call service if available. | |
| void | jvmqmsgque.MqContextC.RouteTraverse (String service, String... args) |
Java: → C-API traverse a tree down and call service if available. | |
| void | jvmqmsgque.MqContextC.RouteTraverse (String service) |
Java: → C-API traverse a tree down and call service if available. | |
| native String | jvmqmsgque.MqContextC.RouteGetPath () |
Java: → C-API return the absolut route-connection-string up to the current ctx … | |
| JNIEXPORT jobject JNICALL | Java_jvmqmsgque_MqContextC_RouteGetTree (JNIEnv *env, jobject self) |
Java: → C-API create an overview about all available routing-target and services … | |
| JNIEXPORT void JNICALL | Java_jvmqmsgque_MqContextC_RouteCreate (JNIEnv *env, jobject self, jstring route, jstring service, jboolean overwrite) |
Java: → C-API create/delete a routing-link between context an a service using route | |
| JNIEXPORT void JNICALL | Java_jvmqmsgque_MqContextC_RouteDelete (JNIEnv *env, jobject self, jstring route, jstring service, jboolean overwrite) |
Java: → C-API delete a routing-link created with MqRouteCreate | |
| JNIEXPORT jobjectArray JNICALL | Java_jvmqmsgque_MqContextC_RouteResolve (JNIEnv *env, jobject self, jstring ident, jint retnum) |
Java: → C-API return a list of all context belonging to ident … | |
| JNIEXPORT void JNICALL | Java_jvmqmsgque_MqContextC_RouteTraverse (JNIEnv *env, jobject self, jstring service, jobject args) |
Java: → C-API traverse a tree down and call service if available. | |
| JNIEXPORT jstring JNICALL | Java_jvmqmsgque_MqContextC_RouteGetPath (JNIEnv *env, jobject self) |
Java: → C-API return the absolut route-connection-string up to the current ctx … | |
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:
ctx.RouteCreate(String route, String service, ?boolean overwrite = false?) 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.java → create a new loop-server package example; import jvmqmsgque.*; import jvmkkernel.*; // package-item final class MyLoopServer extends MqContextC implements MqServerSetupIF { // set the "mydata" attribute to the master-context String mydata = "Hello World"; // Factory Constructor public MyLoopServer(MqContextC tmpl) { super(tmpl); } // service to serve all EXTERNAL requests for token "HLWO" class HLWO_srv implements MqServiceIF { public void Callback(MqContextC ctx) { // get the "loopback" context MqContextC loop = SlaveGet(MqSlaveE.LOOPBACK.get()); // call the LOOP service on the SAME server loop.Send("W","LOOP"); // answer HLWO with string-return from LOOP Send("R", "C", loop.ReadSTR()); } } // service to serve all INTERNAL requests for token "LOOP" class LOOP_srv implements MqServiceIF { public void Callback(MqContextC ctx) { // get the "master" context MyLoopServer master = ((MyLoopServer)SlaveGetMaster()); // answer LOOP with data from MASTER->mydata attribute Send("R", "C", master.mydata); } } // define a service as link between the token "HLWO" and the class "MyFirstService" public void ServerSetup() { // EXTERNAL: link the "HLWO" service with the "HLWO_srv" ServiceCreate("HLWO", new HLWO_srv()); // INTERNAL: link the "LOOP" service with "LOOP_srv" SlaveGet(MqSlaveE.LOOPBACK.get()).ServiceCreate("LOOP", new LOOP_srv()); } // ------------------------------------------------------------- // package-main public static void main(String[] argv) { // create the "MyLoopServer" factory… and the instance MqContextC srv = MqFactoryC.Add(MyLoopServer.class).New(); try { srv.LinkCreate(argv); srv.ProcessEvent(MqWaitOnEventE.FOREVER); } catch (Throwable e) { srv.ErrorCatch(e); } srv.Exit(); } }
Performance analyse
Nhi1Exec perfclient.c --parent --wrk ? @ perfserver.cNhi1Exec -r=uds perfserver.c --spawn|fork|threadNhi1Exec -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....
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:
ctx.RouteCreate(String route, String service, ?boolean overwrite = false?) 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.java → create a new loop-server package example; import jvmqmsgque.*; import jvmkkernel.*; // package-item final class MyLoopServer extends MqContextC implements MqServerSetupIF { // set the "mydata" attribute to the master-context String mydata = "Hello World"; // Factory Constructor public MyLoopServer(MqContextC tmpl) { super(tmpl); } // service to serve all EXTERNAL requests for token "HLWO" class HLWO_srv implements MqServiceIF { public void Callback(MqContextC ctx) { // get the "loopback" context MqContextC loop = SlaveGet(MqSlaveE.LOOPBACK.get()); // call the LOOP service on the SAME server loop.Send("W","LOOP"); // answer HLWO with string-return from LOOP Send("R", "C", loop.ReadSTR()); } } // service to serve all INTERNAL requests for token "LOOP" class LOOP_srv implements MqServiceIF { public void Callback(MqContextC ctx) { // get the "master" context MyLoopServer master = ((MyLoopServer)SlaveGetMaster()); // answer LOOP with data from MASTER->mydata attribute Send("R", "C", master.mydata); } } // define a service as link between the token "HLWO" and the class "MyFirstService" public void ServerSetup() { // EXTERNAL: link the "HLWO" service with the "HLWO_srv" ServiceCreate("HLWO", new HLWO_srv()); // INTERNAL: link the "LOOP" service with "LOOP_srv" SlaveGet(MqSlaveE.LOOPBACK.get()).ServiceCreate("LOOP", new LOOP_srv()); } // ------------------------------------------------------------- // package-main public static void main(String[] argv) { // create the "MyLoopServer" factory… and the instance MqContextC srv = MqFactoryC.Add(MyLoopServer.class).New(); try { srv.LinkCreate(argv); srv.ProcessEvent(MqWaitOnEventE.FOREVER); } catch (Throwable e) { srv.ErrorCatch(e); } srv.Exit(); } }
Performance analyse
Nhi1Exec perfclient.c --parent --wrk ? @ perfserver.cNhi1Exec -r=uds perfserver.c --spawn|fork|threadNhi1Exec -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....
| JNIEXPORT void JNICALL Java_jvmqmsgque_MqContextC_RouteCreate | ( | JNIEnv * | env, |
| jobject | self, | ||
| jstring | route, | ||
| jstring | service, | ||
| jboolean | overwrite ) |
Java: → C-API ctx.RouteCreate(String route, String service, ?boolean overwrite = false?)
create/delete a routing-link between context an a service using route
Definition at line 1675 of file MqContextC_jv.c.
| JNIEXPORT void JNICALL Java_jvmqmsgque_MqContextC_RouteDelete | ( | JNIEnv * | env, |
| jobject | self, | ||
| jstring | route, | ||
| jstring | service, | ||
| jboolean | overwrite ) |
Java: → C-API ctx.RouteDelete(String route, String service, ?boolean overwrite = false?)
delete a routing-link created with MqRouteCreate
Definition at line 1692 of file MqContextC_jv.c.
| JNIEXPORT jstring JNICALL Java_jvmqmsgque_MqContextC_RouteGetPath | ( | JNIEnv * | env, |
| jobject | self ) |
Java: → C-API String ctx.RouteGetPath()
return the absolut route-connection-string up to the current ctx …
Definition at line 1746 of file MqContextC_jv.c.
| JNIEXPORT jobject JNICALL Java_jvmqmsgque_MqContextC_RouteGetTree | ( | JNIEnv * | env, |
| jobject | self ) |
Java: → C-API MkBufferListC ctx.RouteGetTree()
create an overview about all available routing-target and services …
Definition at line 1659 of file MqContextC_jv.c.
| JNIEXPORT jobjectArray JNICALL Java_jvmqmsgque_MqContextC_RouteResolve | ( | JNIEnv * | env, |
| jobject | self, | ||
| jstring | ident, | ||
| jint | retnum ) |
Java: → C-API MqContextC[] ctx.RouteResolve(String ident, ?int retnum = -1?)
return a list of all context belonging to ident …
Definition at line 1709 of file MqContextC_jv.c.
| JNIEXPORT void JNICALL Java_jvmqmsgque_MqContextC_RouteTraverse | ( | JNIEnv * | env, |
| jobject | self, | ||
| jstring | service, | ||
| jobject | args ) |
Java: → C-API ctx.RouteTraverse(String service, ?MkBufferListC args = null?)
traverse a tree down and call service if available.
Definition at line 1728 of file MqContextC_jv.c.
| void jvmqmsgque.MqContextC.RouteCreate | ( | String | route, |
| String | service ) |
Java: → C-API ctx.RouteCreate(String route, String service, ?boolean overwrite = false?)
create/delete a routing-link between context an a service using route
Definition at line 778 of file MqContextC.java.
| native void jvmqmsgque.MqContextC.RouteCreate | ( | String | route, |
| String | service, | ||
| boolean | overwrite ) |
Java: → C-API ctx.RouteCreate(String route, String service, ?boolean overwrite = false?)
create/delete a routing-link between context an a service using route
Here is the caller graph for this function:| void jvmqmsgque.MqContextC.RouteDelete | ( | String | route, |
| String | service ) |
Java: → C-API ctx.RouteDelete(String route, String service, ?boolean overwrite = false?)
delete a routing-link created with MqRouteCreate
Definition at line 786 of file MqContextC.java.
| native void jvmqmsgque.MqContextC.RouteDelete | ( | String | route, |
| String | service, | ||
| boolean | overwrite ) |
Java: → C-API ctx.RouteDelete(String route, String service, ?boolean overwrite = false?)
delete a routing-link created with MqRouteCreate
Here is the caller graph for this function:| native String jvmqmsgque.MqContextC.RouteGetPath | ( | ) |
Java: → C-API String ctx.RouteGetPath()
return the absolut route-connection-string up to the current ctx …
| native MkBufferListC jvmqmsgque.MqContextC.RouteGetTree | ( | ) |
Java: → C-API MkBufferListC ctx.RouteGetTree()
create an overview about all available routing-target and services …
| MqContextC[] jvmqmsgque.MqContextC.RouteResolve | ( | String | ident | ) |
Java: → C-API MqContextC[] ctx.RouteResolve(String ident, ?int retnum = -1?)
return a list of all context belonging to ident …
Definition at line 794 of file MqContextC.java.
| native MqContextC[] jvmqmsgque.MqContextC.RouteResolve | ( | String | ident, |
| int | retnum ) |
Java: → C-API MqContextC[] ctx.RouteResolve(String ident, ?int retnum = -1?)
return a list of all context belonging to ident …
Here is the caller graph for this function:| void jvmqmsgque.MqContextC.RouteTraverse | ( | String | service | ) |
Java: → C-API ctx.RouteTraverse(String service, ?MkBufferListC args = null?)
traverse a tree down and call service if available.
Definition at line 807 of file MqContextC.java.
| native void jvmqmsgque.MqContextC.RouteTraverse | ( | String | service, |
| MkBufferListC | args ) |
Java: → C-API ctx.RouteTraverse(String service, ?MkBufferListC args = null?)
traverse a tree down and call service if available.
Here is the caller graph for this function:| void jvmqmsgque.MqContextC.RouteTraverse | ( | String | service, |
| String... | args ) |
Java: → C-API ctx.RouteTraverse(String service, ?MkBufferListC args = null?)
traverse a tree down and call service if available.
Definition at line 802 of file MqContextC.java.