WvStreams
uniretrygen.cc
1 /*
2  * Worldvisions Weaver Software:
3  * Copyright (C) 2002 Net Integration Technologies, Inc.
4  *
5  * A UniConfGen that reconnects to an inner generator whenever the inner
6  * generator is no longer OK.
7  */
8 #include "uniretrygen.h"
9 #include "wvmoniker.h"
10 #include "wvtclstring.h"
11 #include "wvstringlist.h"
12 #include "wvlinkerhack.h"
13 
14 WV_LINK(UniRetryGen);
15 
16 
17 #if 0
18 #define DPRINTF(format, args...) fprintf(stderr, format ,##args);
19 #else
20 #define DPRINTF if (0) printf
21 #endif
22 
23 
24 static IUniConfGen *creator(WvStringParm encoded_params, IObject *_obj)
25 {
26  DPRINTF("encoded_params = %s\n", encoded_params.cstr());
27  WvStringList params;
28  wvtcl_decode(params, encoded_params);
29  if (params.count() == 0)
30  return NULL;
31 
32  WvString moniker = params.popstr();
33  if (params.count() == 0)
34  return new UniRetryGen(moniker);
35 
36  WvString retry_interval_ms_str = params.popstr();
37  time_t retry_interval_ms = retry_interval_ms_str.num();
38  if (retry_interval_ms < 0)
39  retry_interval_ms = 0;
40  return new UniRetryGen(moniker,
41  UniRetryGen::ReconnectCallback(),
42  retry_interval_ms);
43 }
44 
45 static WvMoniker<IUniConfGen> reg("retry", creator);
46 
47 
48 /***** UniRetryGen *****/
49 
50 UniRetryGen::UniRetryGen(WvStringParm _moniker,
51  ReconnectCallback _reconnect_callback,
52  time_t _retry_interval_ms)
53  : UniFilterGen(NULL),
54  log(WvString("UniRetryGen %s", _moniker), WvLog::Debug1),
55  moniker(_moniker),
56  reconnect_callback(_reconnect_callback),
57  retry_interval_ms(_retry_interval_ms),
58  next_reconnect_attempt(wvtime())
59 {
60  DPRINTF("UniRetryGen::UniRetryGen(%s, %ld)\n",
61  moniker.cstr(), retry_interval_ms);
62 
63  maybe_reconnect();
64 }
65 
66 
67 void UniRetryGen::maybe_reconnect()
68 {
69  if (!inner())
70  {
71  if (!(wvtime() < next_reconnect_attempt))
72  {
73  IUniConfGen *gen = wvcreate<IUniConfGen>(moniker);
74 
75  if (!gen)
76  {
77  DPRINTF("UniRetryGen::maybe_reconnect: !gen\n");
78  return;
79  }
80 
81  if (gen->isok())
82  {
83  DPRINTF("UniRetryGen::maybe_reconnect: gen->isok()\n");
84 
85  log("Connected\n");
86 
87  setinner(gen);
88 
89  if (!!reconnect_callback) reconnect_callback(*this);
90  }
91  else
92  {
93  DPRINTF("UniRetryGen::maybe_reconnect: !gen->isok()\n");
94 
95  WVRELEASE(gen);
96 
97  next_reconnect_attempt =
98  msecadd(next_reconnect_attempt, retry_interval_ms);
99  }
100  }
101  }
102 }
103 
104 
105 void UniRetryGen::maybe_disconnect()
106 {
107  if (inner() && !inner()->isok())
108  {
109  DPRINTF("UniRetryGen::maybe_disconnect: inner() && !inner()->isok()\n");
110 
111  log("Disconnected\n");
112 
113  IUniConfGen *old_inner = inner();
114 
115  setinner(NULL);
116 
117  WVRELEASE(old_inner);
118 
119  next_reconnect_attempt = msecadd(wvtime(), retry_interval_ms);
120  }
121 }
122 
123 
125 {
126  maybe_reconnect();
127 
128  if (UniFilterGen::isok())
130 
131  maybe_disconnect();
132 }
133 
134 
136 {
137  maybe_reconnect();
138 
139  bool result;
140  if (UniFilterGen::isok())
141  result = UniFilterGen::refresh();
142  else
143  result = false;
144 
145  maybe_disconnect();
146 
147  return result;
148 }
149 
150 
151 void UniRetryGen::prefetch(const UniConfKey &key, bool recursive)
152 {
153  maybe_reconnect();
154 
155  if (UniFilterGen::isok())
156  UniFilterGen::prefetch(key, recursive);
157 
158  maybe_disconnect();
159 }
160 
161 
163 {
164  maybe_reconnect();
165 
166  WvString result;
167  if (UniFilterGen::isok())
168  {
169  result = UniFilterGen::get(key);
170  DPRINTF("UniRetryGen::get(%s) returns %s\n", key.printable().cstr(), result.cstr());
171  }
172  else if (key == "")
173  {
174  result = "";
175  DPRINTF("UniRetryGen::get(%s) returns %s because it is root key\n", key.printable().cstr(), result.cstr());
176  }
177  else
178  {
179  DPRINTF("UniRetryGen::get(%s): !isok()\n", key.printable().cstr());
180  result = WvString::null;
181  }
182 
183  maybe_disconnect();
184 
185  return result;
186 }
187 
188 
189 void UniRetryGen::set(const UniConfKey &key, WvStringParm value)
190 {
191  maybe_reconnect();
192 
193  if (UniFilterGen::isok())
194  UniFilterGen::set(key, value);
195 
196  maybe_disconnect();
197 }
198 
199 
201 {
202  maybe_reconnect();
203 
204  DPRINTF("UniRetryGen::exists(%s)\n", key.printable().cstr());
205 
206  bool result;
207  if (UniFilterGen::isok())
208  {
209  result = UniFilterGen::exists(key);
210  DPRINTF("UniRetryGen::exists: returns %s\n", result? "true": "false");
211  }
212  else
213  {
214  DPRINTF("UniRetryGen::exists: !isok()\n");
215  if (key == "")
216  {
217  // here we assume that at least the mount point exists
218  // see void UniMountGen::makemount() that create all the keys with
219  // an empty string
220  result = true;
221  }
222  else
223  {
224  result = false;
225  }
226  }
227 
228  maybe_disconnect();
229 
230  return result;
231 }
232 
233 
235 {
236  maybe_reconnect();
237 
238  bool result;
239  if (UniFilterGen::isok())
240  result = UniFilterGen::haschildren(key);
241  else
242  result = false;
243 
244  maybe_disconnect();
245 
246  return result;
247 }
248 
249 
251 {
252  maybe_reconnect();
253 
254  bool result = UniFilterGen::isok();
255 
256  maybe_disconnect();
257 
258  return result;
259 }
260 
261 
263 {
264  maybe_reconnect();
265 
266  Iter *result;
267  if (UniFilterGen::isok())
268  result = UniFilterGen::iterator(key);
269  else
270  result = NULL;
271 
272  maybe_disconnect();
273 
274  return result;
275 }
276 
277 
279 {
280  maybe_reconnect();
281 
282  Iter *result = UniFilterGen::recursiveiterator(key);
283 
284  maybe_disconnect();
285 
286  return result;
287 }
UniFilterGen::setinner
void setinner(IUniConfGen *inner)
Rebinds the inner generator and prepares its callback.
Definition: unifiltergen.cc:26
UniRetryGen
A UniConfGen that reconnects to an inner generator specified by a moniker whenever the inner generato...
Definition: uniretrygen.h:41
UniRetryGen::refresh
virtual bool refresh()
Refreshes information about a key recursively.
Definition: uniretrygen.cc:135
WvStringList::popstr
WvString popstr()
get the first string in the list, or an empty string if the list is empty.
Definition: wvstringlist.cc:55
UniFilterGen::set
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
Definition: unifiltergen.cc:93
wvtclstring.h
UniRetryGen::exists
virtual bool exists(const UniConfKey &key)
Without fetching its value, returns true if a key exists.
Definition: uniretrygen.cc:200
UniRetryGen::get
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
Definition: uniretrygen.cc:162
UniFilterGen::get
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
Definition: unifiltergen.cc:76
UniConfKey::printable
WvString printable() const
Returns the canonical string representation of the path.
Definition: uniconfkey.cc:212
UniFilterGen::iterator
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
Definition: unifiltergen.cc:137
UniRetryGen::set
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
Definition: uniretrygen.cc:189
UniRetryGen::commit
virtual void commit()
Commits any changes.
Definition: uniretrygen.cc:124
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
IUniConfGen
An abstract data container that backs a UniConf tree.
Definition: uniconfgen.h:39
WvLog
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's.
Definition: wvlog.h:56
UniRetryGen::isok
virtual bool isok()
Determines if the generator is usable and working properly.
Definition: uniretrygen.cc:250
WvFastString::cstr
const char * cstr() const
return a (const char *) for this string.
Definition: wvstring.h:267
UniConfKey
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition: uniconfkey.h:38
WvMoniker
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Definition: wvmoniker.h:61
UniFilterGen::isok
virtual bool isok()
Determines if the generator is usable and working properly.
Definition: unifiltergen.cc:128
UniFilterGen::inner
IUniConfGen * inner() const
Returns the inner generator.
Definition: unifiltergen.h:33
IObject
Definition: IObject.h:65
UniRetryGen::haschildren
virtual bool haschildren(const UniConfKey &key)
Returns true if a key has children.
Definition: uniretrygen.cc:234
IUniConfGen::isok
virtual bool isok()=0
Determines if the generator is usable and working properly.
UniFilterGen::exists
virtual bool exists(const UniConfKey &key)
Without fetching its value, returns true if a key exists.
Definition: unifiltergen.cc:108
UniRetryGen::iterator
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
Definition: uniretrygen.cc:262
UniFilterGen::refresh
virtual bool refresh()
Refreshes information about a key recursively.
Definition: unifiltergen.cc:59
WvStringList
This is a WvList of WvStrings, and is a really handy way to parse strings.
Definition: wvstringlist.h:27
UniRetryGen::prefetch
virtual void prefetch(const UniConfKey &key, bool recursive)
Indicate that we will eventually be interested in doing get(), haschildren(), or other "get-like" ope...
Definition: uniretrygen.cc:151
UniFilterGen::commit
virtual void commit()
Commits any changes.
Definition: unifiltergen.cc:52
wvtcl_decode
void wvtcl_decode(WvList< WvString > &l, WvStringParm _s, const WvStringMask &splitchars=WVTCL_SPLITCHARS, bool do_unescape=true)
split a tcl-style list.
Definition: wvtclstring.cc:386
UniFilterGen::haschildren
virtual bool haschildren(const UniConfKey &key)
Returns true if a key has children.
Definition: unifiltergen.cc:118
UniFilterGen::prefetch
virtual void prefetch(const UniConfKey &key, bool recursive)
Indicate that we will eventually be interested in doing get(), haschildren(), or other "get-like" ope...
Definition: unifiltergen.cc:68
UniRetryGen::recursiveiterator
virtual Iter * recursiveiterator(const UniConfKey &key)
Like iterator(), but the returned iterator is recursive, that is, it will return children of the imme...
Definition: uniretrygen.cc:278
WvFastString::num
int num() const
Return a stdc++ string with the contents of this string.
Definition: wvstring.h:286
UniFilterGen::recursiveiterator
virtual Iter * recursiveiterator(const UniConfKey &key)
Like iterator(), but the returned iterator is recursive, that is, it will return children of the imme...
Definition: unifiltergen.cc:147
UniFilterGen
A UniConfGen that delegates all requests to an inner generator.
Definition: unifiltergen.h:17
UniConfGen::Iter
An abstract iterator over keys and values in a generator.
Definition: uniconfgen.h:323