Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Bridge support functions
0003  *
0004  * @file brsupport.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 #include <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <memory.h>
0038 #include <sys_mqueue.h>
0039 #include <errno.h>
0040 #include <time.h>
0041 #include <sys/param.h>
0042 
0043 
0044 #include <atmi.h>
0045 #include <ndrstandard.h>
0046 #include <ndebug.h>
0047 #include <atmi_int.h>
0048 #include <atmi_shm.h>
0049 
0050 #include <ndrxdcmn.h>
0051 #include "gencall.h"
0052 #include "atmi_tls.h"
0053 /*---------------------------Externs------------------------------------*/
0054 /*---------------------------Macros-------------------------------------*/
0055 /*---------------------------Enums--------------------------------------*/
0056 /*---------------------------Typedefs-----------------------------------*/
0057 /*---------------------------Globals------------------------------------*/
0058 /*---------------------------Statics------------------------------------*/
0059 /*---------------------------Prototypes---------------------------------*/
0060 
0061 /**
0062  * Dump node stack
0063  * @param stack
0064  */
0065 expublic void br_dump_nodestack(char *stack, char *msg)
0066 {
0067     int i=0;
0068     int nodeid;
0069     char node_stack_str[CONF_NDRX_NODEID_COUNT*4];
0070     node_stack_str[0] = EXEOS;
0071     char tmp[10];
0072     int len = strlen(stack);
0073     
0074     for (i=0; i<len; i++)
0075     {
0076         nodeid = stack[i];
0077         if (i+1!=len)
0078             sprintf(tmp, "%d->", nodeid);
0079         else
0080             sprintf(tmp, "%d", nodeid);
0081         strcat(node_stack_str, tmp);
0082     }
0083     NDRX_LOG(log_info, "%s: [%s]", msg, node_stack_str);
0084     
0085 }
0086 
0087 /**
0088  * Fill reply queue, either local (if no nodes in stack), or another birdge service.
0089  * @param call
0090  * @return 
0091  */
0092 expublic int fill_reply_queue(char *nodestack, 
0093             char *org_reply_to, char *reply_to)
0094 {
0095     int i;
0096     int len;
0097     int nodeid;
0098     int ret=EXSUCCEED;
0099     ATMI_TLS_ENTRY;
0100     
0101     *reply_to = EXEOS;
0102     /* So we are going to do reply, we should scan the reply stack
0103      * chose the bridge, and reduce the callstack
0104      */
0105     br_dump_nodestack(nodestack, "Node stack before bridge select");
0106     
0107     if ((len = strlen(nodestack)) > 0 )
0108     {
0109         NDRX_LOG(log_debug, "Selecting bridge for reply");
0110         for (i=0; i<len; i++)
0111         {
0112             nodeid = nodestack[i];
0113             if (ndrx_shm_bridge_is_connected(nodeid))
0114             {
0115                 /* get the bridge service first... */
0116 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
0117                 int is_bridge;
0118                 char tmpsvc[MAXTIDENT+1];
0119                 
0120                 snprintf(tmpsvc, sizeof(tmpsvc), NDRX_SVC_BRIDGE, nodeid);
0121                 
0122                 if (EXSUCCEED!=ndrx_shm_get_svc(tmpsvc, reply_to, &is_bridge, NULL))
0123                 {
0124                     NDRX_LOG(log_error, "Failed to get bridge svc: [%s]", 
0125                             tmpsvc);
0126                     EXFAIL_OUT(ret);
0127                 }
0128 #else
0129                 /* epoll/fdpoll/kqueue mode direct call: */
0130                 sprintf(reply_to, NDRX_SVC_QBRDIGE, G_atmi_tls->G_atmi_conf.q_prefix, nodeid);
0131 #endif
0132                 
0133                 nodestack[i] = EXEOS;
0134                 br_dump_nodestack(nodestack, "Node stack after bridge select");
0135                 break;
0136             }
0137         }
0138         
0139         if (EXEOS==*reply_to)
0140         {
0141             ret=EXFAIL;
0142             NDRX_LOG(log_error, "No bridge to send reply to!");
0143         }
0144     }
0145     /* If have something in node stack */
0146     else
0147     {
0148         /* this was local call, so reply on q */
0149         strcpy(reply_to, org_reply_to);
0150     }
0151     
0152 out:
0153     return ret;
0154 }
0155 /* vim: set ts=4 sw=4 et smartindent: */