I write a simple handler with lwan, this handler do a simple thing: when client make a request which ask server to delay x miliseconds then response, server sleeps x miliseconds then response ok to client.
The reason I do this is we are trying to demonstrate real time bidding issue, when server have to response within 120ms for a bidding request, and client must close request after 120ms even if it does not receive response.
Write a handler which does not use coroutine is easy, but it causes blocking when many concurrent delay client make requests to lwan, it just can reply only some first requests, then cannot response at all.
Using coroutine is better, but I dont know how to use it without passing it through cache. Source code below:
/*
lwan - simple web server
Copyright (c) 2012 Leandro A. F. Pereira leandro@hardinfo.org
*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or any later version.
*
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
As you can see, I try to make uniq cache key by current request time in order to disable caching, but lwan still cache request. If I make 2 request to server: http://localhost/d?delay=1000, 1 request will receive response in 1012 ms, the second one receive response in 10 ms (did not sleep)
So, the issue is: how to disable the cache in this case?
I also try to remove assert(cache->time_to_live > 0) in lwan_cache.c to create cache with time_to_live = 0, but request is still cached.
Hello,
I write a simple handler with lwan, this handler do a simple thing: when client make a request which ask server to delay x miliseconds then response, server sleeps x miliseconds then response ok to client. The reason I do this is we are trying to demonstrate real time bidding issue, when server have to response within 120ms for a bidding request, and client must close request after 120ms even if it does not receive response.
Write a handler which does not use coroutine is easy, but it causes blocking when many concurrent delay client make requests to lwan, it just can reply only some first requests, then cannot response at all.
Using coroutine is better, but I dont know how to use it without passing it through cache. Source code below:
/*
include
include
include
include "lwan.h"
include "lwan-serve-files.h"
include "lwan-template.h"
include "lwan-cache.h"
include "lwan-io-wrappers.h"
include
include
include
include "murmur3.h"
include "sys/stat.h"
include
include
include
include
lwan_t l;
struct delay_info_t { struct cache_entry_t base; char key; const char callback; };
static struct cache_t *cache = NULL;
static struct cache_entry_t create_delay_info(const char input, void context attribute((unused))) { unsigned int i; uintmax_t delay = 0; bool valid = true; for (i = 0; i < strlen(input); i++) { if (!isdigit(input[i])) { valid = false; break; } } if (valid) { delay = strtoumax(input, NULL, 10); } if (!valid || (delay == UINTMAX_MAX && errno == ERANGE)) { return NULL; } time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = localtime ( &rawtime ); usleep((__useconds_t)delay * 1000); struct delay_info_t delay_info; delay_info = calloc(1, sizeof (struct delay_info_t)); delay_info->key = asctime(timeinfo); return (struct cache_entry_t *) delay_info; }
static void destroy_delayinfo(struct cache_entry_t entry, void context attribute((unused))) { struct delay_info_t delay_info = (struct delay_info_t ) entry; if (!delay_info) return; free(delay_info); }
lwan_http_status_t delay_handler(lwan_request_t _request, lwan_response_t response, void data attribute((unused))) { const char name = lwan_request_get_query_param(request, "delay"); struct cache_entry_t dl; dl = calloc(1, sizeof (struct cache_entry_t)); cache = cache_create(create_delay_info, destroy_delayinfo, NULL, 0); dl = cache_coro_get_and_ref_entry(cache, request->conn->coro, name); if (dl) { response->mime_type = "text/html"; strbuf_setstatic(response->buffer, (char) "ok", sizeof ("ok") - 1); cache_entry_unref(cache, dl); return HTTP_OK; } return HTTP_BAD_REQUEST; }
int main(void) { lwan_init(&l); // init cache cache = cache_create(create_fileinfo, destroy_fileinfo, NULL, 10); printf("Config root path: %s\n", l.config.root); lwan_main_loop(&l); lwan_shutdown(&l); return 0; }
As you can see, I try to make uniq cache key by current request time in order to disable caching, but lwan still cache request. If I make 2 request to server: http://localhost/d?delay=1000, 1 request will receive response in 1012 ms, the second one receive response in 10 ms (did not sleep)
So, the issue is: how to disable the cache in this case? I also try to remove assert(cache->time_to_live > 0) in lwan_cache.c to create cache with time_to_live = 0, but request is still cached.
Thanks