Merge branch 'master' of ssh://git.indexdata.com/home/git/pub/pazpar2
[pazpar2-moved-to-github.git] / src / http_command.c
index 567037f..f0dc440 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of Pazpar2.
-   Copyright (C) 2006-2010 Index Data
+   Copyright (C) 2006-2011 Index Data
 
 Pazpar2 is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -64,6 +64,23 @@ struct http_sessions {
     int log_level;
 };
 
+static YAZ_MUTEX g_http_session_mutex = 0;
+static int g_http_sessions = 0;
+
+int http_session_use(int delta)
+{
+    int sessions;
+    if (!g_http_session_mutex)
+        yaz_mutex_create(&g_http_session_mutex);
+    yaz_mutex_enter(g_http_session_mutex);
+    g_http_sessions += delta;
+    sessions = g_http_sessions;
+    yaz_mutex_leave(g_http_session_mutex);
+    yaz_log(YLOG_DEBUG, "%s sesions=%d", delta == 0 ? "" : (delta > 0 ? "INC" : "DEC"), sessions);
+    return sessions;
+
+}
+
 http_sessions_t http_sessions_create(void)
 {
     http_sessions_t hs = xmalloc(sizeof(*hs));
@@ -109,7 +126,7 @@ struct http_session *http_session_create(struct conf_service *service,
     char tmp_str[50];
 
     sprintf(tmp_str, "session#%u", sesid);
-    r->psession = new_session(nmem, service, tmp_str);
+    r->psession = new_session(nmem, service, sesid);
     r->session_id = sesid;
     r->timestamp = 0;
     r->nmem = nmem;
@@ -127,6 +144,7 @@ struct http_session *http_session_create(struct conf_service *service,
     iochan_settimeout(r->timeout_iochan, service->session_timeout);
 
     iochan_add(service->server->iochan_man, r->timeout_iochan);
+    http_session_use(1);
     return r;
 }
 
@@ -136,7 +154,7 @@ void http_session_destroy(struct http_session *s)
 
     http_sessions_t http_sessions = s->http_sessions;
 
-    yaz_log(http_sessions->log_level, "%p Session %u destroyed", s, s->session_id);
+    yaz_log(http_sessions->log_level, "%p HTTP Session %u destroyed", s, s->session_id);
     yaz_mutex_enter(http_sessions->mutex);
     /* only if http_session has no active http sessions on it can be destroyed */
     if (s->destroy_counter == s->activity_counter) {
@@ -152,13 +170,14 @@ void http_session_destroy(struct http_session *s)
     yaz_mutex_leave(http_sessions->mutex);
     if (must_destroy)
     {   /* destroying for real */
-        yaz_log(http_sessions->log_level, "%p Session %u destroyed", s, s->session_id);
+        yaz_log(http_sessions->log_level, "%p HTTP Session %u destroyed", s, s->session_id);
         iochan_destroy(s->timeout_iochan);
         destroy_session(s->psession);
+        http_session_use(-1);
         nmem_destroy(s->nmem);
     }
     else {
-        yaz_log(http_sessions->log_level, "%p Session %u destroyed delayed. Active clients (%d-%d). Waiting for new timeout.", 
+        yaz_log(http_sessions->log_level, "%p HTTP Session %u destroyed delayed. Active clients (%d-%d). Waiting for new timeout.",
                 s, s->session_id, s->activity_counter, s->destroy_counter);
     }
 
@@ -566,6 +585,49 @@ static void cmd_termlist(struct http_channel *c)
     release_session(c,s);
 }
 
+size_t session_get_memory_status(struct session *session);
+
+static void cmd_session_status(struct http_channel *c)
+{
+    struct http_response *rs = c->response;
+    struct http_session *s = locate_session(c);
+    size_t session_nmem;
+    if (!s)
+        return;
+
+    wrbuf_rewind(c->wrbuf);
+    wrbuf_puts(c->wrbuf, HTTP_COMMAND_RESPONSE_PREFIX "<sessionstatus><status>OK</status>\n");
+    wrbuf_printf(c->wrbuf, "<http_count>%u</http_count>\n", s->activity_counter);
+    wrbuf_printf(c->wrbuf, "<http_nmem>%zu</http_nmem>\n", nmem_total(s->nmem) );
+
+    session_nmem = session_get_memory_status(s->psession);
+    wrbuf_printf(c->wrbuf, "<session_nmem>%zu</session_nmem>\n", session_nmem);
+
+    wrbuf_puts(c->wrbuf, "</sessionstatus>\n");
+    rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(c->wrbuf));
+    http_send_response(c);
+    release_session(c,s);
+
+}
+
+int sessions_count(void);
+int clients_count(void);
+int resultsets_count(void);
+
+static void cmd_server_status(struct http_channel *c)
+{
+    struct http_response *rs = c->response;
+    int sessions   = sessions_count();
+    int clients    = clients_count();
+    int resultsets = resultsets_count();
+    wrbuf_rewind(c->wrbuf);
+    wrbuf_puts(c->wrbuf, HTTP_COMMAND_RESPONSE_PREFIX "<server-status><status>OK</status>\n");
+    wrbuf_printf(c->wrbuf, "Sessions %u Clients: %u Resultsets: %u\n</server-status>\n", sessions, clients, resultsets);
+    rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(c->wrbuf));
+    http_send_response(c);
+}
+
+
 
 static void cmd_bytarget(struct http_channel *c)
 {
@@ -936,7 +998,7 @@ static void cmd_show(struct http_channel *c)
 
     if (block)
     {
-        if (!strcmp(block, "preferred") && !session_is_preferred_clients_ready(s->psession)) {
+        if (!strcmp(block, "preferred") && !session_is_preferred_clients_ready(s->psession) && reclist_get_num_records(s->psession->reclist) == 0) {
             // if there is already a watch/block. we do not block this one
             if (session_set_watch(s->psession, SESSION_WATCH_SHOW_PREF,
                                   show_records_ready, c, c) != 0)
@@ -1103,6 +1165,8 @@ static void cmd_info(struct http_channel *c)
 
     wrbuf_puts(c->wrbuf, " </version>\n");
     
+    info_services(c->server, c->wrbuf);
+
     wrbuf_puts(c->wrbuf, "</info>");
     rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(c->wrbuf));
     http_send_response(c);
@@ -1120,6 +1184,8 @@ struct {
     { "search", cmd_search },
     { "termlist", cmd_termlist },
     { "exit", cmd_exit },
+    { "sessionstatus", cmd_session_status },
+    { "serverstatus", cmd_server_status },
     { "ping", cmd_ping },
     { "record", cmd_record },
     { "info", cmd_info },