root/src/noit_check_tools.c

Revision 4b96846179a35015ac0b22d5fe9e9f92480f06a5, 4.0 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 7 years ago)

check code consolidation. allow modules to be more terse and add convenience functions to make writing completely asynch checkers much easier. (add a postgres proof-of-concept asynch checker

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7 #include "noit_check_tools.h"
8
9 #include <assert.h>
10
11 typedef struct {
12   noit_module_t *self;
13   noit_check_t *check;
14   dispatch_func_t dispatch;
15 } recur_closure_t;
16
17 int
18 noit_check_interpolate(char *buff, int len, const char *fmt,
19                        noit_hash_table *attrs,
20                        noit_hash_table *config) {
21   char *copy = NULL;
22   char closer;
23   const char *fmte, *key;
24   int replaced_something = 1;
25   int iterations = 3;
26
27   while(replaced_something && iterations > 0) {
28     char *cp = buff, * const end = buff + len;
29     iterations--;
30     replaced_something = 0;
31     while(*fmt && cp < end) {
32       switch(*fmt) {
33         case '%':
34           if(fmt[1] == '{' || fmt[1] == '[') {
35             closer = (fmt[1] == '{') ? '}' : ']';
36             fmte = fmt + 2;
37             key = fmte;
38             while(*fmte && *fmte != closer) fmte++;
39             if(*fmte == closer) {
40               /* We have a full key here */
41               const char *replacement;
42               if(!noit_hash_retrieve((closer == '}') ?  config : attrs,
43                                      key, fmte - key, (void **)&replacement))
44                 replacement = "";
45               fmt = fmte + 1; /* Format points just after the end of the key */
46               strlcpy(cp, replacement, end-cp);
47               cp += strlen(cp);
48               replaced_something = 1;
49               break;
50             }
51           }
52         default:
53           *cp++ = *fmt++;
54       }
55     }
56     *cp = '\0';
57     if(copy) free(copy);
58     if(replaced_something)
59       copy = strdup(buff);
60     fmt = copy;
61   }
62   return strlen(buff);
63 }
64
65 static int
66 noit_check_recur_handler(eventer_t e, int mask, void *closure,
67                               struct timeval *now) {
68   recur_closure_t *rcl = closure;
69   rcl->check->fire_event = NULL; /* This is us, we get free post-return */
70   noit_check_schedule_next(rcl->self, &e->whence, rcl->check, now,
71                            rcl->dispatch);
72   rcl->dispatch(rcl->self, rcl->check);
73   free(rcl);
74   return 0;
75 }
76
77 int
78 noit_check_schedule_next(noit_module_t *self,
79                          struct timeval *last_check, noit_check_t *check,
80                          struct timeval *now, dispatch_func_t dispatch) {
81   eventer_t newe;
82   struct timeval period, earliest;
83   recur_closure_t *rcl;
84
85   assert(check->fire_event == NULL);
86   if(check->period == 0) return 0;
87   if(NOIT_CHECK_DISABLED(check) || NOIT_CHECK_KILLED(check)) return 0;
88
89   /* If we have an event, we know when we intended it to fire.  This means
90    * we should schedule that point + period.
91    */
92   if(now)
93     memcpy(&earliest, now, sizeof(earliest));
94   else
95     gettimeofday(&earliest, NULL);
96   period.tv_sec = check->period / 1000;
97   period.tv_usec = (check->period % 1000) * 1000;
98
99   newe = eventer_alloc();
100   memcpy(&newe->whence, last_check, sizeof(*last_check));
101   add_timeval(newe->whence, period, &newe->whence);
102   if(compare_timeval(newe->whence, earliest) < 0)
103     memcpy(&newe->whence, &earliest, sizeof(earliest));
104   newe->mask = EVENTER_TIMER;
105   newe->callback = noit_check_recur_handler;
106   rcl = calloc(1, sizeof(*rcl));
107   rcl->self = self;
108   rcl->check = check;
109   rcl->dispatch = dispatch;
110   newe->closure = rcl;
111
112   eventer_add(newe);
113   check->fire_event = newe;
114   return 0;
115 }
116
117 void
118 noit_check_run_full_asynch(noit_check_t *check, eventer_func_t callback) {
119   eventer_t e;
120   e = eventer_alloc();
121   e->fd = -1;
122   e->mask = EVENTER_ASYNCH;
123   memcpy(&e->whence, &__now, sizeof(__now));
124   p_int.tv_sec = check->timeout / 1000;
125   p_int.tv_usec = (check->timeout % 1000) * 1000;
126   add_timeval(e->whence, p_int, &e->whence);
127   e->callback = ssh2_connect_complete;
128   e->closure =  check->closure;
129   eventer_add(e);
130 }
131
132 void
133 noit_check_make_attrs(noit_check_t *check, noit_hash_table *attrs) {
134 #define CA_STORE(a,b) noit_hash_store(attrs, a, strlen(a), b)
135   CA_STORE("target", check->target);
136   CA_STORE("name", check->name);
137   CA_STORE("module", check->module);
138 }
139 void
140 noit_check_release_attrs(noit_hash_table *attrs) {
141   noit_hash_destroy(attrs, NULL, NULL);
142 }
Note: See TracBrowser for help on using the browser.