diff options
| author | Lars Hjemli <hjemli@gmail.com> | 2009-08-20 17:41:54 +0200 | 
|---|---|---|
| committer | Lars Hjemli <hjemli@gmail.com> | 2009-08-24 10:22:57 +0200 | 
| commit | d746827ec43a6dd53bce56ee8d8100a03383329e (patch) | |
| tree | f7d9e273672b7d0cf6c97bb40f7573a5d2ae178d | |
| parent | 302a3efa261b1b6127b2a2189e25ab45019b1b54 (diff) | |
cgit.c: add support for caching autodetected repositories
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
| -rw-r--r-- | cgit.c | 75 | ||||
| -rw-r--r-- | cgit.h | 1 | 
2 files changed, 75 insertions, 1 deletions
| @@ -40,6 +40,8 @@ struct cgit_filter *new_filter(const char *cmd, int extra_args)  	return f;  } +static void process_cached_repolist(const char *path); +  void config_cb(const char *name, const char *value)  {  	if (!strcmp(name, "root-title")) @@ -96,6 +98,8 @@ void config_cb(const char *name, const char *value)  		ctx.cfg.cache_root_ttl = atoi(value);  	else if (!strcmp(name, "cache-repo-ttl"))  		ctx.cfg.cache_repo_ttl = atoi(value); +	else if (!strcmp(name, "cache-scanrc-ttl")) +		ctx.cfg.cache_scanrc_ttl = atoi(value);  	else if (!strcmp(name, "cache-static-ttl"))  		ctx.cfg.cache_static_ttl = atoi(value);  	else if (!strcmp(name, "cache-dynamic-ttl")) @@ -137,7 +141,10 @@ void config_cb(const char *name, const char *value)  	else if (!strcmp(name, "repo.group"))  		ctx.cfg.repo_group = xstrdup(value);  	else if (!strcmp(name, "repo.scan")) -		scan_tree(value); +		if (!ctx.cfg.nocache && ctx.cfg.cache_size) +			process_cached_repolist(value); +		else +			scan_tree(value);  	else if (!strcmp(name, "repo.url"))  		ctx.repo = cgit_add_repo(value);  	else if (!strcmp(name, "repo.name")) @@ -236,6 +243,7 @@ static void prepare_context(struct cgit_context *ctx)  	ctx->cfg.cache_repo_ttl = 5;  	ctx->cfg.cache_root = CGIT_CACHE_ROOT;  	ctx->cfg.cache_root_ttl = 5; +	ctx->cfg.cache_scanrc_ttl = 15;  	ctx->cfg.cache_static_ttl = -1;  	ctx->cfg.css = "/cgit.css";  	ctx->cfg.logo = "/cgit.png"; @@ -438,6 +446,71 @@ void print_repolist(FILE *f, struct cgit_repolist *list, int start)  		print_repo(f, &list->repos[i]);  } +/* Scan 'path' for git repositories, save the resulting repolist in 'cached_rc' + * and return 0 on success. + */ +static int generate_cached_repolist(const char *path, const char *cached_rc) +{ +	char *locked_rc; +	int idx; +	FILE *f; + +	locked_rc = xstrdup(fmt("%s.lock", cached_rc)); +	f = fopen(locked_rc, "wx"); +	if (!f) { +		/* Inform about the error unless the lockfile already existed, +		 * since that only means we've got concurrent requests. +		 */ +		if (errno != EEXIST) +			fprintf(stderr, "[cgit] Error opening %s: %s (%d)\n", +				locked_rc, strerror(errno), errno); +		return errno; +	} +	idx = cgit_repolist.count; +	scan_tree(path); +	print_repolist(f, &cgit_repolist, idx); +	if (rename(locked_rc, cached_rc)) +		fprintf(stderr, "[cgit] Error renaming %s to %s: %s (%d)\n", +			locked_rc, cached_rc, strerror(errno), errno); +	fclose(f); +	return 0; +} + +static void process_cached_repolist(const char *path) +{ +	struct stat st; +	char *cached_rc; +	time_t age; + +	cached_rc = xstrdup(fmt("%s/rc-%8x", ctx.cfg.cache_root, +		hash_str(path))); + +	if (stat(cached_rc, &st)) { +		/* Nothing is cached, we need to scan without forking. And +		 * if we fail to generate a cached repolist, we need to +		 * invoke scan_tree manually. +		 */ +		if (generate_cached_repolist(path, cached_rc)) +			scan_tree(path); +		return; +	} + +	parse_configfile(cached_rc, config_cb); + +	/* If the cached configfile hasn't expired, lets exit now */ +	age = time(NULL) - st.st_mtime; +	if (age <= (ctx.cfg.cache_scanrc_ttl * 60)) +		return; + +	/* The cached repolist has been parsed, but it was old. So lets +	 * rescan the specified path and generate a new cached repolist +	 * in a child-process to avoid latency for the current request. +	 */ +	if (fork()) +		return; + +	exit(generate_cached_repolist(path, cached_rc)); +}  static void cgit_parse_args(int argc, const char **argv)  { @@ -168,6 +168,7 @@ struct cgit_config {  	int cache_max_create_time;  	int cache_repo_ttl;  	int cache_root_ttl; +	int cache_scanrc_ttl;  	int cache_static_ttl;  	int embedded;  	int enable_index_links; | 
