fix cache related segfault
This commit is contained in:
parent
7fd9810c78
commit
ede8b593b8
2 changed files with 40 additions and 6 deletions
42
src/cache/Cache.zig
vendored
42
src/cache/Cache.zig
vendored
|
|
@ -14,18 +14,21 @@ pub const Config = struct {
|
||||||
cache_dir: []const u8,
|
cache_dir: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, config: Config) !Cache {
|
pub fn init(allocator: std.mem.Allocator, config: Config) !*Cache {
|
||||||
std.fs.makeDirAbsolute(config.cache_dir) catch |err| {
|
std.fs.makeDirAbsolute(config.cache_dir) catch |err| {
|
||||||
if (err != error.PathAlreadyExists) return err;
|
if (err != error.PathAlreadyExists) return err;
|
||||||
};
|
};
|
||||||
|
|
||||||
var cache = Cache{
|
const cache = try allocator.create(Cache);
|
||||||
|
errdefer allocator.destroy(cache);
|
||||||
|
|
||||||
|
cache.* = Cache{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.lru = try Lru.init(allocator, config.max_entries),
|
.lru = try Lru.init(allocator, config.max_entries),
|
||||||
.cache_dir = try allocator.dupe(u8, config.cache_dir),
|
.cache_dir = try allocator.dupe(u8, config.cache_dir),
|
||||||
};
|
};
|
||||||
|
|
||||||
cache.lru.setEvictionCallback(&cache, evictCallback);
|
cache.lru.setEvictionCallback(cache, evictCallback);
|
||||||
|
|
||||||
// Clean up expired files and populate L1 cache from L2
|
// Clean up expired files and populate L1 cache from L2
|
||||||
cache.loadFromDir() catch |err| {
|
cache.loadFromDir() catch |err| {
|
||||||
|
|
@ -69,6 +72,7 @@ pub fn put(self: *Cache, key: []const u8, value: []const u8, ttl_seconds: u64) !
|
||||||
pub fn deinit(self: *Cache) void {
|
pub fn deinit(self: *Cache) void {
|
||||||
self.lru.deinit();
|
self.lru.deinit();
|
||||||
self.allocator.free(self.cache_dir);
|
self.allocator.free(self.cache_dir);
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getCacheFilename(self: *Cache, key: []const u8) ![]const u8 {
|
fn getCacheFilename(self: *Cache, key: []const u8) ![]const u8 {
|
||||||
|
|
@ -247,7 +251,7 @@ test "L1/L2 cache flow" {
|
||||||
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
const cache_dir = try tmp_dir.dir.realpath(".", &path_buf);
|
const cache_dir = try tmp_dir.dir.realpath(".", &path_buf);
|
||||||
|
|
||||||
var cache = try Cache.init(allocator, .{ .max_entries = 10, .cache_dir = cache_dir });
|
const cache = try Cache.init(allocator, .{ .max_entries = 10, .cache_dir = cache_dir });
|
||||||
defer cache.deinit();
|
defer cache.deinit();
|
||||||
|
|
||||||
// Put item in cache
|
// Put item in cache
|
||||||
|
|
@ -271,3 +275,33 @@ test "L1/L2 cache flow" {
|
||||||
// Now it should be in L1
|
// Now it should be in L1
|
||||||
try std.testing.expectEqualStrings("value1", cache.lru.get("key1").?);
|
try std.testing.expectEqualStrings("value1", cache.lru.get("key1").?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "expired cache entry returns null" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
|
var tmp_dir = std.testing.tmpDir(.{});
|
||||||
|
defer tmp_dir.cleanup();
|
||||||
|
|
||||||
|
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
|
const cache_dir = try tmp_dir.dir.realpath(".", &path_buf);
|
||||||
|
|
||||||
|
const cache = try Cache.init(allocator, .{ .max_entries = 10, .cache_dir = cache_dir });
|
||||||
|
defer cache.deinit();
|
||||||
|
|
||||||
|
// Put item with past expiration time
|
||||||
|
const now = std.time.milliTimestamp();
|
||||||
|
const past_expires = now - 1000;
|
||||||
|
|
||||||
|
// Manually insert expired entry into L1
|
||||||
|
const key_copy = try allocator.dupe(u8, "key1");
|
||||||
|
const value_copy = try allocator.dupe(u8, "value1");
|
||||||
|
try cache.lru.map.put(key_copy, .{
|
||||||
|
.value = value_copy,
|
||||||
|
.expires = past_expires,
|
||||||
|
.access_count = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get should return null for expired entry
|
||||||
|
const result = cache.get("key1");
|
||||||
|
try std.testing.expect(result == null);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ pub fn main() !void {
|
||||||
// Initialize location resolver
|
// Initialize location resolver
|
||||||
var resolver = Resolver.init(allocator, &geoip, &geocache, &airports_db);
|
var resolver = Resolver.init(allocator, &geoip, &geocache, &airports_db);
|
||||||
|
|
||||||
var cache = try Cache.init(allocator, .{
|
const cache = try Cache.init(allocator, .{
|
||||||
.max_entries = cfg.cache_size,
|
.max_entries = cfg.cache_size,
|
||||||
.cache_dir = cfg.cache_dir,
|
.cache_dir = cfg.cache_dir,
|
||||||
});
|
});
|
||||||
|
|
@ -66,7 +66,7 @@ pub fn main() !void {
|
||||||
defer metno.deinit();
|
defer metno.deinit();
|
||||||
|
|
||||||
var server = try Server.init(allocator, cfg.listen_host, cfg.listen_port, .{
|
var server = try Server.init(allocator, cfg.listen_host, cfg.listen_port, .{
|
||||||
.provider = metno.provider(&cache),
|
.provider = metno.provider(cache),
|
||||||
.resolver = &resolver,
|
.resolver = &resolver,
|
||||||
.geoip = &geoip,
|
.geoip = &geoip,
|
||||||
}, &rate_limiter);
|
}, &rate_limiter);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue