Skip to content

Instantly share code, notes, and snippets.

@kellabyte
Last active December 22, 2015 01:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kellabyte/6399734 to your computer and use it in GitHub Desktop.
Save kellabyte/6399734 to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "uv.h"
#include "haywire.h"
#include "hw_string.h"
#include "khash.h"
#include "http_response_cache.h"
#include "http_server.h"
#define CRLF "\r\n"
KHASH_MAP_INIT_STR(string_hashmap, hw_string*)
static uv_timer_t cache_invalidation_timer;
static uv_key_t thread_cache_key;
void initialize_http_request_cache();
void free_http_request_cache();
void http_request_cache_timer(uv_timer_t* handle, int status);
void create_cached_http_request(khash_t(string_hashmap)* http_request_cache, char* http_status);
void set_cached_request(khash_t(string_hashmap)* http_request_cache, char* http_status, hw_string* cache_entry);
hw_string* get_cached_request(char* http_status);
void clear_http_cache(uv_async_t* handle, int status);
void initialize_http_request_cache()
{
int rc = uv_key_create(&thread_cache_key);
uv_timer_init(uv_loop, &cache_invalidation_timer);
uv_timer_start(&cache_invalidation_timer, http_request_cache_timer, 500, 500);
}
void http_request_cache_configure_listener(uv_loop_t* loop, uv_async_t* handle)
{
uv_async_init(loop, handle, clear_http_cache);
}
void clear_http_cache(uv_async_t* handle, int status)
{
printf("HIT uv_async_send() callback!\n");
}
void free_http_request_cache(khash_t(string_hashmap)* http_request_cache)
{
const char* k;
hw_string* v;
khiter_t keys[1];
keys[0] = NULL;
//int key_count = 0;
kh_foreach(http_request_cache, k, v,
{
free((char*)k);
free(v->value);
free(v);
//keys[key_count] = k;
//key_count++;
});
kh_destroy_string_hashmap(http_request_cache);
/*
for (int i=0; i<key_count; i++)
{
//printf("DELETE %s\n", (char*)keys[i]);
kh_del(string_hashmap, http_request_cache, (char*)keys[i]);
}
if (key_count > 0)
{
//printf("CLEARING\n");
kh_clear(string_hashmap, http_request_cache);
}
*/
}
void http_request_cache_timer(uv_timer_t* handle, int status)
{
for(int i=0; i<listener_count; i++)
{
uv_async_t* async_handle = &listener_async_handles[i];
uv_async_send(async_handle);
}
}
void create_cached_http_request(khash_t(string_hashmap)* http_request_cache, char* http_status)
{
hw_string* cache_entry = malloc(sizeof(hw_string));
cache_entry->value = calloc(1024, 1);
cache_entry->length = 0;
append_string(cache_entry, http_v1_1);
APPENDSTRING(cache_entry, http_status);
APPENDSTRING(cache_entry, CRLF);
append_string(cache_entry, server_name);
APPENDSTRING(cache_entry, CRLF);
APPENDSTRING(cache_entry, "Date: Fri, 31 Aug 2011 00:31:53 GMT");
APPENDSTRING(cache_entry, CRLF);
set_cached_request(http_request_cache, http_status, cache_entry);
}
void set_cached_request(khash_t(string_hashmap)* http_request_cache, char* http_status, hw_string* cache_entry)
{
int ret;
int is_missing;
khiter_t key;
hw_string* val;
key = kh_get(string_hashmap, http_request_cache, http_status);
if (key != 0)
{
/* cache entry already exists and another thread beat us. Ignore. */
val = kh_value(http_request_cache, key);
is_missing = (key == kh_end(http_request_cache));
if (!is_missing)
{
printf("FOUND\n");
//kh_del(string_hashmap, http_request_cache, key);
}
}
key = kh_put(string_hashmap, http_request_cache, dupstr(http_status), &ret);
kh_value(http_request_cache, key) = cache_entry;
//printf("SET %s\n", http_status);
}
hw_string* get_cached_request(char* http_status)
{
int is_missing;
void* val;
khash_t(string_hashmap)* http_request_cache;
/* This thread hasn't created a response cache so create one */
http_request_cache = uv_key_get(&thread_cache_key);
if (http_request_cache == NULL)
{
http_request_cache = kh_init(string_hashmap);
uv_key_set(&thread_cache_key, http_request_cache);
printf("CREATED CACHE\n");
}
khiter_t key = kh_get(string_hashmap, http_request_cache, http_status);
if (key == 0)
{
is_missing = 1;
}
else
{
val = kh_value(http_request_cache, key);
is_missing = (key == kh_end(http_request_cache));
}
if (is_missing)
{
create_cached_http_request(http_request_cache, http_status);
}
key = kh_get(string_hashmap, http_request_cache, http_status);
if (key == 0)
{
is_missing = 1;
}
else
{
val = kh_value(http_request_cache, key);
is_missing = (key == kh_end(http_request_cache));
}
if (is_missing)
{
return NULL;
}
return val;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment