Browse Source

add basic support for record TTLs

master
Brett Langdon 13 years ago
parent
commit
068816419a
6 changed files with 44 additions and 10 deletions
  1. +1
    -0
      src/common.h
  2. +22
    -5
      src/handlers.c
  3. +1
    -1
      src/handlers.h
  4. +15
    -3
      src/main.c
  5. +4
    -1
      src/proxy.c
  6. +1
    -0
      src/proxy.h

+ 1
- 0
src/common.h View File

@ -5,6 +5,7 @@
extern sig_atomic_t misses; extern sig_atomic_t misses;
extern sig_atomic_t hits; extern sig_atomic_t hits;
extern sig_atomic_t connections; extern sig_atomic_t connections;
extern int record_expire_time;
KCDB* db; KCDB* db;
int server; int server;
QUEUE requests; QUEUE requests;


+ 22
- 5
src/handlers.c View File

@ -83,14 +83,31 @@ void handle_get(KCLIST* tokens, FILE* client){
++misses; ++misses;
sprintf(out, "VALUE %s 0 0\r\n\r\nEND\r\n", key); sprintf(out, "VALUE %s 0 0\r\n\r\nEND\r\n", key);
} else{ } else{
++hits;
sprintf(out, "VALUE %s 0 %d\r\n%s\r\nEND\r\n", key, (int)strlen(result_buffer), result_buffer);
char* value = result_buffer + 11;
char expiration[16];
strncpy(expiration, result_buffer, 10);
int exp = atoi(expiration);
int now = (int)time(NULL);
if(exp > 0 && exp < now){
++misses;
value = "";
char reset_value[16];
sprintf(reset_value, "%10d:0", 0);
kcdbset(db, key, strlen(key), reset_value, strlen(reset_value));
queue_add(&requests, key);
} else{
++hits;
}
sprintf(out, "VALUE %s 0 %d\r\n%s\r\nEND\r\n", key, (int)strlen(value), value);
} }
kcfree(result_buffer); kcfree(result_buffer);
} else{ } else{
++misses; ++misses;
sprintf(out, "VALUE %s 0 2\r\n{}\r\nEND\r\n", key);
kcdbset(db, key, strlen(key), "0", 1);
sprintf(out, "VALUE %s 0 0\r\n\r\nEND\r\n", key);
char value[16];
int now = (int)time(NULL);
sprintf(value, "%10d:0", now + 60);
kcdbset(db, key, strlen(key), value, strlen(value));
queue_add(&requests, key); queue_add(&requests, key);
} }
fputs(out, client); fputs(out, client);
@ -107,7 +124,7 @@ int handle_command(char* buffer, FILE* client){
char* command; char* command;
list_shift(tokens, &command); list_shift(tokens, &command);
if(command != NULL){ if(command != NULL){
if(strncmp(command, "get", 3) == 0){
if(strcmp(command, "get") == 0){
handle_get(tokens, client); handle_get(tokens, client);
} else if(strcmp(command, "stats") == 0){ } else if(strcmp(command, "stats") == 0){
handle_stats(tokens, client); handle_stats(tokens, client);


+ 1
- 1
src/handlers.h View File

@ -1,7 +1,7 @@
#ifndef FAST_CACHE_HANDLERS #ifndef FAST_CACHE_HANDLERS
#define FAST_CACHE_HANDLERS #define FAST_CACHE_HANDLERS
#include <kclangc.h> #include <kclangc.h>
#include <time.h>
#include "common.h" #include "common.h"
#include "queue.h" #include "queue.h"


+ 15
- 3
src/main.c View File

@ -16,23 +16,27 @@
sig_atomic_t misses = 0; sig_atomic_t misses = 0;
sig_atomic_t hits = 0; sig_atomic_t hits = 0;
sig_atomic_t connections = 0; sig_atomic_t connections = 0;
int record_expire_time = 3600;
static struct option long_options[] = { static struct option long_options[] = {
{"port", 1, 0, 0}, {"port", 1, 0, 0},
{"url", 1, 0, 0}, {"url", 1, 0, 0},
{"workers", 1, 0, 0}, {"workers", 1, 0, 0},
{"cache", 1, 0, 0}, {"cache", 1, 0, 0},
{"expire", 1, 0, 0},
{"help", 0, 0, 0}, {"help", 0, 0, 0},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
void usage(){ void usage(){
const char* usage_str = const char* usage_str =
"Usage: fast-cache [-p|--port <NUM>] [-w|--workers <NUM>] [-u|--url <STRING>] [-c|--cache <STRING>] [-h|--help]\r\n"
"Usage: fast-cache [-h|--help] [-p|--port <NUM>] [-w|--workers <NUM>] [-u|--url <STRING>]\r\n"
" [-c|--cache <STRING>] [-e|--expire <NUM>]\r\n"
"\t-p, --port\t- which port number to bind too [default: 7000]\r\n" "\t-p, --port\t- which port number to bind too [default: 7000]\r\n"
"\t-w, --workers\t- how many background workers to spawn [default: 10]\r\n" "\t-w, --workers\t- how many background workers to spawn [default: 10]\r\n"
"\t-u, --url\t- which url to proxy requests to [default: http://127.0.0.1:8000]\r\n" "\t-u, --url\t- which url to proxy requests to [default: http://127.0.0.1:8000]\r\n"
"\t-c, --cache\t- kyoto cabinet cache to use [default: \"*\"]\r\n" "\t-c, --cache\t- kyoto cabinet cache to use [default: \"*\"]\r\n"
"\t-e, --expire\t- the expiration time in seconds from when a record is cached [default:3600]\r\n"
"\t-h, --help\t- display this message\r\n"; "\t-h, --help\t- display this message\r\n";
printf("%s", usage_str); printf("%s", usage_str);
} }
@ -114,6 +118,9 @@ int main(int argc, char* argv[]){
c = 'c'; c = 'c';
break; break;
case 4: case 4:
c = 'e';
break;
case 5:
c = 'h'; c = 'h';
break; break;
default: default:
@ -142,12 +149,17 @@ int main(int argc, char* argv[]){
case 'c': case 'c':
cache_file = optarg; cache_file = optarg;
break; break;
case 'e':
record_expire_time = atoi(optarg);
if(record_expire_time <= 0){
fprintf(stderr, "Invalid Expiration Time: %s\r\n", optarg);
exit(1);
}
break;
case 'h': case 'h':
usage(); usage();
exit(0); exit(0);
case '?': case '?':
usage();
exit(1);
default: default:
fprintf(stderr, "Unknown Option: %c\r\n", c); fprintf(stderr, "Unknown Option: %c\r\n", c);
usage(); usage();


+ 4
- 1
src/proxy.c View File

@ -38,7 +38,10 @@ void* call_proxy(void* arg){
curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, result); curl_easy_setopt(curl, CURLOPT_WRITEDATA, result);
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
kcdbset(db, next, strlen(next), result->data, strlen(result->data));
char value[1024];
int now = (int)time(NULL);
sprintf(value, "%10d:%s", now + record_expire_time, result->data);
kcdbset(db, next, strlen(next), value, strlen(value));
if(url != NULL){ if(url != NULL){
free(url); free(url);


+ 1
- 0
src/proxy.h View File

@ -2,6 +2,7 @@
#define FAST_CACHE_PROXY #define FAST_CACHE_PROXY
#include <curl/curl.h> #include <curl/curl.h>
#include <time.h>
#include "common.h" #include "common.h"
#include "queue.h" #include "queue.h"


Loading…
Cancel
Save