Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Transaction recover server process. Used to clean up the transactions
0003  *  after the boot or periodically during the application runtime.
0004  *
0005  * @file tprecoversv.c
0006  */
0007 /* -----------------------------------------------------------------------------
0008  * Enduro/X Middleware Platform for Distributed Transaction Processing
0009  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0010  * Copyright (C) 2017-2018, Mavimax, Ltd. All Rights Reserved.
0011  * This software is released under one of the following licenses:
0012  * AGPL or Mavimax's license for commercial use.
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 
0035 /*---------------------------Includes-----------------------------------*/
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <string.h>
0039 #include <unistd.h>
0040 #include <ndrstandard.h>
0041 #include <ndebug.h>
0042 #include <atmi.h>
0043 #include "tmrecover.h"
0044 /*---------------------------Externs------------------------------------*/
0045 /*---------------------------Macros-------------------------------------*/
0046 /*---------------------------Enums--------------------------------------*/
0047 /*---------------------------Typedefs-----------------------------------*/
0048 /*---------------------------Globals------------------------------------*/
0049 exprivate int M_periodic = EXFALSE;    /**< by default single scan */
0050 /*---------------------------Statics------------------------------------*/
0051 /* Auto generated system advertise table */
0052 expublic struct tmdsptchtbl_t ndrx_G_tmdsptchtbl[] = {
0053     { NULL, NULL, NULL, 0, 0 }
0054 };
0055 /*---------------------------Prototypes---------------------------------*/
0056 
0057 /**
0058  * Transaction recover scan start
0059  * @return EXSUCCEED/EXFAIL
0060  */
0061 exprivate int recover_scan(void)
0062 {
0063     int ret = EXSUCCEED;
0064     
0065     NDRX_LOG(log_debug, "Recover scan started");
0066     
0067     /* recover transactions */
0068     ret = ndrx_tmrecover_do();
0069     
0070     /* set success if have 0 or rolled back.*/
0071     if (ret>=0)
0072     {
0073         if (!M_periodic)
0074         {
0075             /* remove our selves from periodic scanning as we are done
0076              */
0077             tpext_delperiodcb();
0078        }
0079        ret=EXSUCCEED;
0080     }
0081     
0082     return ret;
0083 }
0084 
0085 /**
0086  * Standard server init
0087  * @param argc
0088  * @param argv
0089  * @return 
0090  */
0091 int tpsvrinit (int argc, char **argv)
0092 {
0093     /* register periodic callback
0094      * - used to wait for bridges to establish 
0095      * - used for single & periodic recover scans.
0096      */
0097     int ret=EXSUCCEED;
0098     /* scan after 30 sec */
0099     int scan_time = 30;
0100     int c;
0101     int immediate = EXFALSE;
0102 
0103     /* Parse command line  */
0104     while ((c = getopt(argc, argv, "s:pi")) != -1)
0105     {
0106         if (optarg)
0107         {
0108             NDRX_LOG(log_debug, "%c = [%s]", c, optarg);
0109         }
0110         else
0111         {
0112             NDRX_LOG(log_debug, "got %c", c);
0113         }
0114 
0115         switch(c)
0116         {
0117             case 's': 
0118                 scan_time = atoi(optarg);
0119                 NDRX_LOG(log_info, "Transaction scan time set to: %d", scan_time);
0120                 break;
0121                 /* status directory: */
0122             case 'p':
0123                 M_periodic=EXTRUE;
0124                 NDRX_LOG(log_info, "Periodic scan enabled");
0125                 break;
0126             case 'i':
0127                 immediate=EXTRUE;
0128                 NDRX_LOG(log_info, "Immediate (boot time) recover enabled");
0129                 break;
0130             default:
0131                 /*return FAIL;*/
0132                 break;
0133         }
0134     }
0135 
0136     if (immediate)
0137     {
0138         NDRX_LOG(log_info, "Immediate transaction recover scan started");
0139 
0140         /* requires client init for accessing shared memory */
0141         if (EXSUCCEED!=tpinit(NULL))
0142         {
0143             EXFAIL_OUT(ret);
0144         }
0145 
0146         /* this returns >=0 for success (nr of rolled back) */
0147         if (ndrx_tmrecover_do()<0)
0148         {
0149             EXFAIL_OUT(ret);
0150         }
0151 
0152     }
0153 
0154     /* register extension only if periodic or deffered scanning is enabled. */
0155     if (M_periodic || !immediate)
0156     {
0157         /* Register timer check (needed for time-out detection) */
0158         if (EXSUCCEED!=tpext_addperiodcb(scan_time, recover_scan))
0159         {
0160             NDRX_LOG(log_error, "tpext_addperiodcb failed: %s",
0161                             tpstrerror(tperrno));
0162             EXFAIL_OUT(ret);
0163         }
0164     }
0165     
0166 out:
0167     return ret;
0168 }
0169 
0170 /**
0171  * Standard server done
0172  */
0173 void tpsvrdone(void)
0174 {
0175     /* nothing todo */
0176 }
0177 /**
0178  * Main entry for tmsrv
0179  */
0180 int main( int argc, char** argv )
0181 {
0182     _tmbuilt_with_thread_option=0;
0183     struct tmsvrargs_t tmsvrargs =
0184     {
0185         &tmnull_switch,
0186         &ndrx_G_tmdsptchtbl[0],
0187         0,
0188         tpsvrinit,
0189         tpsvrdone,
0190         NULL,
0191         NULL,
0192         NULL,
0193         NULL,
0194         NULL,
0195         NULL,
0196         NULL
0197     };
0198     
0199     return( _tmstartserver( argc, argv, &tmsvrargs ));
0200     
0201 }
0202 
0203 /* vim: set ts=4 sw=4 et smartindent: */