odissey: implement router cancel logic

This commit is contained in:
Dmitry Simonenko 2017-05-30 14:34:08 +03:00
parent cf823e87ee
commit 6b696ccdef
6 changed files with 87 additions and 9 deletions

View File

@ -84,13 +84,11 @@ int od_cancel(od_instance_t *instance,
machine_io_free(io); machine_io_free(io);
return -1; return -1;
} }
#if 0
rc = machine_set_readahead(io, instance->scheme.readahead); rc = machine_set_readahead(io, instance->scheme.readahead);
if (rc == -1) { if (rc == -1) {
od_error(&instance->log, NULL, "(cancel) failed to set readahead"); od_error(&instance->log, NULL, "(cancel) failed to set readahead");
return -1; return -1;
} }
#endif
so_stream_t stream; so_stream_t stream;
so_stream_init(&stream); so_stream_init(&stream);
@ -146,3 +144,25 @@ int od_cancel(od_instance_t *instance,
so_stream_free(&stream); so_stream_free(&stream);
return 0; return 0;
} }
static inline int
od_cancel_cmp(od_server_t *server, void *arg)
{
so_key_t *key = arg;
return so_keycmp(&server->key_client, key);
}
int od_cancel_match(od_instance_t *instance,
od_routepool_t *route_pool,
so_key_t *key)
{
/* match server by client key (forge) */
od_server_t *server;
server = od_routepool_foreach(route_pool, OD_SACTIVE, od_cancel_cmp, key);
if (server == NULL)
return -1;
od_route_t *route = server->route;
od_schemeserver_t *server_scheme = route->scheme->server;
so_key_t cancel_key = server->key;
return od_cancel(instance, server_scheme, &cancel_key);
}

View File

@ -8,5 +8,6 @@
*/ */
int od_cancel(od_instance_t*, od_schemeserver_t*, so_key_t*); int od_cancel(od_instance_t*, od_schemeserver_t*, so_key_t*);
int od_cancel_match(od_instance_t*, od_routepool_t*, so_key_t*);
#endif #endif

View File

@ -381,12 +381,7 @@ void od_frontend(void *arg)
/* client cancel request */ /* client cancel request */
if (client->startup.is_cancel) { if (client->startup.is_cancel) {
od_debug(&instance->log, client->io, "C: cancel request"); od_debug(&instance->log, client->io, "C: cancel request");
#if 0 od_router_cancel(client);
od_relay_t *relay = client->system->relay;
so_key_t key = client->startup.key;
od_frontend_close(client);
od_cancel(relay, &key);
#endif
od_frontend_close(client); od_frontend_close(client);
return; return;
} }

View File

@ -5,7 +5,8 @@ typedef enum {
OD_MCLIENT_NEW, OD_MCLIENT_NEW,
OD_MROUTER_ROUTE, OD_MROUTER_ROUTE,
OD_MROUTER_ATTACH, OD_MROUTER_ATTACH,
OD_MROUTER_DETACH OD_MROUTER_DETACH,
OD_MROUTER_CANCEL
} od_msg_t; } od_msg_t;
#endif /* OD_MSG_H */ #endif /* OD_MSG_H */

View File

@ -43,6 +43,7 @@
#include "od_router.h" #include "od_router.h"
#include "od_frontend.h" #include "od_frontend.h"
#include "od_backend.h" #include "od_backend.h"
#include "od_cancel.h"
typedef struct typedef struct
{ {
@ -227,6 +228,23 @@ od_router(void *arg)
/* todo: wakeup attachers */ /* todo: wakeup attachers */
break; break;
} }
case OD_MROUTER_CANCEL:
{
/* match server by client key and initiate
* cancel request connection */
od_msgrouter_t *msg_cancel;
msg_cancel = machine_msg_get_data(msg);
int rc;
rc = od_cancel_match(instance, &router->route_pool,
&msg_cancel->client->startup.key);
if (rc == -1)
msg_cancel->status = OD_RERROR;
else
msg_cancel->status = OD_ROK;
machine_queue_put(msg_cancel->response, msg);
continue;
}
default: default:
assert(0); assert(0);
break; break;
@ -365,3 +383,43 @@ od_router_detach(od_server_t *server)
msg_detach->server = server; msg_detach->server = server;
machine_queue_put(router->queue, msg); machine_queue_put(router->queue, msg);
} }
od_routerstatus_t
od_router_cancel(od_client_t *client)
{
od_router_t *router = client->system->router;
/* create response queue */
machine_queue_t response;
response = machine_queue_create();
if (response == NULL)
return OD_RERROR;
/* send cancel request to router */
machine_msg_t msg;
msg = machine_msg_create(OD_MROUTER_CANCEL, sizeof(od_msgrouter_t));
if (msg == NULL) {
machine_queue_free(response);
return OD_RERROR;
}
od_msgrouter_t *msg_cancel;
msg_cancel = machine_msg_get_data(msg);
msg_cancel->status = OD_RERROR;
msg_cancel->client = client;
msg_cancel->response = response;
machine_queue_put(router->queue, msg);
/* wait for reply */
msg = machine_queue_get(response, UINT32_MAX);
if (msg == NULL) {
/* todo: */
machine_queue_free(response);
return OD_RERROR;
}
msg_cancel = machine_msg_get_data(msg);
od_routerstatus_t status;
status = msg_cancel->status;
machine_queue_free(response);
machine_msg_free(msg);
return status;
}

View File

@ -37,4 +37,7 @@ od_router_attach(od_client_t*);
void void
od_router_detach(od_server_t*); od_router_detach(od_server_t*);
od_routerstatus_t
od_router_cancel(od_client_t*);
#endif /* OD_ROUTER_H */ #endif /* OD_ROUTER_H */