[Groonga-commit] groonga/groonga at 0dd6cbc [master] groonga-httpd: reuse grn_ctx

Back to archive index

Kouhei Sutou null+****@clear*****
Sat Nov 14 18:37:54 JST 2015


Kouhei Sutou	2015-11-14 18:37:54 +0900 (Sat, 14 Nov 2015)

  New Revision: 0dd6cbc554144b7fd58fe740619f3347e17c2be7
  https://github.com/groonga/groonga/commit/0dd6cbc554144b7fd58fe740619f3347e17c2be7

  Message:
    groonga-httpd: reuse grn_ctx
    
    It improves performance.

  Modified files:
    src/httpd/nginx-module/ngx_http_groonga_module.c

  Modified: src/httpd/nginx-module/ngx_http_groonga_module.c (+92 -144)
===================================================================
--- src/httpd/nginx-module/ngx_http_groonga_module.c    2015-11-14 17:23:44 +0900 (4012daf)
+++ src/httpd/nginx-module/ngx_http_groonga_module.c    2015-11-14 18:37:54 +0900 (22227cd)
@@ -50,7 +50,7 @@ typedef struct {
   char *config_file;
   int config_line;
   char *name;
-  grn_ctx context;
+  grn_obj *database;
   grn_cache *cache;
 } ngx_http_groonga_loc_conf_t;
 
@@ -62,7 +62,6 @@ typedef struct {
 
 typedef struct {
   grn_bool initialized;
-  grn_ctx context;
   struct {
     grn_bool processed;
     grn_bool header_sent;
@@ -78,21 +77,14 @@ typedef struct {
   } typed;
 } ngx_http_groonga_handler_data_t;
 
-typedef struct {
-  ngx_pool_t *pool;
-  ngx_open_file_t *file;
-} ngx_http_groonga_logger_data_t;
-
-typedef struct {
-  ngx_pool_t *pool;
-  ngx_open_file_t *file;
-  ngx_str_t *path;
-} ngx_http_groonga_query_logger_data_t;
-
 typedef void (*ngx_http_groonga_loc_conf_callback_pt)(ngx_http_groonga_loc_conf_t *conf, void *user_data);
 
 ngx_module_t ngx_http_groonga_module;
 
+static grn_ctx ngx_http_groonga_context;
+static grn_ctx *context = &ngx_http_groonga_context;
+static ngx_http_groonga_loc_conf_t *ngx_http_groonga_current_location_conf = NULL;
+
 static char *
 ngx_str_null_terminate(ngx_pool_t *pool, const ngx_str_t *string)
 {
@@ -169,7 +161,7 @@ ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level,
                             const char *message, const char *location,
                             void *user_data)
 {
-  ngx_http_groonga_logger_data_t *logger_data = user_data;
+  ngx_open_file_t *file = user_data;
   const char level_marks[] = " EACewnid-";
   u_char buffer[NGX_MAX_ERROR_STR];
   u_char *last;
@@ -179,6 +171,10 @@ ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level,
   size_t postfix_size;
   size_t log_message_size;
 
+  if (!file) {
+    return;
+  }
+
 #define LOG_PREFIX_FORMAT "%s|%c|%s"
   prefix_size =
     strlen(timestamp) +
@@ -200,17 +196,17 @@ ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level,
     last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR,
                         LOG_PREFIX_FORMAT,
                         timestamp, *(level_marks + level), title);
-    ngx_write_fd(logger_data->file->fd, buffer, last - buffer);
-    ngx_http_groonga_write_fd(logger_data->file->fd,
+    ngx_write_fd(file->fd, buffer, last - buffer);
+    ngx_http_groonga_write_fd(file->fd,
                               buffer, NGX_MAX_ERROR_STR,
                               message, message_size);
     if (location_size > 0) {
-      ngx_write_fd(logger_data->file->fd, " ", 1);
-      ngx_http_groonga_write_fd(logger_data->file->fd,
+      ngx_write_fd(file->fd, " ", 1);
+      ngx_http_groonga_write_fd(file->fd,
                                 buffer, NGX_MAX_ERROR_STR,
                                 location, location_size);
     }
-    ngx_write_fd(logger_data->file->fd, "\n", 1);
+    ngx_write_fd(file->fd, "\n", 1);
   } else {
     if (location && *location) {
       last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR,
@@ -222,7 +218,7 @@ ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level,
                           LOG_PREFIX_FORMAT " %s\n",
                           timestamp, *(level_marks + level), title, message);
     }
-    ngx_write_fd(logger_data->file->fd, buffer, last - buffer);
+    ngx_write_fd(file->fd, buffer, last - buffer);
   }
 #undef LOG_PREFIX_FORMAT
 }
@@ -238,9 +234,6 @@ ngx_http_groonga_logger_reopen(grn_ctx *ctx, void *user_data)
 static void
 ngx_http_groonga_logger_fin(grn_ctx *ctx, void *user_data)
 {
-  ngx_http_groonga_logger_data_t *logger_data = user_data;
-
-  ngx_pfree(logger_data->pool, logger_data);
 }
 
 static grn_logger ngx_http_groonga_logger = {
@@ -253,28 +246,17 @@ static grn_logger ngx_http_groonga_logger = {
 };
 
 static ngx_int_t
-ngx_http_groonga_context_init_logger(grn_ctx *context,
-                                     ngx_http_groonga_loc_conf_t *location_conf,
+ngx_http_groonga_context_init_logger(ngx_http_groonga_loc_conf_t *location_conf,
                                      ngx_pool_t *pool,
                                      ngx_log_t *log)
 {
-  ngx_http_groonga_logger_data_t *logger_data;
-
-  if (!location_conf->log_file) {
-    return NGX_OK;
-  }
-
-  logger_data = ngx_pcalloc(pool, sizeof(ngx_http_groonga_logger_data_t));
-  if (!logger_data) {
-    ngx_log_error(NGX_LOG_ERR, log, 0,
-                  "http_groonga: failed to allocate memory for logger");
-    return NGX_ERROR;
+  if (ngx_http_groonga_current_location_conf) {
+    ngx_http_groonga_current_location_conf->log_level =
+      grn_logger_get_max_level(context);
   }
 
-  logger_data->pool = pool;
-  logger_data->file = location_conf->log_file;
   ngx_http_groonga_logger.max_level = location_conf->log_level;
-  ngx_http_groonga_logger.user_data = logger_data;
+  ngx_http_groonga_logger.user_data = location_conf->log_file;
   grn_logger_set(context, &ngx_http_groonga_logger);
 
   return NGX_OK;
@@ -285,36 +267,29 @@ ngx_http_groonga_query_logger_log(grn_ctx *ctx, unsigned int flag,
                                   const char *timestamp, const char *info,
                                   const char *message, void *user_data)
 {
-  ngx_http_groonga_query_logger_data_t *data = user_data;
+  ngx_open_file_t *file = user_data;
   u_char buffer[NGX_MAX_ERROR_STR];
   u_char *last;
 
+  if (!file) {
+    return;
+  }
+
   last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR,
                       "%s|%s%s\n",
                       timestamp, info, message);
-  ngx_write_fd(data->file->fd, buffer, last - buffer);
+  ngx_write_fd(file->fd, buffer, last - buffer);
 }
 
 static void
 ngx_http_groonga_query_logger_reopen(grn_ctx *ctx, void *user_data)
 {
-  ngx_http_groonga_query_logger_data_t *data = user_data;
-
-  GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ",
-                "query log will be closed: <%.*s>",
-                (int)(data->path->len), data->path->data);
   ngx_reopen_files((ngx_cycle_t *)ngx_cycle, -1);
-  GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ",
-                "query log is opened: <%.*s>",
-                (int)(data->path->len), data->path->data);
 }
 
 static void
 ngx_http_groonga_query_logger_fin(grn_ctx *ctx, void *user_data)
 {
-  ngx_http_groonga_query_logger_data_t *data = user_data;
-
-  ngx_pfree(data->pool, data);
 }
 
 static grn_query_logger ngx_http_groonga_query_logger = {
@@ -326,71 +301,51 @@ static grn_query_logger ngx_http_groonga_query_logger = {
 };
 
 static ngx_int_t
-ngx_http_groonga_context_init_query_logger(grn_ctx *context,
-                                           ngx_http_groonga_loc_conf_t *location_conf,
+ngx_http_groonga_context_init_query_logger(ngx_http_groonga_loc_conf_t *location_conf,
                                            ngx_pool_t *pool,
                                            ngx_log_t *log)
 {
-  ngx_http_groonga_query_logger_data_t *query_logger_data;
-
-  if (!location_conf->query_log_file) {
-    return NGX_OK;
-  }
-
-  query_logger_data = ngx_pcalloc(pool,
-                                  sizeof(ngx_http_groonga_query_logger_data_t));
-  if (!query_logger_data) {
-    ngx_log_error(NGX_LOG_ERR, log, 0,
-                  "http_groonga: failed to allocate memory for query logger");
-    return NGX_ERROR;
-  }
-
-  query_logger_data->pool = pool;
-  query_logger_data->file = location_conf->query_log_file;
-  query_logger_data->path = &(location_conf->query_log_path);
-  ngx_http_groonga_query_logger.user_data = query_logger_data;
+  ngx_http_groonga_query_logger.user_data = location_conf->query_log_file;
   grn_query_logger_set(context, &ngx_http_groonga_query_logger);
 
   return NGX_OK;
 }
 
 static ngx_int_t
-ngx_http_groonga_context_init(grn_ctx *context,
-                              ngx_http_groonga_loc_conf_t *location_conf,
+ngx_http_groonga_context_init(ngx_http_groonga_loc_conf_t *location_conf,
                               ngx_pool_t *pool,
                               ngx_log_t *log)
 {
   ngx_int_t status;
 
-  grn_ctx_init(context, GRN_NO_FLAGS);
+  if (location_conf == ngx_http_groonga_current_location_conf) {
+    return NGX_OK;
+  }
 
-  status = ngx_http_groonga_context_init_logger(context,
-                                                location_conf,
+  status = ngx_http_groonga_context_init_logger(location_conf,
                                                 pool,
                                                 log);
   if (status == NGX_ERROR) {
-    grn_ctx_fin(context);
     return status;
   }
 
-  status = ngx_http_groonga_context_init_query_logger(context,
-                                                      location_conf,
+  status = ngx_http_groonga_context_init_query_logger(location_conf,
                                                       pool,
                                                       log);
   if (status == NGX_ERROR) {
-    grn_ctx_fin(context);
     return status;
   }
 
-  if (location_conf->cache) {
-    grn_cache_current_set(context, location_conf->cache);
-  }
+  grn_ctx_use(context, location_conf->database);
+  grn_cache_current_set(context, location_conf->cache);
+
+  ngx_http_groonga_current_location_conf = location_conf;
 
   return status;
 }
 
 static void
-ngx_http_groonga_context_log_error(ngx_log_t *log, grn_ctx *context)
+ngx_http_groonga_context_log_error(ngx_log_t *log)
 {
   if (context->rc == GRN_SUCCESS) {
     return;
@@ -400,12 +355,12 @@ ngx_http_groonga_context_log_error(ngx_log_t *log, grn_ctx *context)
 }
 
 static ngx_int_t
-ngx_http_groonga_context_check_error(ngx_log_t *log, grn_ctx *context)
+ngx_http_groonga_context_check_error(ngx_log_t *log)
 {
   if (context->rc == GRN_SUCCESS) {
     return NGX_OK;
   } else {
-    ngx_http_groonga_context_log_error(log, context);
+    ngx_http_groonga_context_log_error(log);
     return NGX_HTTP_BAD_REQUEST;
   }
 }
@@ -432,19 +387,14 @@ static void
 ngx_http_groonga_handler_cleanup(void *user_data)
 {
   ngx_http_groonga_handler_data_t *data = user_data;
-  grn_ctx *context;
 
   if (!data->initialized) {
     return;
   }
 
-  context = &(data->context);
   GRN_OBJ_FIN(context, &(data->typed.head));
   GRN_OBJ_FIN(context, &(data->typed.body));
   GRN_OBJ_FIN(context, &(data->typed.foot));
-  grn_logger_set(context, NULL);
-  grn_query_logger_set(context, NULL);
-  grn_ctx_fin(context);
 }
 
 static void
@@ -669,22 +619,18 @@ ngx_http_groonga_handler_create_data(ngx_http_request_t *r,
   ngx_http_cleanup_t *cleanup;
   ngx_http_groonga_handler_data_t *data;
 
-  grn_ctx *context;
-
   location_conf = ngx_http_get_module_loc_conf(r, ngx_http_groonga_module);
 
+  rc = ngx_http_groonga_context_init(location_conf, r->pool, r->connection->log);
+  if (rc != NGX_OK) {
+    return rc;
+  }
+
   cleanup = ngx_http_cleanup_add(r, sizeof(ngx_http_groonga_handler_data_t));
   cleanup->handler = ngx_http_groonga_handler_cleanup;
   data = cleanup->data;
   *data_return = data;
 
-  context = &(data->context);
-  rc = ngx_http_groonga_context_init(context, location_conf,
-                                     r->pool, r->connection->log);
-  if (rc != NGX_OK) {
-    return rc;
-  }
-
   data->initialized = GRN_TRUE;
 
   data->raw.processed = GRN_FALSE;
@@ -698,8 +644,8 @@ ngx_http_groonga_handler_create_data(ngx_http_request_t *r,
   GRN_TEXT_INIT(&(data->typed.body), GRN_NO_FLAGS);
   GRN_TEXT_INIT(&(data->typed.foot), GRN_NO_FLAGS);
 
-  grn_ctx_use(context, grn_ctx_db(&(location_conf->context)));
-  rc = ngx_http_groonga_context_check_error(r->connection->log, context);
+  grn_ctx_use(context, location_conf->database);
+  rc = ngx_http_groonga_context_check_error(r->connection->log);
   if (rc != NGX_OK) {
     return rc;
   }
@@ -716,16 +662,14 @@ ngx_http_groonga_handler_process_command_path(ngx_http_request_t *r,
                                               ngx_str_t *command_path,
                                               ngx_http_groonga_handler_data_t *data)
 {
-  grn_ctx *context;
   grn_obj uri;
 
-  context = &(data->context);
   GRN_TEXT_INIT(&uri, 0);
   GRN_TEXT_PUTS(context, &uri, "/d/");
   GRN_TEXT_PUT(context, &uri, command_path->data, command_path->len);
   grn_ctx_send(context, GRN_TEXT_VALUE(&uri), GRN_TEXT_LEN(&uri),
                GRN_NO_FLAGS);
-  ngx_http_groonga_context_log_error(r->connection->log, context);
+  ngx_http_groonga_context_log_error(r->connection->log);
   GRN_OBJ_FIN(context, &uri);
 
   return NGX_OK;
@@ -736,7 +680,6 @@ ngx_http_groonga_handler_validate_post_command(ngx_http_request_t *r,
                                                ngx_str_t *command_path,
                                                ngx_http_groonga_handler_data_t *data)
 {
-  grn_ctx *context;
   ngx_str_t command;
 
   command.data = command_path->data;
@@ -749,7 +692,6 @@ ngx_http_groonga_handler_validate_post_command(ngx_http_request_t *r,
     return NGX_OK;
   }
 
-  context = &(data->context);
   ngx_http_groonga_handler_set_content_type(r, "text/plain");
   GRN_TEXT_PUTS(context, &(data->typed.body),
                 "command for POST must be <load>: <");
@@ -760,8 +702,7 @@ ngx_http_groonga_handler_validate_post_command(ngx_http_request_t *r,
 }
 
 static ngx_int_t
-ngx_http_groonga_send_lines(grn_ctx *context,
-                            ngx_http_request_t *r,
+ngx_http_groonga_send_lines(ngx_http_request_t *r,
                             u_char *current,
                             u_char *last)
 {
@@ -776,7 +717,7 @@ ngx_http_groonga_send_lines(grn_ctx *context,
 
     grn_ctx_send(context, (const char *)line_start, current - line_start,
                  GRN_NO_FLAGS);
-    rc = ngx_http_groonga_context_check_error(r->connection->log, context);
+    rc = ngx_http_groonga_context_check_error(r->connection->log);
     if (rc != NGX_OK) {
       return rc;
     }
@@ -785,7 +726,7 @@ ngx_http_groonga_send_lines(grn_ctx *context,
   if (line_start < current) {
     grn_ctx_send(context, (const char *)line_start, current - line_start,
                  GRN_NO_FLAGS);
-    rc = ngx_http_groonga_context_check_error(r->connection->log, context);
+    rc = ngx_http_groonga_context_check_error(r->connection->log);
     if (rc != NGX_OK) {
       return rc;
     }
@@ -853,14 +794,10 @@ ngx_http_groonga_handler_process_body(ngx_http_request_t *r,
 {
   ngx_int_t rc;
 
-  grn_ctx *context;
-
   ngx_buf_t *body;
   u_char *body_data;
   u_char *body_data_end;
 
-  context = &(data->context);
-
   body = r->request_body->bufs->buf;
   if (!body) {
     ngx_http_groonga_handler_set_content_type(r, "text/plain");
@@ -876,7 +813,7 @@ ngx_http_groonga_handler_process_body(ngx_http_request_t *r,
     return rc;
   }
 
-  rc = ngx_http_groonga_send_lines(context, r, body_data, body_data_end);
+  rc = ngx_http_groonga_send_lines(r, body_data, body_data_end);
   ngx_pfree(r->pool, body_data);
 
   return rc;
@@ -937,7 +874,6 @@ ngx_http_groonga_handler_send_response(ngx_http_request_t *r,
                                        ngx_http_groonga_handler_data_t *data)
 {
   ngx_int_t rc;
-  grn_ctx *context;
   const char *content_type;
   ngx_buf_t *head_buf, *body_buf, *foot_buf;
   ngx_chain_t head_chain, body_chain, foot_chain;
@@ -947,8 +883,6 @@ ngx_http_groonga_handler_send_response(ngx_http_request_t *r,
     return data->raw.rc;
   }
 
-  context = &(data->context);
-
   /* set the 'Content-type' header */
   if (r->headers_out.content_type.len == 0) {
     content_type = grn_ctx_get_mime_type(context);
@@ -1255,16 +1189,17 @@ ngx_http_groonga_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
                             GRN_CACHE_DEFAULT_MAX_N_ENTRIES);
 
 #ifdef NGX_HTTP_GROONGA_LOG_PATH
-  if (!conf->log_file) {
-    ngx_str_t default_log_path;
-    default_log_path.data = (u_char *)NGX_HTTP_GROONGA_LOG_PATH;
-    default_log_path.len = strlen(NGX_HTTP_GROONGA_LOG_PATH);
-    conf->log_file = ngx_conf_open_file(cf->cycle, &default_log_path);
+  ngx_conf_merge_str_value(conf->log_path, prev->log_path,
+                           NGX_HTTP_GROONGA_LOG_PATH);
+  if (!conf->log_file &&
+      ngx_str_is_custom_path(&(conf->log_path)) &&
+      conf->enabled) {
+    conf->log_file = ngx_conf_open_file(cf->cycle, &(conf->log_path));
     if (!conf->log_file) {
       ngx_log_error(NGX_LOG_ERR, cf->cycle->log, 0,
                     "http_groonga: "
                     "failed to open the default groonga log file: <%V>",
-                    &default_log_path);
+                    &(conf->log_path));
       return NGX_CONF_ERROR;
     }
   }
@@ -1373,7 +1308,6 @@ ngx_http_groonga_create_database(ngx_http_groonga_loc_conf_t *location_conf,
                                  ngx_http_groonga_database_callback_data_t *data)
 {
   const char *database_base_name;
-  grn_ctx *context;
 
   database_base_name = strrchr(location_conf->database_path_cstr, '/');
   if (database_base_name) {
@@ -1388,8 +1322,8 @@ ngx_http_groonga_create_database(ngx_http_groonga_loc_conf_t *location_conf,
     }
   }
 
-  context = &(location_conf->context);
-  grn_db_create(context, location_conf->database_path_cstr, NULL);
+  location_conf->database =
+    grn_db_create(context, location_conf->database_path_cstr, NULL);
   if (context->rc == GRN_SUCCESS) {
     return;
   }
@@ -1405,11 +1339,16 @@ ngx_http_groonga_open_database_callback(ngx_http_groonga_loc_conf_t *location_co
                                         void *user_data)
 {
   ngx_http_groonga_database_callback_data_t *data = user_data;
-  grn_ctx *context;
 
-  context = &(location_conf->context);
-  data->rc = ngx_http_groonga_context_init(context, location_conf,
-                                           data->pool, data->log);
+  data->rc = ngx_http_groonga_context_init_logger(location_conf,
+                                                  data->pool,
+                                                  data->log);
+  if (data->rc != NGX_OK) {
+    return;
+  }
+  data->rc = ngx_http_groonga_context_init_query_logger(location_conf,
+                                                        data->pool,
+                                                        data->log);
   if (data->rc != NGX_OK) {
     return;
   }
@@ -1429,7 +1368,8 @@ ngx_http_groonga_open_database_callback(ngx_http_groonga_loc_conf_t *location_co
       ngx_str_null_terminate(data->pool, &(location_conf->database_path));
   }
 
-  grn_db_open(context, location_conf->database_path_cstr);
+  location_conf->database =
+    grn_db_open(context, location_conf->database_path_cstr);
   if (context->rc != GRN_SUCCESS) {
     if (location_conf->database_auto_create) {
       ngx_http_groonga_create_database(location_conf, data);
@@ -1438,6 +1378,8 @@ ngx_http_groonga_open_database_callback(ngx_http_groonga_loc_conf_t *location_co
                     "failed to open groonga database: %s",
                     context->errbuf);
       data->rc = NGX_ERROR;
+    }
+    if (data->rc != NGX_OK) {
       return;
     }
   }
@@ -1450,6 +1392,7 @@ ngx_http_groonga_open_database_callback(ngx_http_groonga_loc_conf_t *location_co
     data->rc = NGX_ERROR;
     return;
   }
+
   if (location_conf->cache_limit != NGX_CONF_UNSET_SIZE) {
     grn_cache_set_max_n_entries(context,
                                 location_conf->cache,
@@ -1462,26 +1405,20 @@ ngx_http_groonga_close_database_callback(ngx_http_groonga_loc_conf_t *location_c
                                          void *user_data)
 {
   ngx_http_groonga_database_callback_data_t *data = user_data;
-  grn_ctx *context;
 
-  context = &(location_conf->context);
-  ngx_http_groonga_context_init_logger(context,
-                                       location_conf,
+  ngx_http_groonga_context_init_logger(location_conf,
                                        data->pool,
                                        data->log);
-  ngx_http_groonga_context_init_query_logger(context,
-                                             location_conf,
+  ngx_http_groonga_context_init_query_logger(location_conf,
                                              data->pool,
                                              data->log);
   grn_cache_current_set(context, location_conf->cache);
 
-  grn_obj_close(context, grn_ctx_db(context));
-  ngx_http_groonga_context_log_error(data->log, context);
+  grn_obj_close(context, location_conf->database);
+  ngx_http_groonga_context_log_error(data->log);
 
   grn_cache_current_set(context, NULL);
   grn_cache_close(context, location_conf->cache);
-
-  grn_ctx_fin(context);
 }
 
 static ngx_int_t
@@ -1493,6 +1430,10 @@ ngx_http_groonga_init_process(ngx_cycle_t *cycle)
 
   grn_thread_set_get_limit_func(ngx_http_groonga_get_thread_limit, NULL);
 
+#ifdef NGX_HTTP_GROONGA_LOG_PATH
+  grn_default_logger_set_path(NGX_HTTP_GROONGA_LOG_PATH);
+#endif
+
   rc = grn_init();
   if (rc != GRN_SUCCESS) {
     return NGX_ERROR;
@@ -1500,6 +1441,11 @@ ngx_http_groonga_init_process(ngx_cycle_t *cycle)
 
   grn_set_segv_handler();
 
+  rc = grn_ctx_init(context, GRN_NO_FLAGS);
+  if (rc != GRN_SUCCESS) {
+    return NGX_ERROR;
+  }
+
   http_conf =
     (ngx_http_conf_ctx_t *)ngx_get_conf(cycle->conf_ctx, ngx_http_module);
 
@@ -1527,6 +1473,8 @@ ngx_http_groonga_exit_process(ngx_cycle_t *cycle)
                                  ngx_http_groonga_close_database_callback,
                                  &data);
 
+  grn_ctx_fin(context);
+
   grn_fin();
 
   return;
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index