X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;f=src%2Fsession.c;h=a48f69bd8037d830ad8bbc3a443ba6976ec757fd;hb=7087f7cc9945cfacfbe7341a1099eef773914772;hp=21a47294f11bd0133a8d3598ac830b9406dca1b3;hpb=29d7b058269704d060ab5a39c9cec515cd8d7d87;p=pazpar2-moved-to-github.git diff --git a/src/session.c b/src/session.c index 21a4729..a48f69b 100644 --- a/src/session.c +++ b/src/session.c @@ -405,12 +405,8 @@ static int prepare_map(struct session *se, struct session_database *sdb) { const char *s; - if (!sdb->settings) - { - session_log(se, YLOG_WARN, "No settings on %s", sdb->database->id); - return -1; - } - if ((s = session_setting_oneval(sdb, PZ_XSLT))) + if (sdb->settings && sdb->settings[PZ_XSLT] && !sdb->map && + (s = session_setting_oneval(sdb, PZ_XSLT))) { char auto_stylesheet[256]; @@ -445,25 +441,6 @@ static int prepare_map(struct session *se, struct session_database *sdb) return 0; } -// This analyzes settings and recomputes any supporting data structures -// if necessary. -static int prepare_session_database(struct session *se, - struct session_database *sdb) -{ - if (!sdb->settings) - { - session_log(se, YLOG_WARN, - "No settings associated with %s", sdb->database->id); - return -1; - } - if (sdb->settings[PZ_XSLT] && !sdb->map) - { - if (prepare_map(se, sdb) < 0) - return -1; - } - return 0; -} - // called if watch should be removed because http_channel is to be destroyed static void session_watch_cancel(void *data, struct http_channel *c, void *data2) @@ -530,26 +507,60 @@ void session_alert_watch(struct session *s, int what) static void select_targets_callback(struct session *se, struct session_database *db) { - struct client *cl = client_create(db->database->id); + struct client *cl; struct client_list *l; - client_set_database(cl, db); + for (l = se->clients_cached; l; l = l->next) + if (client_get_database(l->client) == db) + break; - client_set_session(cl, se); + if (l) + cl = l->client; + else + { + cl = client_create(db->database->id); + client_set_database(cl, db); + client_set_session(cl, se); + + l = xmalloc(sizeof(*l)); + l->client = cl; + l->next = se->clients_cached; + se->clients_cached = l; + } l = xmalloc(sizeof(*l)); l->client = cl; - l->next = se->clients; - se->clients = l; + l->next = se->clients_active; + se->clients_active = l; +} + +static void session_reset_active_clients(struct session *se, + struct client_list *new_list) +{ + struct client_list *l; + + session_enter(se); + l = se->clients_active; + se->clients_active = new_list; + session_leave(se); + + while (l) + { + struct client_list *l_next = l->next; + xfree(l); + l = l_next; + } } -static void session_remove_clients(struct session *se) +static void session_remove_cached_clients(struct session *se) { struct client_list *l; + session_reset_active_clients(se, 0); + session_enter(se); - l = se->clients; - se->clients = 0; + l = se->clients_cached; + se->clients_cached = 0; session_leave(se); while (l) @@ -578,7 +589,7 @@ int session_active_clients(struct session *s) struct client_list *l; int res = 0; - for (l = s->clients; l; l = l->next) + for (l = s->clients_active; l; l = l->next) if (client_is_active(l->client)) res++; @@ -590,7 +601,7 @@ int session_is_preferred_clients_ready(struct session *s) struct client_list *l; int res = 0; - for (l = s->clients; l; l = l->next) + for (l = s->clients_active; l; l = l->next) if (client_is_active_preferred(l->client)) res++; session_log(s, YLOG_DEBUG, "Has %d active preferred clients.", res); @@ -650,7 +661,7 @@ void session_sort(struct session *se, const char *field, int increasing) sr->next = se->sorted_results; se->sorted_results = sr; - for (l = se->clients; l; l = l->next) + for (l = se->clients_active; l; l = l->next) { struct client *cl = l->client; const char *strategy_plus_sort = get_strategy_plus_sort(cl, field); @@ -679,7 +690,7 @@ enum pazpar2_error_code session_search(struct session *se, int live_channels = 0; int no_working = 0; int no_failed = 0; - struct client_list *l; + struct client_list *l, *l0; struct timeval tval; facet_limits_t facet_limits; @@ -687,11 +698,15 @@ enum pazpar2_error_code session_search(struct session *se, *addinfo = 0; - session_remove_clients(se); + if (se->settings_modified) + session_remove_cached_clients(se); + else + session_reset_active_clients(se, 0); session_enter(se); reclist_destroy(se->reclist); se->reclist = 0; + se->settings_modified = 0; relevance_destroy(&se->relevance); nmem_reset(se->nmem); se->total_records = se->total_merged = 0; @@ -722,21 +737,27 @@ enum pazpar2_error_code session_search(struct session *se, session_leave(se); return PAZPAR2_MALFORMED_PARAMETER_VALUE; } - for (l = se->clients; l; l = l->next) + + l0 = se->clients_active; + se->clients_active = 0; + session_leave(se); + + for (l = l0; l; l = l->next) { + int parse_ret; struct client *cl = l->client; const char *strategy_plus_sort = get_strategy_plus_sort(cl, sort_field); - if (maxrecs) - client_set_maxrecs(cl, atoi(maxrecs)); - if (startrecs) - client_set_startrecs(cl, atoi(startrecs)); - if (prepare_session_database(se, client_get_database(cl)) < 0) - ; - else if (client_parse_query(cl, query, facet_limits) < 0) + if (prepare_map(se, client_get_database(cl)) < 0) + continue; + + parse_ret = client_parse_query(cl, query, facet_limits, startrecs, + maxrecs); + if (parse_ret < 0) no_failed++; - else + else if (parse_ret == 0) { + session_log(se, YLOG_LOG, "client NEW %s", client_get_id(cl)); no_working++; if (client_prep_connection(cl, se->service->z3950_operation_timeout, se->service->z3950_session_timeout, @@ -744,9 +765,22 @@ enum pazpar2_error_code session_search(struct session *se, &tval)) client_start_search(cl, strategy_plus_sort, increasing); } + else + { + session_log(se, YLOG_LOG, "client REUSE %s", client_get_id(cl)); + no_working++; + if (client_prep_connection(cl, se->service->z3950_operation_timeout, + se->service->z3950_session_timeout, + se->service->server->iochan_man, + &tval)) + { + client_reingest(cl); + } + } } facet_limits_destroy(facet_limits); - session_leave(se); + session_reset_active_clients(se, l0); + if (no_working == 0) { if (no_failed > 0) @@ -757,6 +791,7 @@ enum pazpar2_error_code session_search(struct session *se, else return PAZPAR2_NO_TARGETS; } + yaz_log(YLOG_LOG, "session_start_search done"); return PAZPAR2_NO_ERROR; } @@ -840,6 +875,8 @@ void session_apply_setting(struct session *se, char *dbname, char *setting, new->next = sdb->settings[offset]; sdb->settings[offset] = new; + se->settings_modified = 1; + // Force later recompute of settings-driven data structures // (happens when a search starts and client connections are prepared) switch (offset) @@ -853,11 +890,12 @@ void session_apply_setting(struct session *se, char *dbname, char *setting, } } -void session_destroy(struct session *se) { +void session_destroy(struct session *se) +{ struct session_database *sdb; session_log(se, YLOG_DEBUG, "Destroying"); session_use(-1); - session_remove_clients(se); + session_remove_cached_clients(se); for (sdb = se->databases; sdb; sdb = sdb->next) session_database_destroy(sdb); @@ -899,7 +937,9 @@ struct session *new_session(NMEM nmem, struct conf_service *service, session->number_of_warnings_unknown_metadata = 0; session->num_termlists = 0; session->reclist = 0; - session->clients = 0; + session->clients_active = 0; + session->clients_cached = 0; + session->settings_modified = 0; session->session_nmem = nmem; session->nmem = nmem_create(); session->databases = 0; @@ -924,12 +964,12 @@ static struct hitsbytarget *hitsbytarget_nb(struct session *se, struct client_list *l; size_t sz = 0; - for (l = se->clients; l; l = l->next) + for (l = se->clients_active; l; l = l->next) sz++; res = nmem_malloc(nmem, sizeof(*res) * sz); *count = 0; - for (l = se->clients; l; l = l->next) + for (l = se->clients_active; l; l = l->next) { struct client *cl = l->client; WRBUF w = wrbuf_alloc(); @@ -1171,7 +1211,7 @@ struct record_cluster **show_range_start(struct session *se, *total = reclist_get_num_records(se->reclist); *sumhits = 0; - for (l = se->clients; l; l = l->next) + for (l = se->clients_active; l; l = l->next) *sumhits += client_get_hits(l->client); for (i = 0; i < start; i++) @@ -1216,7 +1256,7 @@ void statistics(struct session *se, struct statistics *stat) memset(stat, 0, sizeof(*stat)); stat->num_hits = 0; - for (l = se->clients; l; l = l->next) + for (l = se->clients_active; l; l = l->next) { struct client *cl = l->client; if (!client_get_connection(cl))