odyssey/core/od_pooler.c

119 lines
2.5 KiB
C
Raw Normal View History

2016-11-09 11:30:06 +00:00
/*
* odissey.
*
* PostgreSQL connection pooler and request router.
*/
#include <stdlib.h>
2016-11-15 11:38:31 +00:00
#include <stdarg.h>
2016-11-09 11:30:06 +00:00
#include <stdint.h>
#include <stdio.h>
#include <string.h>
2016-11-09 11:33:25 +00:00
#include <flint.h>
#include <soprano.h>
2016-11-09 11:33:25 +00:00
2016-11-09 11:30:06 +00:00
#include "od_macro.h"
#include "od_list.h"
#include "od_log.h"
#include "od_scheme.h"
#include "od_lex.h"
#include "od_config.h"
#include "od_server.h"
2016-11-09 12:01:48 +00:00
#include "od_server_pool.h"
2016-11-11 10:42:30 +00:00
#include "od_route_id.h"
#include "od_route.h"
#include "od_route_pool.h"
2016-11-09 11:52:09 +00:00
#include "od_client.h"
2016-11-09 12:08:55 +00:00
#include "od_client_pool.h"
2016-11-09 11:30:06 +00:00
#include "od.h"
#include "od_pooler.h"
#include "od_periodic.h"
2016-11-09 12:19:26 +00:00
#include "od_router.h"
2016-11-09 11:30:06 +00:00
2016-11-09 11:42:52 +00:00
static inline void
od_pooler(void *arg)
2016-11-09 11:30:06 +00:00
{
2016-11-09 12:19:26 +00:00
odpooler_t *pooler = arg;
od_t *env = pooler->od;
/* bind to listen address and port */
int rc;
2016-11-09 12:19:26 +00:00
rc = ft_bind(pooler->server, env->scheme.host,
env->scheme.port);
if (rc < 0) {
od_error(&env->log, "bind %s:%d failed",
env->scheme.host,
env->scheme.port);
return;
}
/* starting periodic task scheduler fiber */
rc = ft_create(pooler->env, od_periodic, pooler);
if (rc < 0) {
od_error(&env->log, "failed to create periodic fiber");
return;
}
od_log(&env->log, "pooler started at %s:%d",
env->scheme.host, env->scheme.port);
od_log(&env->log, "");
/* accept loop */
2016-11-09 12:19:26 +00:00
while (ft_is_online(pooler->env))
2016-11-09 12:01:48 +00:00
{
ftio_t client_io;
2016-11-09 12:19:26 +00:00
rc = ft_accept(pooler->server, &client_io);
if (rc < 0) {
od_error(&env->log, "accept failed");
continue;
}
2016-11-09 12:19:26 +00:00
odclient_t *client = od_clientpool_new(&pooler->client_pool);
2016-11-09 12:01:48 +00:00
if (client == NULL) {
od_error(&env->log, "failed to allocate client object");
ft_close(client_io);
continue;
}
client->id = pooler->client_seq++;
2016-11-09 12:19:26 +00:00
client->pooler = pooler;
2016-11-09 12:01:48 +00:00
client->io = client_io;
2016-11-09 12:19:26 +00:00
rc = ft_create(pooler->env, od_router, client);
2016-11-09 12:01:48 +00:00
if (rc < 0) {
od_error(&env->log, "failed to create client fiber");
ft_close(client_io);
2016-11-09 12:19:26 +00:00
od_clientpool_unlink(&pooler->client_pool, client);
2016-11-09 12:01:48 +00:00
continue;
}
}
2016-11-09 11:42:52 +00:00
}
2016-11-09 12:19:26 +00:00
int od_pooler_init(odpooler_t *pooler, od_t *od)
2016-11-09 11:42:52 +00:00
{
2016-11-09 12:19:26 +00:00
pooler->env = ft_new();
if (pooler->env == NULL)
2016-11-09 11:42:52 +00:00
return -1;
2016-11-09 12:19:26 +00:00
pooler->server = ft_io_new(pooler->env);
if (pooler->server == NULL) {
ft_free(pooler->env);
2016-11-09 11:42:52 +00:00
return -1;
}
pooler->client_seq = 0;
2016-11-09 12:19:26 +00:00
pooler->od = od;
od_routepool_init(&pooler->route_pool);
2016-11-09 12:19:26 +00:00
od_clientpool_init(&pooler->client_pool);
2016-11-09 11:42:52 +00:00
return 0;
}
2016-11-09 12:19:26 +00:00
int od_pooler_start(odpooler_t *pooler)
2016-11-09 11:42:52 +00:00
{
2016-11-09 12:01:48 +00:00
int rc;
2016-11-09 12:19:26 +00:00
rc = ft_create(pooler->env, od_pooler, pooler);
2016-11-09 12:01:48 +00:00
if (rc < 0) {
2016-11-09 12:19:26 +00:00
od_error(&pooler->od->log, "failed to create pooler fiber");
2016-11-09 12:01:48 +00:00
return -1;
}
2016-11-09 12:19:26 +00:00
ft_start(pooler->env);
2016-11-09 11:30:06 +00:00
return 0;
}