Kore pgsql improvements.

Don't wait for a full event loop until we call the page handler
for a received pgsql result. This speeds up page loads using
KORE_PGSQL by quite a lot, especially on a non busy server.
This commit is contained in:
Joris Vink 2014-04-17 10:49:48 +02:00
parent 94de8b27d2
commit d6d6f96ca0
4 changed files with 73 additions and 57 deletions

View File

@ -132,7 +132,8 @@ kore_pgsql_handle(void *c, int err)
i = conn->job->idx;
req = conn->job->req;
kore_debug("kore_pgsql_handle(): %p (%d)", req, i);
kore_debug("kore_pgsql_handle: %p (%d) (%d)",
req, i, req->pgsql[i]->state);
if (!PQconsumeInput(conn->db)) {
req->pgsql[i]->state = KORE_PGSQL_STATE_ERROR;
@ -141,10 +142,12 @@ kore_pgsql_handle(void *c, int err)
pgsql_read_result(req, i, conn);
}
if (req->pgsql[i]->state == KORE_PGSQL_STATE_WAIT)
if (req->pgsql[i]->state == KORE_PGSQL_STATE_WAIT) {
req->flags |= HTTP_REQUEST_SLEEPING;
else
} else {
req->flags &= ~HTTP_REQUEST_SLEEPING;
http_process_request(req, 1);
}
}
void
@ -153,6 +156,9 @@ kore_pgsql_continue(struct http_request *req, int i)
int fd;
struct pgsql_conn *conn;
kore_debug("kore_pgsql_continue: %p->%p (%d) (%d)",
req->owner, req, i, req->pgsql[i]->state);
if (req->pgsql[i]->error) {
kore_mem_free(req->pgsql[i]->error);
req->pgsql[i]->error = NULL;
@ -180,6 +186,8 @@ kore_pgsql_continue(struct http_request *req, int i)
fd = PQsocket(conn->db);
kore_platform_disable_read(fd);
http_process_request(req, 0);
break;
case KORE_PGSQL_STATE_ERROR:
case KORE_PGSQL_STATE_RESULT:

View File

@ -74,12 +74,4 @@ char *kore_pgsql_getvalue(struct kore_pgsql *, int, int);
} \
} while (0);
#define KORE_PGSQL_EXEC(r, q, i) \
do { \
if (r->pgsql[i] == NULL) \
kore_pgsql_query(r, q, i); \
if (r->pgsql[i] == NULL) \
return (KORE_RESULT_RETRY); \
} while (0);
#endif

View File

@ -161,6 +161,7 @@ void http_init(void);
void http_process(void);
time_t http_date_to_time(char *);
void http_request_free(struct http_request *);
void http_process_request(struct http_request *, int);
void http_response(struct http_request *, int, void *, u_int32_t);
int http_request_header_get(struct http_request *, char *, char **);
void http_response_header_add(struct http_request *, char *, char *);

View File

@ -150,9 +150,7 @@ http_request_new(struct connection *c, struct spdy_stream *s, char *host,
void
http_process(void)
{
struct kore_module_handle *hdlr;
struct http_request *req, *next;
int r, (*cb)(struct http_request *);
for (req = TAILQ_FIRST(&http_requests); req != NULL; req = next) {
next = TAILQ_NEXT(req, list);
@ -170,57 +168,72 @@ http_process(void)
if (!(req->flags & HTTP_REQUEST_COMPLETE))
continue;
if (req->hdlr != NULL)
hdlr = req->hdlr;
http_process_request(req, 0);
}
}
void
http_process_request(struct http_request *req, int retry_only)
{
struct kore_module_handle *hdlr;
int r, (*cb)(struct http_request *);
kore_debug("http_process_request: %p->%p (%s)",
req->owner, req, req->path);
if (req->flags & HTTP_REQUEST_DELETE)
return;
if (req->hdlr != NULL)
hdlr = req->hdlr;
else
hdlr = kore_module_handler_find(req->host, req->path);
req->start = kore_time_ms();
if (hdlr == NULL) {
r = http_generic_404(req);
} else {
if (req->hdlr != hdlr && hdlr->auth != NULL)
r = kore_auth(req, hdlr->auth);
else
hdlr = kore_module_handler_find(req->host, req->path);
r = KORE_RESULT_OK;
req->start = kore_time_ms();
if (hdlr == NULL) {
r = http_generic_404(req);
if (r == KORE_RESULT_OK) {
req->hdlr = hdlr;
cb = hdlr->addr;
worker->active_hdlr = hdlr;
r = cb(req);
worker->active_hdlr = NULL;
} else {
if (req->hdlr != hdlr && hdlr->auth != NULL)
r = kore_auth(req, hdlr->auth);
else
r = KORE_RESULT_OK;
if (r == KORE_RESULT_OK) {
req->hdlr = hdlr;
cb = hdlr->addr;
worker->active_hdlr = hdlr;
r = cb(req);
worker->active_hdlr = NULL;
} else {
/*
* Set r to KORE_RESULT_OK so we can properly
* flush the result from kore_auth().
*/
r = KORE_RESULT_OK;
}
/*
* Set r to KORE_RESULT_OK so we can properly
* flush the result from kore_auth().
*/
r = KORE_RESULT_OK;
}
req->end = kore_time_ms();
req->total += req->end - req->start;
}
req->end = kore_time_ms();
req->total += req->end - req->start;
switch (r) {
case KORE_RESULT_OK:
r = net_send_flush(req->owner);
if (r == KORE_RESULT_ERROR)
kore_connection_disconnect(req->owner);
break;
case KORE_RESULT_ERROR:
if (retry_only == 1 && r != KORE_RESULT_RETRY)
fatal("http_process_request: expected RETRY but got %d", r);
switch (r) {
case KORE_RESULT_OK:
r = net_send_flush(req->owner);
if (r == KORE_RESULT_ERROR)
kore_connection_disconnect(req->owner);
break;
case KORE_RESULT_RETRY:
break;
}
break;
case KORE_RESULT_ERROR:
kore_connection_disconnect(req->owner);
break;
case KORE_RESULT_RETRY:
break;
}
if (r != KORE_RESULT_RETRY) {
kore_accesslog(req);
TAILQ_REMOVE(&http_requests, req, list);
http_request_free(req);
http_request_count--;
}
if (r != KORE_RESULT_RETRY && !(req->flags & HTTP_REQUEST_DELETE)) {
kore_accesslog(req);
req->flags |= HTTP_REQUEST_DELETE;
}
}
@ -244,6 +257,8 @@ http_request_free(struct http_request *req)
struct http_arg *q, *qnext;
struct http_header *hdr, *next;
kore_debug("http_request_free: %p->%p", req->owner, req);
TAILQ_REMOVE(&(req->owner->http_requests), req, olist);
for (hdr = TAILQ_FIRST(&(req->resp_headers)); hdr != NULL; hdr = next) {