]> granicus.if.org Git - apache/commitdiff
Add the file logic for the handler.
authorJean-Frederic Clere <jfclere@apache.org>
Thu, 30 Jul 2009 15:37:22 +0000 (15:37 +0000)
committerJean-Frederic Clere <jfclere@apache.org>
Thu, 30 Jul 2009 15:37:22 +0000 (15:37 +0000)
(Next step add the slotmem logic for the multicast socket).

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@799334 13f79535-47bb-0310-9956-ffa450edef68

modules/cluster/mod_heartmonitor.c

index 4d95d0b38751b41ace20d663fce9774f2820fe6d..f24ae27b51a181d2fc651a44268c421a102599fc 100644 (file)
@@ -203,6 +203,188 @@ static  apr_status_t  hm_slotmem_update_stat(hm_server_t *s, request_rec *r)
     }
     return APR_SUCCESS;
 }
+/* Copied from mod_lbmethod_heartbeat.c... */
+static void
+argstr_to_table(apr_pool_t *p, char *str, apr_table_t *parms)
+{
+    char *key;
+    char *value;
+    char *strtok_state;
+    
+    key = apr_strtok(str, "&", &strtok_state);
+    while (key) {
+        value = strchr(key, '=');
+        if (value) {
+            *value = '\0';      /* Split the string in two */
+            value++;            /* Skip passed the = */
+        }
+        else {
+            value = "1";
+        }
+        ap_unescape_url(key);
+        ap_unescape_url(value);
+        apr_table_set(parms, key, value);
+        /*
+         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Found query arg: %s = %s", key, value);
+         */
+        key = apr_strtok(NULL, "&", &strtok_state);
+    }
+}
+static apr_status_t hm_file_update_stat(hm_ctx_t *ctx, hm_server_t *s, apr_pool_t *pool)
+{
+    apr_status_t rv;
+    apr_file_t *fp;
+    apr_file_t *fpin;
+    apr_hash_index_t *hi;
+    apr_time_t now;
+    unsigned int fage;
+    apr_finfo_t fi;
+    int updated = 0;
+    char *path = apr_pstrcat(pool, ctx->storage_path, ".tmp.XXXXXX", NULL);
+
+
+    /* TODO: Update stats file (!) */
+    rv = apr_file_mktemp(&fp, path, APR_CREATE | APR_WRITE, pool);
+
+    if (rv) {
+        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+                     "Heartmonitor: Unable to open tmp file: %s", path);
+        return rv;
+    }
+    rv = apr_file_open(&fpin, ctx->storage_path, APR_READ|APR_BINARY|APR_BUFFERED,
+                       APR_OS_DEFAULT, pool);
+
+    now = apr_time_now();
+    if (rv == APR_SUCCESS) {
+        char *t;
+        apr_table_t *hbt = apr_table_make(pool, 10);
+        apr_bucket_alloc_t *ba = apr_bucket_alloc_create(pool);
+        apr_bucket_brigade *bb = apr_brigade_create(pool, ba);
+        apr_bucket_brigade *tmpbb = apr_brigade_create(pool, ba);
+        rv = apr_file_info_get(&fi, APR_FINFO_SIZE | APR_FINFO_MTIME, fpin);
+        if (rv) {
+            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+                         "Heartmonitor: Unable to read file: %s", ctx->storage_path);
+            return rv;
+        }
+
+        /* Read the file and update the line corresponding to the node */
+        ba = apr_bucket_alloc_create(pool);
+        bb = apr_brigade_create(pool, ba);
+        apr_brigade_insert_file(bb, fpin, 0, fi.size, pool);
+        tmpbb = apr_brigade_create(pool, ba);
+        fage = (unsigned int) apr_time_sec(now - fi.mtime);
+        do {
+            char buf[4096];
+            const char *ip;
+            apr_size_t bsize = sizeof(buf);
+            apr_brigade_cleanup(tmpbb);
+            if (APR_BRIGADE_EMPTY(bb)) {
+                break;
+            } 
+            rv = apr_brigade_split_line(tmpbb, bb,
+                                        APR_BLOCK_READ, sizeof(buf));
+       
+            if (rv) {
+                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+                             "Heartmonitor: Unable to read from file: %s", ctx->storage_path);
+                return rv;
+            }
+
+            apr_brigade_flatten(tmpbb, buf, &bsize);
+            if (bsize == 0) {
+                break;
+            }
+            buf[bsize - 1] = 0;
+            t = strchr(buf, ' ');
+            if (t) {
+                ip = apr_pstrndup(pool, buf, t - buf);
+            } else {
+                ip = NULL;
+            }
+            if (!ip || buf[0] == '#') {
+                /* copy things we can't process */
+                apr_file_printf(fp, "%s\n", buf);
+            } else if (strcmp(ip, s->ip) !=0 ) {
+                hm_server_t node; 
+                unsigned int seen;
+                /* Update seen time according to the last file modification */
+                apr_table_clear(hbt);
+                argstr_to_table(pool, apr_pstrdup(pool, t), hbt);
+                if (apr_table_get(hbt, "busy")) {
+                    node.busy = atoi(apr_table_get(hbt, "busy"));
+                }
+
+                if (apr_table_get(hbt, "ready")) {
+                    node.ready = atoi(apr_table_get(hbt, "ready"));
+                }
+
+                if (apr_table_get(hbt, "lastseen")) {
+                    node.seen = atoi(apr_table_get(hbt, "lastseen"));
+                } 
+                seen = fage + node.seen;
+                apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u\n",
+                                ip, node.ready, node.busy, (unsigned int) seen);
+            } else {
+                apr_time_t seen;
+                seen = apr_time_sec(now - s->seen);
+                apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u\n",
+                                s->ip, s->ready, s->busy, (unsigned int) seen);
+                updated = 1;
+            }
+        } while (1);
+    }
+
+    if (!updated) {
+        apr_time_t seen;
+        seen = apr_time_sec(now - s->seen);
+        apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u\n",
+                        s->ip, s->ready, s->busy, (unsigned int) seen);
+    }
+
+    rv = apr_file_flush(fp);
+    if (rv) {
+      ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+                   "Heartmonitor: Unable to flush file: %s", path);
+      return rv;
+    }
+
+    rv = apr_file_close(fp);
+    if (rv) {
+      ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+                   "Heartmonitor: Unable to close file: %s", path);
+      return rv;
+    }
+  
+    rv = apr_file_perms_set(path,
+                            APR_FPROT_UREAD | APR_FPROT_GREAD |
+                            APR_FPROT_WREAD);
+    if (rv && rv != APR_INCOMPLETE) {
+        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+                     "Heartmonitor: Unable to set file permssions on %s",
+                     path);
+        return rv;
+    }
+
+    rv = apr_file_rename(path, ctx->storage_path, pool);
+
+    if (rv) {
+        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+                     "Heartmonitor: Unable to move file: %s -> %s", path,
+                     ctx->storage_path);
+        return rv;
+    }
+
+    return APR_SUCCESS;
+}
+static  apr_status_t  hm_update_stat(hm_ctx_t *ctx, hm_server_t *s, request_rec *r)
+{
+    if (slotmem)
+        return hm_slotmem_update_stat(s, r);
+    else
+        return hm_file_update_stat(ctx, s, r->pool);
+}
 
 /* Store in a file */
 static apr_status_t hm_file_update_stats(hm_ctx_t *ctx, apr_pool_t *p)
@@ -504,6 +686,8 @@ static int hm_handler(request_rec *r)
     apr_table_t *tbl;
     hm_server_t hmserver;
     char *ip;
+    hm_ctx_t *ctx = ap_get_module_config(r->server->module_config,
+                                         &heartmonitor_module);
 
     if (strcmp(r->handler, "hearthbeat")) {
         return DECLINED;
@@ -528,7 +712,7 @@ static int hm_handler(request_rec *r)
     hmserver.busy = atoi(apr_table_get(tbl, "busy"));
     hmserver.ready = atoi(apr_table_get(tbl, "ready"));
     hmserver.seen = apr_time_now();
-    hm_slotmem_update_stat(&hmserver, r);
+    hm_update_stat(ctx, &hmserver, r);
 
     ap_set_content_type(r, "text/plain");
     ap_set_content_length(r, 2);