clean up estimated wait printout
This commit is contained in:
parent
6aaf97000d
commit
4366414207
1 changed files with 46 additions and 27 deletions
73
src/main.zig
73
src/main.zig
|
|
@ -464,10 +464,22 @@ fn upperDupe(allocator: std.mem.Allocator, s: []const u8) ![]u8 {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn printRateLimitWait(svc: *zfin.DataService, data_type: zfin.cache.DataType, stdout: *std.Io.Writer) !void {
|
/// Print an inline rate-limit estimate tag like "[~14s] " before the
|
||||||
|
/// next fetch of `data_type`, then flush so the tag is visible before
|
||||||
|
/// the (possibly blocking) fetch runs. An interactive caller sees the
|
||||||
|
/// estimate, then the pause, then the result land on a single line; a
|
||||||
|
/// cron log just gets the tag inline. No-op when a token is available
|
||||||
|
/// (estimate 0) or the provider isn't instantiated yet.
|
||||||
|
///
|
||||||
|
/// The number is the pause a *live* fetch would incur right now -- not
|
||||||
|
/// a promise that we will wait. A cache hit consumes no token and skips
|
||||||
|
/// the wait entirely (see the one-time legend at the top of a refresh
|
||||||
|
/// run). The estimate is read before the fetch, so it reflects the
|
||||||
|
/// pre-fetch bucket state.
|
||||||
|
fn printRateLimitTag(svc: *zfin.DataService, data_type: zfin.cache.DataType, stdout: *std.Io.Writer) !void {
|
||||||
if (svc.estimateWaitSeconds(data_type)) |wait| {
|
if (svc.estimateWaitSeconds(data_type)) |wait| {
|
||||||
if (wait > 0) {
|
if (wait > 0) {
|
||||||
try stdout.print("\n (rate limit -- waiting {d}s)\n ", .{wait});
|
try stdout.print("[~{d}s] ", .{wait});
|
||||||
try stdout.flush();
|
try stdout.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -600,6 +612,7 @@ fn refresh(io: std.Io, allocator: std.mem.Allocator, environ: *const std.process
|
||||||
|
|
||||||
try stdout.print("zfin-server {s}\n", .{version});
|
try stdout.print("zfin-server {s}\n", .{version});
|
||||||
try stdout.print("Refreshing {d} symbols from {s}\n", .{ symbols.count(), portfolio_path });
|
try stdout.print("Refreshing {d} symbols from {s}\n", .{ symbols.count(), portfolio_path });
|
||||||
|
try stdout.print("note: [~Ns] = est. pause before the next live fetch (bucket empty); cache hits skip it\n", .{});
|
||||||
try stdout.flush();
|
try stdout.flush();
|
||||||
|
|
||||||
var success_count: u32 = 0;
|
var success_count: u32 = 0;
|
||||||
|
|
@ -613,7 +626,7 @@ fn refresh(io: std.Io, allocator: std.mem.Allocator, environ: *const std.process
|
||||||
// handlers to serve. Per-symbol `getEtfMetrics` calls below
|
// handlers to serve. Per-symbol `getEtfMetrics` calls below
|
||||||
// also rely on these maps being loaded.
|
// also rely on these maps being loaded.
|
||||||
{
|
{
|
||||||
try printRateLimitWait(&svc, .tickers_funds, stdout);
|
try printRateLimitTag(&svc, .tickers_funds, stdout);
|
||||||
if (svc.loadMutualFundTickerMap(.{})) |mut_map| {
|
if (svc.loadMutualFundTickerMap(.{})) |mut_map| {
|
||||||
var m = mut_map;
|
var m = mut_map;
|
||||||
m.deinit();
|
m.deinit();
|
||||||
|
|
@ -621,7 +634,7 @@ fn refresh(io: std.Io, allocator: std.mem.Allocator, environ: *const std.process
|
||||||
} else |err| {
|
} else |err| {
|
||||||
try stdout.print("EDGAR mutual-fund ticker map FAILED ({t})\n", .{err});
|
try stdout.print("EDGAR mutual-fund ticker map FAILED ({t})\n", .{err});
|
||||||
}
|
}
|
||||||
try printRateLimitWait(&svc, .tickers_companies, stdout);
|
try printRateLimitTag(&svc, .tickers_companies, stdout);
|
||||||
if (svc.loadCompanyTickerMap(.{})) |co_map| {
|
if (svc.loadCompanyTickerMap(.{})) |co_map| {
|
||||||
var m = co_map;
|
var m = co_map;
|
||||||
m.deinit();
|
m.deinit();
|
||||||
|
|
@ -641,7 +654,7 @@ fn refresh(io: std.Io, allocator: std.mem.Allocator, environ: *const std.process
|
||||||
var sym_ok = true;
|
var sym_ok = true;
|
||||||
|
|
||||||
// Candles
|
// Candles
|
||||||
try printRateLimitWait(&svc, .candles_daily, stdout);
|
try printRateLimitTag(&svc, .candles_daily, stdout);
|
||||||
if (svc.getCandles(sym, .{})) |result| {
|
if (svc.getCandles(sym, .{})) |result| {
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
try stdout.print("candles ok ({s})", .{@tagName(result.source)});
|
try stdout.print("candles ok ({s})", .{@tagName(result.source)});
|
||||||
|
|
@ -679,32 +692,35 @@ fn refresh(io: std.Io, allocator: std.mem.Allocator, environ: *const std.process
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dividends
|
// Dividends
|
||||||
try printRateLimitWait(&svc, .dividends, stdout);
|
try stdout.print(", ", .{});
|
||||||
|
try printRateLimitTag(&svc, .dividends, stdout);
|
||||||
if (svc.getDividends(sym, .{})) |result| {
|
if (svc.getDividends(sym, .{})) |result| {
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
try stdout.print(", dividends ok ({s})", .{@tagName(result.source)});
|
try stdout.print("dividends ok ({s})", .{@tagName(result.source)});
|
||||||
} else |err| {
|
} else |err| {
|
||||||
try stdout.print(", dividends FAILED ({s})", .{@errorName(err)});
|
try stdout.print("dividends FAILED ({s})", .{@errorName(err)});
|
||||||
sym_ok = false;
|
sym_ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Splits
|
// Splits
|
||||||
try printRateLimitWait(&svc, .splits, stdout);
|
try stdout.print(", ", .{});
|
||||||
|
try printRateLimitTag(&svc, .splits, stdout);
|
||||||
if (svc.getSplits(sym, .{})) |result| {
|
if (svc.getSplits(sym, .{})) |result| {
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
try stdout.print(", splits ok ({s})", .{@tagName(result.source)});
|
try stdout.print("splits ok ({s})", .{@tagName(result.source)});
|
||||||
} else |err| {
|
} else |err| {
|
||||||
try stdout.print(", splits FAILED ({s})", .{@errorName(err)});
|
try stdout.print("splits FAILED ({s})", .{@errorName(err)});
|
||||||
sym_ok = false;
|
sym_ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Earnings
|
// Earnings
|
||||||
try printRateLimitWait(&svc, .earnings, stdout);
|
try stdout.print(", ", .{});
|
||||||
|
try printRateLimitTag(&svc, .earnings, stdout);
|
||||||
if (svc.getEarnings(sym, .{})) |result| {
|
if (svc.getEarnings(sym, .{})) |result| {
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
try stdout.print(", earnings ok ({s})", .{@tagName(result.source)});
|
try stdout.print("earnings ok ({s})", .{@tagName(result.source)});
|
||||||
} else |err| {
|
} else |err| {
|
||||||
try stdout.print(", earnings FAILED ({s})", .{@errorName(err)});
|
try stdout.print("earnings FAILED ({s})", .{@errorName(err)});
|
||||||
sym_ok = false;
|
sym_ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -715,7 +731,8 @@ fn refresh(io: std.Io, allocator: std.mem.Allocator, environ: *const std.process
|
||||||
var cik_buf: ?[]u8 = null;
|
var cik_buf: ?[]u8 = null;
|
||||||
defer if (cik_buf) |b| allocator.free(b);
|
defer if (cik_buf) |b| allocator.free(b);
|
||||||
var is_etf = false;
|
var is_etf = false;
|
||||||
try printRateLimitWait(&svc, .classification, stdout);
|
try stdout.print(", ", .{});
|
||||||
|
try printRateLimitTag(&svc, .classification, stdout);
|
||||||
if (svc.getClassification(sym, .{})) |result| {
|
if (svc.getClassification(sym, .{})) |result| {
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
if (result.data.len > 0) {
|
if (result.data.len > 0) {
|
||||||
|
|
@ -724,11 +741,11 @@ fn refresh(io: std.Io, allocator: std.mem.Allocator, environ: *const std.process
|
||||||
}
|
}
|
||||||
is_etf = result.data[0].is_etf;
|
is_etf = result.data[0].is_etf;
|
||||||
}
|
}
|
||||||
try stdout.print(", classification ok ({s})", .{@tagName(result.source)});
|
try stdout.print("classification ok ({s})", .{@tagName(result.source)});
|
||||||
} else |err| switch (err) {
|
} else |err| switch (err) {
|
||||||
zfin.DataError.NotFound => try stdout.print(", classification n/a", .{}),
|
zfin.DataError.NotFound => try stdout.print("classification n/a", .{}),
|
||||||
else => {
|
else => {
|
||||||
try stdout.print(", classification FAILED ({t})", .{err});
|
try stdout.print("classification FAILED ({t})", .{err});
|
||||||
sym_ok = false;
|
sym_ok = false;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -737,14 +754,15 @@ fn refresh(io: std.Io, allocator: std.mem.Allocator, environ: *const std.process
|
||||||
// non-funds (NPORT-P only exists for funds + UITs); a
|
// non-funds (NPORT-P only exists for funds + UITs); a
|
||||||
// negative-cache entry suppresses retries. Logged as
|
// negative-cache entry suppresses retries. Logged as
|
||||||
// `n/a` and doesn't flip sym_ok.
|
// `n/a` and doesn't flip sym_ok.
|
||||||
try printRateLimitWait(&svc, .etf_metrics, stdout);
|
try stdout.print(", ", .{});
|
||||||
|
try printRateLimitTag(&svc, .etf_metrics, stdout);
|
||||||
if (svc.getEtfMetrics(sym, .{})) |result| {
|
if (svc.getEtfMetrics(sym, .{})) |result| {
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
try stdout.print(", etf_metrics ok ({s})", .{@tagName(result.source)});
|
try stdout.print("etf_metrics ok ({s})", .{@tagName(result.source)});
|
||||||
} else |err| switch (err) {
|
} else |err| switch (err) {
|
||||||
zfin.DataError.NotFound => try stdout.print(", etf_metrics n/a", .{}),
|
zfin.DataError.NotFound => try stdout.print("etf_metrics n/a", .{}),
|
||||||
else => {
|
else => {
|
||||||
try stdout.print(", etf_metrics FAILED ({t})", .{err});
|
try stdout.print("etf_metrics FAILED ({t})", .{err});
|
||||||
sym_ok = false;
|
sym_ok = false;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -756,17 +774,18 @@ fn refresh(io: std.Io, allocator: std.mem.Allocator, environ: *const std.process
|
||||||
// concepts entity_facts looks for; calling EDGAR for
|
// concepts entity_facts looks for; calling EDGAR for
|
||||||
// them is guaranteed-404 noise. Skip them up front.
|
// them is guaranteed-404 noise. Skip them up front.
|
||||||
if (cik_buf) |cik| {
|
if (cik_buf) |cik| {
|
||||||
|
try stdout.print(", ", .{});
|
||||||
if (is_etf) {
|
if (is_etf) {
|
||||||
try stdout.print(", entity_facts n/a (ETF)", .{});
|
try stdout.print("entity_facts n/a (ETF)", .{});
|
||||||
} else {
|
} else {
|
||||||
try printRateLimitWait(&svc, .entity_facts, stdout);
|
try printRateLimitTag(&svc, .entity_facts, stdout);
|
||||||
if (svc.getEntityFacts(cik, .{})) |result| {
|
if (svc.getEntityFacts(cik, .{})) |result| {
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
try stdout.print(", entity_facts ok ({s})", .{@tagName(result.source)});
|
try stdout.print("entity_facts ok ({s})", .{@tagName(result.source)});
|
||||||
} else |err| switch (err) {
|
} else |err| switch (err) {
|
||||||
zfin.DataError.NotFound => try stdout.print(", entity_facts n/a", .{}),
|
zfin.DataError.NotFound => try stdout.print("entity_facts n/a", .{}),
|
||||||
else => {
|
else => {
|
||||||
try stdout.print(", entity_facts FAILED ({t})", .{err});
|
try stdout.print("entity_facts FAILED ({t})", .{err});
|
||||||
sym_ok = false;
|
sym_ok = false;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue