libwebsockets
Lightweight C library for HTML5 websockets
|
Macros | |
#define | LWS_DISKCACHE_QUERY_NO_CACHE 0 |
#define | LWS_DISKCACHE_QUERY_EXISTS 1 |
#define | LWS_DISKCACHE_QUERY_CREATING 2 |
#define | LWS_DISKCACHE_QUERY_ONGOING 3 /* something else is creating it */ |
Functions | |
LWS_VISIBLE LWS_EXTERN struct lws_diskcache_scan * | lws_diskcache_create (const char *cache_dir_base, uint64_t cache_size_limit) |
LWS_VISIBLE LWS_EXTERN void | lws_diskcache_destroy (struct lws_diskcache_scan **lds) |
LWS_VISIBLE LWS_EXTERN int | lws_diskcache_prepare (const char *cache_base_dir, int mode, uid_t uid) |
LWS_VISIBLE LWS_EXTERN int | lws_diskcache_query (struct lws_diskcache_scan *lds, int is_bot, const char *hash_hex, int *_fd, char *cache, int cache_len, size_t *extant_cache_len) |
LWS_VISIBLE LWS_EXTERN int | lws_diskcache_finalize_name (char *cache) |
LWS_VISIBLE LWS_EXTERN int | lws_diskcache_trim (struct lws_diskcache_scan *lds) |
LWS_VISIBLE LWS_EXTERN int | lws_diskcache_secs_to_idle (struct lws_diskcache_scan *lds) |
Lws provides helper apis useful if you need a disk cache containing hashed files and need to delete files from it on an LRU basis to keep it below some size limit.
The API lws_diskcache_prepare()
deals with creating the cache dir and 256 subdirs, which are used according to the first two chars of the hex hash of the cache file.
lws_diskcache_create()
and lws_diskcache_destroy()
allocate and free an opaque struct that represents the disk cache.
lws_diskcache_trim()
should be called at eg, 1s intervals to perform the cache dir monitoring and LRU autodelete in the background lazily. It can be done in its own thread or on a timer... it monitors the directories in a stateful way that stats one or more file in the cache per call, and keeps a list of the oldest files as it goes. When it completes a scan, if the aggregate size is over the limit, it will delete oldest files first to try to keep it under the limit.
The cache size monitoring is extremely efficient in time and memory even when the cache directory becomes huge.
lws_diskcache_query()
is used to determine if the file already exists in the cache, or if it must be created. If it must be created, then the file is opened using a temp name that must be converted to a findable name with lws_diskcache_finalize_name()
when the generation of the file contents are complete. Aborted cached files that did not complete generation will be flushed by the LRU eventually. If the file already exists, it is 'touched' to make it new again and the fd returned.
LWS_VISIBLE LWS_EXTERN struct lws_diskcache_scan* lws_diskcache_create | ( | const char * | cache_dir_base, |
uint64_t | cache_size_limit | ||
) |
#include <include/libwebsockets/lws-diskcache.h>
lws_diskcache_create() - creates an opaque struct representing the disk cache
cache_dir_base | The cache dir path, eg /var/cache/mycache |
cache_size_limit | maximum size on disk the cache is allowed to use |
This returns an opaque struct lws_diskcache_scan *
which represents the disk cache, the trim scanning state and so on. You should use lws_diskcache_destroy()
to free it to destroy it.
LWS_VISIBLE LWS_EXTERN void lws_diskcache_destroy | ( | struct lws_diskcache_scan ** | lds | ) |
#include <include/libwebsockets/lws-diskcache.h>
lws_diskcache_destroy() - destroys the pointer returned by ...create()
lds | pointer to the pointer returned by lws_diskcache_create() |
Frees *lds and any allocations it did, and then sets *lds to NULL and returns.
LWS_VISIBLE LWS_EXTERN int lws_diskcache_finalize_name | ( | char * | cache | ) |
#include <include/libwebsockets/lws-diskcache.h>
lws_diskcache_query() - ensures the cache dir structure exists on disk
cache | The cache file temp name returned with LWS_DISKCACHE_QUERY_CREATING |
This renames the cache file you are creating to its final name. It should be called on the temp name returned by lws_diskcache_query()
if it gave a LWS_DISKCACHE_QUERY_CREATING return, after you have filled the cache file and closed it.
LWS_VISIBLE LWS_EXTERN int lws_diskcache_prepare | ( | const char * | cache_base_dir, |
int | mode, | ||
uid_t | uid | ||
) |
#include <include/libwebsockets/lws-diskcache.h>
lws_diskcache_prepare() - ensures the cache dir structure exists on disk
cache_base_dir | The cache dir path, eg /var/cache/mycache |
mode | octal dir mode to enforce, like 0700 |
uid | uid the cache dir should belong to |
This should be called while your app is still privileged. It will create the cache directory structure on disk as necessary, enforce the given access mode on it and set the given uid as the owner. It won't make any trouble if the cache already exists.
Typically the mode is 0700 and the owner is the user that your application will transition to use when it drops root privileges.
LWS_VISIBLE LWS_EXTERN int lws_diskcache_query | ( | struct lws_diskcache_scan * | lds, |
int | is_bot, | ||
const char * | hash_hex, | ||
int * | _fd, | ||
char * | cache, | ||
int | cache_len, | ||
size_t * | extant_cache_len | ||
) |
#include <include/libwebsockets/lws-diskcache.h>
lws_diskcache_query() - ensures the cache dir structure exists on disk
lds | The opaque struct representing the disk cache |
is_bot | nonzero means the request is from a bot. Don't create new cache contents if so. |
hash_hex | hex string representation of the cache object hash |
_fd | pointer to the fd to be set |
cache | destination string to take the cache filepath |
cache_len | length of the buffer at cache |
extant_cache_len | pointer to a size_t to take any extant cached file size |
This function is called when you want to find if the hashed name already exists in the cache. The possibilities for the return value are
lws_diskcache_finalize_name()
when it is done. Closing _fd is your responsibility.LWS_VISIBLE LWS_EXTERN int lws_diskcache_secs_to_idle | ( | struct lws_diskcache_scan * | lds | ) |
#include <include/libwebsockets/lws-diskcache.h>
lws_diskcache_secs_to_idle() - see how long to idle before calling trim
lds | The opaque object representing the cache |
If the cache is undersize, there's no need to monitor it immediately. This suggests how long to "sleep" before calling lws_diskcache_trim()
again.
LWS_VISIBLE LWS_EXTERN int lws_diskcache_trim | ( | struct lws_diskcache_scan * | lds | ) |
#include <include/libwebsockets/lws-diskcache.h>
lws_diskcache_trim() - performs one or more file checks in the cache for size management
lds | The opaque object representing the cache |
This should be called periodically to statefully walk the cache on disk collecting the oldest files. When it has visited every file, if the cache is oversize it will delete the oldest files until it's back under size again.
Each time it's called, it will look at one or more dir in the cache. If called when the cache is oversize, it increases the amount of work done each call until it is reduced again. Typically it will take 256 calls before it deletes anything, so if called once per second, it will delete files once every 4 minutes. Each call is very inexpensive both in memory and time.