Skip to content

Commit 6adeff5

Browse files
author
Rishitha Kalicheti
committed
{182781126} fix api_history_hung
Signed-off-by: Rishitha Kalicheti <rkalicheti1@bloomberg.com>
1 parent 0f66630 commit 6adeff5

File tree

13 files changed

+267
-150
lines changed

13 files changed

+267
-150
lines changed

db/api_history.c

Lines changed: 24 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,12 @@
2121
#include <pthread.h>
2222
#include <string.h>
2323

24+
#include "comdb2.h"
2425
#include "logmsg.h"
26+
#include "sql.h"
2527

2628
#include "api_history.h"
2729

28-
struct api_history {
29-
hash_t *entries;
30-
pthread_rwlock_t lock;
31-
};
32-
3330
static int hash_entry(api_driver_t *entry, int len)
3431
{
3532
return hash_default_fixedwidth((unsigned char*)entry->name, strlen(entry->name));
@@ -73,101 +70,55 @@ static int free_entry(api_driver_t *entry, void *arg)
7370
return 0;
7471
}
7572

76-
void acquire_api_history_lock(api_history_t *api_history, int write)
77-
{
78-
if (write) {
79-
Pthread_rwlock_wrlock(&api_history->lock);
80-
} else {
81-
Pthread_rwlock_rdlock(&api_history->lock);
82-
}
83-
}
84-
85-
void release_api_history_lock(api_history_t *api_history)
86-
{
87-
Pthread_rwlock_unlock(&api_history->lock);
88-
}
89-
9073
api_history_t *init_api_history()
9174
{
92-
api_history_t *api_history = malloc(sizeof(api_history_t));
93-
assert(api_history);
94-
Pthread_rwlock_init(&api_history->lock, NULL);
95-
96-
api_history->entries = hash_init_user((hashfunc_t *)hash_entry, (cmpfunc_t *)compare_entries, 0, 0);
97-
if (!api_history->entries) {
75+
api_history_t *api_history = hash_init_user((hashfunc_t *)hash_entry, (cmpfunc_t *)compare_entries, 0, 0);
76+
if (!api_history) {
9877
logmsg(LOGMSG_FATAL, "Unable to initialize api history.\n");
9978
abort();
10079
}
101-
80+
10281
return api_history;
10382
}
10483

105-
int free_api_history(api_history_t *api_history)
84+
void free_api_history(api_history_t *api_history)
10685
{
10786
assert(api_history);
108-
acquire_api_history_lock(api_history, 1);
109-
110-
int rc = hash_for(api_history->entries, (hashforfunc_t *)free_entry, NULL);
111-
if (rc) {
112-
logmsg(LOGMSG_FATAL, "Unable to free api history entries.\n");
113-
release_api_history_lock(api_history);
114-
return rc;
115-
}
116-
117-
hash_free(api_history->entries);
118-
release_api_history_lock(api_history);
119-
Pthread_rwlock_destroy(&api_history->lock);
120-
free(api_history);
121-
return 0;
87+
hash_for(api_history, (hashforfunc_t *)free_entry, NULL);
88+
hash_free(api_history);
12289
}
12390

124-
api_driver_t *get_next_api_history_entry(api_history_t *api_history, void **curr, unsigned int *iter)
91+
int get_num_api_history_entries(struct rawnodestats *stats)
12592
{
126-
assert(api_history);
127-
acquire_api_history_lock(api_history, 0);
128-
api_driver_t *entry;
129-
130-
if (!*curr && !*iter) {
131-
entry = (api_driver_t *)hash_first(api_history->entries, curr, iter);
132-
} else {
133-
entry = (api_driver_t *)hash_next(api_history->entries, curr, iter);
134-
}
135-
136-
release_api_history_lock(api_history);
137-
return entry;
138-
}
139-
140-
int get_num_api_history_entries(api_history_t *api_history) {
141-
assert(api_history);
142-
acquire_api_history_lock(api_history, 0);
143-
144-
int num = hash_get_num_entries(api_history->entries);
145-
146-
release_api_history_lock(api_history);
93+
assert(stats);
94+
Pthread_mutex_lock(&stats->lk);
95+
int num = stats->api_history ? hash_get_num_entries(stats->api_history) : 0;
96+
Pthread_mutex_unlock(&stats->lk);
14797
return num;
14898
}
14999

150-
int update_api_history(api_history_t *api_history, char *api_driver_name, char *api_driver_version)
100+
int update_api_history(struct sqlclntstate *clnt)
151101
{
152-
assert(api_history);
153-
acquire_api_history_lock(api_history, 1);
154-
155-
api_driver_t *search_entry = create_entry(api_driver_name, api_driver_version);
156-
api_driver_t *found_entry = hash_find(api_history->entries, search_entry);
157-
102+
assert(clnt && clnt->rawnodestats);
103+
struct rawnodestats *stats = clnt->rawnodestats;
104+
105+
Pthread_mutex_lock(&stats->lk);
106+
api_driver_t *search_entry = create_entry(clnt->api_driver_name, clnt->api_driver_version);
107+
api_driver_t *found_entry = hash_find(stats->api_history, search_entry);
108+
158109
if (found_entry) {
159110
time(&found_entry->last_seen);
160111
free_entry(search_entry, NULL);
161112
} else {
162113
time(&search_entry->last_seen);
163-
int rc = hash_add(api_history->entries, search_entry);
114+
int rc = hash_add(stats->api_history, search_entry);
164115
if (rc) {
116+
Pthread_mutex_unlock(&stats->lk);
165117
logmsg(LOGMSG_FATAL, "Unable to add api history entry.\n");
166-
release_api_history_lock(api_history);
167118
return rc;
168119
}
169120
}
170121

171-
release_api_history_lock(api_history);
122+
Pthread_mutex_unlock(&stats->lk);
172123
return 0;
173124
}

db/api_history.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,22 @@
1818
#define _API_HISTORY_H_
1919

2020
#include <sys/time.h>
21+
#include <plhash_glue.h>
2122

2223
typedef struct api_driver {
2324
char *name;
2425
char *version;
2526
time_t last_seen;
2627
} api_driver_t;
2728

28-
typedef struct api_history api_history_t;
29+
typedef hash_t api_history_t; // holds api_driver_t entries, keyed by name+version
30+
31+
struct sqlclntstate;
32+
struct rawnodestats;
2933

30-
void acquire_api_history_lock(api_history_t*, int);
31-
void release_api_history_lock(api_history_t*);
3234
api_history_t *init_api_history();
33-
int free_api_history(api_history_t*);
34-
api_driver_t *get_next_api_history_entry(api_history_t*, void**, unsigned int*);
35-
int get_num_api_history_entries(api_history_t*);
36-
int update_api_history(api_history_t*, char*, char*);
35+
void free_api_history(api_history_t *);
36+
int get_num_api_history_entries(struct rawnodestats *);
37+
int update_api_history(struct sqlclntstate *);
3738

3839
#endif

db/comdb2.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ void berk_memp_sync_alarm_ms(int);
8080
#include "sql.h"
8181
#include "logmsg.h"
8282
#include "reqlog.h"
83+
#include "reqlog_int.h"
8384

8485
#include "comdb2_trn_intrl.h"
8586
#include "history.h"
@@ -1800,6 +1801,7 @@ void clean_exit(void)
18001801

18011802
backend_cleanup(thedb);
18021803
net_cleanup();
1804+
cleanup_clientstats();
18031805

18041806
if (gbl_ssl_ctx != NULL) {
18051807
SSL_CTX_free(gbl_ssl_ctx);

db/reqlog.c

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2550,6 +2550,7 @@ static void update_clientstats_cache(nodestats_t *entry) {
25502550
Pthread_mutex_unlock(&clientstats_cache_mtx);
25512551
}
25522552

2553+
static int free_nodestats_entry(void *elem, void *unused);
25532554
static nodestats_t *add_clientstats(unsigned checksum, const char *whoami, int task_len, int stack_len, int id_len,
25542555
char *host, int node, int fd)
25552556
{
@@ -2582,15 +2583,7 @@ static nodestats_t *add_clientstats(unsigned checksum, const char *whoami, int t
25822583
nodestats_t *old_entry = listc_rtl(&clientstats_cache);
25832584
if (old_entry) {
25842585
hash_del(clientstats, old_entry);
2585-
if (old_entry->rawtotals.fingerprints) {
2586-
hash_for(old_entry->rawtotals.fingerprints, hash_free_element, NULL);
2587-
hash_free(old_entry->rawtotals.fingerprints);
2588-
}
2589-
free_api_history(old_entry->rawtotals.api_history);
2590-
time_metric_free(old_entry->rawtotals.svc_time);
2591-
Pthread_mutex_destroy(&old_entry->mtx);
2592-
Pthread_mutex_destroy(&old_entry->rawtotals.lk);
2593-
free(old_entry);
2586+
free_nodestats_entry(old_entry, NULL);
25942587
} else {
25952588
break;
25962589
}
@@ -2664,7 +2657,6 @@ static int release_clientstats(unsigned checksum, int node)
26642657
rc = -1;
26652658
goto done;
26662659
}
2667-
26682660
Pthread_mutex_lock(&entry->mtx);
26692661
entry->ref--;
26702662
update_clientstats_cache(entry);
@@ -2676,20 +2668,34 @@ static int release_clientstats(unsigned checksum, int node)
26762668
return rc;
26772669
}
26782670

2679-
nodestats_t *get_next_clientstats_entry(void **curr, unsigned int *iter)
2671+
static int free_nodestats_entry(void *elem, void *unused)
26802672
{
2681-
assert(clientstats);
2682-
acquire_clientstats_lock(0);
2683-
nodestats_t *entry;
2684-
2685-
if (!*curr && !*iter) {
2686-
entry = (nodestats_t *)hash_first(clientstats, curr, iter);
2687-
} else {
2688-
entry = (nodestats_t *)hash_next(clientstats, curr, iter);
2673+
nodestats_t *entry = (nodestats_t *)elem;
2674+
if (entry->rawtotals.fingerprints) {
2675+
hash_for(entry->rawtotals.fingerprints, hash_free_element, NULL);
2676+
hash_free(entry->rawtotals.fingerprints);
26892677
}
2690-
2678+
free_api_history(entry->rawtotals.api_history);
2679+
time_metric_free(entry->rawtotals.svc_time);
2680+
Pthread_mutex_destroy(&entry->mtx);
2681+
Pthread_mutex_destroy(&entry->rawtotals.lk);
2682+
free(entry);
2683+
return 0;
2684+
}
2685+
2686+
void cleanup_clientstats(void)
2687+
{
2688+
acquire_clientstats_lock(1);
2689+
hash_for(clientstats, free_nodestats_entry, NULL);
2690+
hash_free(clientstats);
2691+
clientstats = NULL;
26912692
release_clientstats_lock();
2692-
return entry;
2693+
}
2694+
2695+
int hash_for_clientstats(hashforfunc_t *func, void *arg)
2696+
{
2697+
assert(clientstats);
2698+
return hash_for(clientstats, func, arg);
26932699
}
26942700

26952701
struct rawnodestats *get_raw_node_stats(const char *task, const char *stack, const char *id, char *host, int fd,

db/reqlog_int.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "cson.h"
77
#include "sql.h"
88
#include "reqlog.h"
9+
#include <plhash_glue.h>
910

1011
/* This used to be private to reqlog. Moving to a shared header since
1112
eventlog also needs access to reqlog internals. I am not sure
@@ -242,7 +243,8 @@ typedef struct nodestats {
242243

243244
void acquire_clientstats_lock(int);
244245
void release_clientstats_lock();
245-
nodestats_t *get_next_clientstats_entry(void**, unsigned int*);
246+
void cleanup_clientstats(void);
247+
int hash_for_clientstats(hashforfunc_t *func, void *arg);
246248

247249
extern int gbl_time_fdb;
248250

db/sqlinterfaces.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ static void sql_statement_done(struct sql_thread *thd, struct reqlogger *logger,
13541354
if (have_fingerprint)
13551355
add_fingerprint_to_rawstats(clnt->rawnodestats, fingerprint, cost,
13561356
rows, time);
1357-
update_api_history(clnt->rawnodestats->api_history, clnt->api_driver_name, clnt->api_driver_version);
1357+
update_api_history(clnt);
13581358
}
13591359

13601360
reset_sql_steps(thd);

lua/sp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2371,7 +2371,7 @@ static void lua_end_step(struct sqlclntstate *clnt, SP sp,
23712371
put_ref(&sql_ref);
23722372
if (clnt->rawnodestats) {
23732373
add_fingerprint_to_rawstats(clnt->rawnodestats, fingerprint, cost, pVdbe->luaRows, timeMs);
2374-
update_api_history(clnt->rawnodestats->api_history, clnt->api_driver_name, clnt->api_driver_version);
2374+
update_api_history(clnt);
23752375
}
23762376

23772377
clnt->spcost.cost += cost;

0 commit comments

Comments
 (0)