From abde6fdf3b6f4fe65859533e8b05ed3d43b4cf3a Mon Sep 17 00:00:00 2001 From: Emil Lerch Date: Wed, 11 Mar 2026 13:36:04 -0700 Subject: [PATCH] add debug statements so we can see what is going on if needed --- src/service.zig | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/service.zig b/src/service.zig index 9b1f4e1..9cf2d9d 100644 --- a/src/service.zig +++ b/src/service.zig @@ -8,6 +8,7 @@ //! based on available API keys. Callers never need to know which provider was used. const std = @import("std"); +const log = std.log.scoped(.service); const Date = @import("models/date.zig").Date; const Candle = @import("models/candle.zig").Candle; const Dividend = @import("models/dividend.zig").Dividend; @@ -162,15 +163,21 @@ pub const DataService = struct { var s = self.store(); const data_type = comptime cache.Store.dataTypeFor(T); - if (s.read(T, symbol, postProcess, .fresh_only)) |cached| + if (s.read(T, symbol, postProcess, .fresh_only)) |cached| { + log.debug("{s}: {s} fresh in local cache", .{ symbol, @tagName(data_type) }); return .{ .data = cached.data, .source = .cached, .timestamp = cached.timestamp }; + } // Try server sync before hitting providers if (self.syncFromServer(symbol, data_type)) { - if (s.read(T, symbol, postProcess, .fresh_only)) |cached| + if (s.read(T, symbol, postProcess, .fresh_only)) |cached| { + log.debug("{s}: {s} synced from server and fresh", .{ symbol, @tagName(data_type) }); return .{ .data = cached.data, .source = .cached, .timestamp = cached.timestamp }; + } + log.debug("{s}: {s} synced from server but stale, falling through to provider", .{ symbol, @tagName(data_type) }); } + log.debug("{s}: fetching {s} from provider", .{ symbol, @tagName(data_type) }); const fetched = self.fetchFromProvider(T, symbol) catch |err| { if (err == error.RateLimited) { // Wait and retry once @@ -235,6 +242,7 @@ pub const DataService = struct { const m = mr.meta; if (s.isCandleMetaFresh(symbol)) { // Fresh — deserialize candles and return + log.debug("{s}: candles fresh in local cache", .{symbol}); if (s.read(Candle, symbol, null, .any)) |r| return .{ .data = r.data, .source = .cached, .timestamp = mr.created }; } @@ -242,9 +250,11 @@ pub const DataService = struct { // Stale — try server sync before incremental fetch if (self.syncCandlesFromServer(symbol)) { if (s.isCandleMetaFresh(symbol)) { + log.debug("{s}: candles synced from server and fresh", .{symbol}); if (s.read(Candle, symbol, null, .any)) |r| return .{ .data = r.data, .source = .cached, .timestamp = std.time.timestamp() }; } + log.debug("{s}: candles synced from server but stale, falling through to incremental fetch", .{symbol}); // Server data also stale — fall through to incremental fetch } @@ -302,13 +312,16 @@ pub const DataService = struct { // No usable cache — try server sync first if (self.syncCandlesFromServer(symbol)) { if (s.isCandleMetaFresh(symbol)) { + log.debug("{s}: candles synced from server and fresh (no prior cache)", .{symbol}); if (s.read(Candle, symbol, null, .any)) |r| return .{ .data = r.data, .source = .cached, .timestamp = std.time.timestamp() }; } + log.debug("{s}: candles synced from server but stale, falling through to full fetch", .{symbol}); // Server data also stale — fall through to full fetch } // No usable cache — full fetch (~10 years, plus buffer for leap years) + log.debug("{s}: fetching full candle history from provider", .{symbol}); var td = try self.getProvider(TwelveData); const from = today.addDays(-3700); @@ -366,6 +379,7 @@ pub const DataService = struct { } else false; if (!needs_refresh) { + log.debug("{s}: earnings fresh in local cache", .{symbol}); return .{ .data = cached.data, .source = .cached, .timestamp = cached.timestamp }; } // Stale: free cached events and re-fetch below @@ -374,10 +388,14 @@ pub const DataService = struct { // Try server sync before hitting Finnhub if (self.syncFromServer(symbol, .earnings)) { - if (s.read(EarningsEvent, symbol, earningsPostProcess, .fresh_only)) |cached| + if (s.read(EarningsEvent, symbol, earningsPostProcess, .fresh_only)) |cached| { + log.debug("{s}: earnings synced from server and fresh", .{symbol}); return .{ .data = cached.data, .source = .cached, .timestamp = cached.timestamp }; + } + log.debug("{s}: earnings synced from server but stale, falling through to provider", .{symbol}); } + log.debug("{s}: fetching earnings from provider", .{symbol}); var fh = try self.getProvider(Finnhub); const from = today.subtractYears(5); const to = today.addDays(365); @@ -773,15 +791,24 @@ pub const DataService = struct { const full_url = std.fmt.allocPrint(self.allocator, "{s}/{s}{s}", .{ server_url, symbol, endpoint }) catch return false; defer self.allocator.free(full_url); + log.debug("{s}: syncing {s} from server", .{ symbol, @tagName(data_type) }); + var client = http.Client.init(self.allocator); defer client.deinit(); - var response = client.get(full_url) catch return false; + var response = client.get(full_url) catch |err| { + log.debug("{s}: server sync failed for {s}: {s}", .{ symbol, @tagName(data_type), @errorName(err) }); + return false; + }; defer response.deinit(); // Write to local cache var s = self.store(); - s.writeRaw(symbol, data_type, response.body) catch return false; + s.writeRaw(symbol, data_type, response.body) catch |err| { + log.debug("{s}: failed to write synced {s} to cache: {s}", .{ symbol, @tagName(data_type), @errorName(err) }); + return false; + }; + log.debug("{s}: synced {s} from server ({d} bytes)", .{ symbol, @tagName(data_type), response.body.len }); return true; }