Documentation of the MyRouter tool used for route2.test
.
The MyRouter tool is used to test the routing-feature of libmqmsgque.
To perform the test multiple classes are created and connected using the libmqmsgque protocol.
The following class-hierarchie is used:
Base |----|----| WO1 WO2 WO3
The routing-test is perfomed by connecting multiple context.
|-> WO3#1 |-> WO2#1 -|-> WO3#2 client -> WO1 -| |-> W02#2 -|-> WO3#1 |-> WO3#2
All context created, 1x client and 7x server, are connected using the libmqmsgque protocoll and build together a tree-like structure.
The GOAL for this setup is:
/** * @file NHI1/example/c/MyRouter.c * @brief MyRouter.c - 02 Oct 2024 - aotto1968 * @copyright (C) NHI - #1 - Project - Group * This software has NO permission to copy, * please contact AUTHOR for additional information * @version 6b6d463bfff4302b7ea9898694b5548df6d8aef4 * @date Wed Oct 2 23:41:27 2024 +0200 * @author aotto1968 <aotto1968@t-online.de> */ /* LABEL-START */ #define META_FILE_NAME "MyRouter.c" /* LABEL-END */ #include "common.h" #define use_2 #define use_3 // ======================================================================= static enum MkErrorE BasicSetup ( MK_RT_ARGS MQ_CTX const mqctx); #if defined(use_2) || defined(use_3) static enum MkErrorE BasicCreateWorker ( MQ_CTX mqctx, MK_NUM master_id, MK_STRN factory ) { MkRtSetup_XN(mqctx); MK_BFL argv = MkBufferListCreate(5); MkBufferListAppendSTR(argv, "--prefix"); MkBufferListAppendV(argv, "cl%s-%i", factory, master_id); MkBufferListAppendSTR(argv, "@"); MkBufferListAppendSTR(argv, "--prefix"); MkBufferListAppendV(argv, "sv%s-%i", factory, master_id); MqSlaveWorker_E (mqctx, master_id, factory, argv); error: MkBufferListDelete(argv); return MkErrorStack_1M_Check(mqctx); } static const MK_NUM id1 = MQ_SLAVE_USER+1; static const MK_NUM id2 = MQ_SLAVE_USER+2; #endif static enum MkErrorE Basic_HLWO ( MQ_SERVICE_CALL_ARGS ) { return MqSend(mqctx, "R", "C", MqConfigGetName(mqctx)); } static enum MkErrorE Basic_FOID ( MQ_SERVICE_CALL_ARGS ) { MqSendSTART_E(mqctx); MqSendV_E(mqctx, "%s-%i", MqClassOriginalIdentGet(mqctx), MqLinkGetCtxId(mqctx)); error: return MqSendRETURN(mqctx); } static enum MkErrorE Basic_PATH ( MQ_SERVICE_CALL_ARGS ) { return MqSend(mqctx, "R", "C", MqRouteGetPath_e(mqctx)); error: return MqSendRETURN(mqctx); } static enum MkErrorE Basic_TREE ( MQ_SERVICE_CALL_ARGS ) { return MqSend(mqctx, "R", "L", MqRouteGetTree_e(mqctx)); error: return MqSendRETURN(mqctx); } static enum MkErrorE Basic_HLWS ( MQ_SERVICE_CALL_ARGS ) { MkErrorCheck(BasicSetup( MK_RT_CALL MqSlaveGetMaster(mqctx))); error: return MqSendRETURN(mqctx); } static enum MkErrorE BasicSetup ( MK_RT_ARGS MQ_CTX const mqctx ) { MqServiceCreate_E (mqctx,"HLWO", Basic_HLWO, NULL, NULL, NULL); MqServiceCreate_E (mqctx,"FOID", Basic_FOID, NULL, NULL, NULL); MqServiceCreate_E (mqctx,"PATH", Basic_PATH, NULL, NULL, NULL); MqServiceCreate_E (mqctx,"TREE", Basic_TREE, NULL, NULL, NULL); MqServiceCreate_E (mqctx,"HLWS", Basic_HLWS, NULL, NULL, NULL); return MK_OK; error: return MkErrorStack_1X(mqctx); } // ======================================================================= static enum MkErrorE WO1ServerSetup ( MQ_SERVICE_CALL_ARGS ) { #ifdef use_2 if (MqLinkIsParent(mqctx)) { MkErrorCheck(BasicCreateWorker (mqctx, id1, "WO2")); MkErrorCheck(BasicCreateWorker (mqctx, id2, "WO2")); } #endif MkErrorCheck(BasicSetup( MK_RT_CALL mqctx)); return MK_OK; error: return MkErrorStack_1X(mqctx); } static enum MkErrorE WO1Factory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { MQ_CTX const mqctx = *contextP = MqContextCreate(NULL,tmpl); MqConfigSetServerSetup (mqctx, WO1ServerSetup, NULL, NULL, NULL); return MK_OK; } // ======================================================================= #ifdef use_2 static enum MkErrorE WO2ServerSetup ( MQ_SERVICE_CALL_ARGS ) { #ifdef use_3 if (MqLinkIsParent(mqctx)) { MkErrorCheck(BasicCreateWorker (mqctx, id1, "WO3")); MkErrorCheck(BasicCreateWorker (mqctx, id2, "WO3")); } #endif MkErrorCheck(BasicSetup( MK_RT_CALL mqctx)); return MK_OK; error: return MkErrorStack_1X(mqctx); } static enum MkErrorE WO2Factory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { MQ_CTX const mqctx = *contextP = MqContextCreate(NULL,tmpl); MqConfigSetServerSetup (mqctx, WO2ServerSetup, NULL, NULL, NULL); return MK_OK; } #endif // ======================================================================= #ifdef use_3 static enum MkErrorE WO3_FINL ( MQ_SERVICE_CALL_ARGS ) { MqSendSTART_E(mqctx); MqSendV_E(mqctx, "FINL-%s", MqConfigGetName(mqctx)); error: return MqSendRETURN(mqctx); } static enum MkErrorE WO3ServerSetup ( MQ_SERVICE_CALL_ARGS ) { MkErrorCheck(BasicSetup( MK_RT_CALL mqctx)); MqServiceCreate_E (mqctx,"FINL", WO3_FINL, NULL, NULL, NULL); return MK_OK; error: return MkErrorStack_1X(mqctx); } static enum MkErrorE WO3Factory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { MQ_CTX const mqctx = *contextP = MqContextCreate(NULL,tmpl); MqConfigSetServerSetup (mqctx, WO3ServerSetup, NULL, NULL, NULL); return MK_OK; } #endif // ======================================================================= int main (int argc, MK_STRN argv[]) { AllRtSetup_NULL; MqFactoryDefault( MqFactoryAdd(MK_ERROR_PANIC, WO1Factory, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "WO1") ); #ifdef use_2 MqFactoryAdd(MK_ERROR_PANIC, WO2Factory, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "WO2"); #endif #ifdef use_3 MqFactoryAdd(MK_ERROR_PANIC, WO3Factory, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "WO3"); #endif MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; mqctx = MqFactoryNew_e (MqFactoryGetCalledL(largv), NULL); MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }