uniretrygen.cc

00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 2002 Net Integration Technologies, Inc.
00004  * 
00005  * A UniConfGen that reconnects to an inner generator whenever the inner
00006  * generator is no longer OK.
00007  */
00008 #include "uniretrygen.h"
00009 #include "wvmoniker.h"
00010 #include "wvtclstring.h"
00011 #include "wvstringlist.h"
00012 #include "wvlinkerhack.h"
00013 
00014 WV_LINK(UniRetryGen);
00015 
00016 
00017 #if 0
00018 #define DPRINTF(format, args...) fprintf(stderr, format ,##args);
00019 #else
00020 #define DPRINTF if (0) printf
00021 #endif
00022 
00023 
00024 static IUniConfGen *creator(WvStringParm encoded_params)
00025 {
00026     DPRINTF("encoded_params = %s\n", encoded_params.cstr());
00027     WvStringList params;
00028     wvtcl_decode(params, encoded_params);
00029     if (params.count() == 0)
00030         return NULL;
00031         
00032     WvString moniker = params.popstr();
00033     if (params.count() == 0)
00034         return new UniRetryGen(moniker);
00035         
00036     WvString retry_interval_ms_str = params.popstr();
00037     time_t retry_interval_ms = retry_interval_ms_str.num();
00038     if (retry_interval_ms < 0)
00039         retry_interval_ms = 0;
00040     return new UniRetryGen(moniker, UniRetryGen::ReconnectCallback(),
00041             retry_interval_ms);
00042 }
00043 
00044 static WvMoniker<IUniConfGen> reg("retry", creator);
00045 
00046 
00047 /***** UniRetryGen *****/
00048 
00049 UniRetryGen::UniRetryGen(WvStringParm _moniker,
00050         ReconnectCallback _reconnect_callback,
00051         time_t _retry_interval_ms) 
00052     : UniFilterGen(NULL),
00053         log(WvString("UniRetryGen %s", _moniker), WvLog::Debug1),
00054         moniker(_moniker),
00055         reconnect_callback(_reconnect_callback),
00056         retry_interval_ms(_retry_interval_ms),
00057         next_reconnect_attempt(wvtime())
00058 {
00059     DPRINTF("UniRetryGen::UniRetryGen(%s, %ld)\n",
00060             moniker.cstr(), retry_interval_ms);
00061     
00062     maybe_reconnect();
00063 }
00064 
00065 
00066 void UniRetryGen::maybe_reconnect()
00067 {
00068     if (!inner())
00069     {
00070         if (!(wvtime() < next_reconnect_attempt))
00071         {
00072             IUniConfGen *gen = wvcreate<IUniConfGen>(moniker);
00073             
00074             if (!gen)
00075             {
00076                 DPRINTF("UniRetryGen::maybe_reconnect: !gen\n");
00077                 return;
00078             }
00079         
00080             if (gen->isok())
00081             {
00082                 DPRINTF("UniRetryGen::maybe_reconnect: gen->isok()\n");
00083                 
00084                 log("Connected\n");
00085                 
00086                 setinner(gen);
00087 
00088                 if (!!reconnect_callback) reconnect_callback(*this);
00089             }
00090             else
00091             {
00092                 DPRINTF("UniRetryGen::maybe_reconnect: !gen->isok()\n");
00093                 
00094                 WVRELEASE(gen);
00095                 
00096                 next_reconnect_attempt =
00097                         msecadd(next_reconnect_attempt, retry_interval_ms);
00098             }           
00099         }
00100     }
00101 }
00102 
00103 
00104 void UniRetryGen::maybe_disconnect()
00105 {
00106     if (inner() && !inner()->isok())
00107     {
00108         DPRINTF("UniRetryGen::maybe_disconnect: inner() && !inner()->isok()\n");
00109                 
00110         log("Disconnected\n");
00111         
00112         IUniConfGen *old_inner = inner();
00113         
00114         setinner(NULL);
00115         
00116         WVRELEASE(old_inner);
00117 
00118         next_reconnect_attempt = msecadd(wvtime(), retry_interval_ms);
00119     }
00120 }
00121 
00122 
00123 void UniRetryGen::commit()
00124 {
00125     maybe_reconnect();
00126     
00127     if (UniFilterGen::isok())
00128         UniFilterGen::commit();
00129     
00130     maybe_disconnect();
00131 }
00132 
00133 
00134 bool UniRetryGen::refresh()
00135 {
00136     maybe_reconnect();
00137     
00138     bool result;
00139     if (UniFilterGen::isok())
00140         result = UniFilterGen::refresh();
00141     else
00142         result = false;
00143     
00144     maybe_disconnect();
00145     
00146     return result;
00147 }
00148 
00149 
00150 void UniRetryGen::prefetch(const UniConfKey &key, bool recursive)
00151 {
00152     maybe_reconnect();
00153     
00154     if (UniFilterGen::isok())
00155         UniFilterGen::prefetch(key, recursive);
00156     
00157     maybe_disconnect();
00158 }
00159 
00160 
00161 WvString UniRetryGen::get(const UniConfKey &key)
00162 {
00163     maybe_reconnect();
00164     
00165     WvString result;
00166     if (UniFilterGen::isok())
00167     {
00168         result = UniFilterGen::get(key);
00169         DPRINTF("UniRetryGen::get(%s) returns %s\n", key.cstr(), result.cstr());
00170     }
00171     else if (key == "")
00172     {
00173         result = "";
00174         DPRINTF("UniRetryGen::get(%s) returns %s because it is root key\n", key.cstr(), result.cstr());        
00175     }
00176     else
00177     {
00178         DPRINTF("UniRetryGen::get(%s): !isok()\n", key.cstr());
00179         result = WvString::null;
00180     }
00181     
00182     maybe_disconnect();
00183 
00184     return result;
00185 }
00186 
00187 
00188 void UniRetryGen::set(const UniConfKey &key, WvStringParm value)
00189 {
00190     maybe_reconnect();
00191     
00192     if (UniFilterGen::isok())
00193         UniFilterGen::set(key, value);
00194     
00195     maybe_disconnect();
00196 }
00197 
00198 
00199 bool UniRetryGen::exists(const UniConfKey &key)
00200 {
00201     maybe_reconnect();
00202     
00203     DPRINTF("UniRetryGen::exists(%s)\n", key.cstr());
00204     
00205     bool result;
00206     if (UniFilterGen::isok())
00207     {
00208         result = UniFilterGen::exists(key);
00209         DPRINTF("UniRetryGen::exists: returns %s\n", result? "true": "false");
00210     }
00211     else
00212     {
00213         DPRINTF("UniRetryGen::exists: !isok()\n");
00214         if (key == "")
00215         {
00216             // here we assume that at least the mount point exists
00217             // see void UniMountGen::makemount() that create all the keys with
00218             // an empty string
00219             result = true;
00220         }
00221         else 
00222         {
00223             result = false;
00224         }
00225     }
00226     
00227     maybe_disconnect();
00228     
00229     return result;
00230 }
00231 
00232 
00233 bool UniRetryGen::haschildren(const UniConfKey &key)
00234 {
00235     maybe_reconnect();
00236     
00237     bool result;
00238     if (UniFilterGen::isok())
00239         result = UniFilterGen::haschildren(key);
00240     else
00241         result = false;
00242     
00243     maybe_disconnect();
00244     
00245     return result;
00246 }
00247 
00248 
00249 bool UniRetryGen::isok()
00250 {
00251     maybe_reconnect();
00252     
00253     bool result = UniFilterGen::isok();
00254     
00255     maybe_disconnect();
00256     
00257     return result;
00258 }
00259 
00260 
00261 UniConfGen::Iter *UniRetryGen::iterator(const UniConfKey &key)
00262 {
00263     maybe_reconnect();
00264     
00265     Iter *result;
00266     if (UniFilterGen::isok())
00267         result = UniFilterGen::iterator(key);
00268     else
00269         result = NULL;
00270     
00271     maybe_disconnect();
00272     
00273     return result;
00274 }
00275 
00276 
00277 UniConfGen::Iter *UniRetryGen::recursiveiterator(const UniConfKey &key)
00278 {
00279     maybe_reconnect();
00280     
00281     Iter *result = UniFilterGen::recursiveiterator(key);
00282     
00283     maybe_disconnect();
00284     
00285     return result;
00286 }

Generated on Fri Oct 5 18:20:26 2007 for WvStreams by  doxygen 1.5.3