mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-08 02:14:37 +00:00
feat(scarfmon): split nous.readCache into fileExists/readFile/decode/bytes
Last perf capture showed nous.readCache as a single 60-second interval — but the function does three things (transport.fileExists, transport.readFile, JSONDecoder). Splitting the measure points so the next capture localizes which step actually owns the wall-clock. Adds: - nous.readCache.fileExists (interval) — SSH `test -e` round-trip - nous.readCache.readFile (interval) — SSH `cat` round-trip - nous.readCache.bytes (event) — payload size of the cache file - nous.readCache.decode (interval) — JSON parsing cost If the next 60-second beach ball localizes to readFile, we know the cache file is somehow huge or the SSH read is hung; if it's fileExists, the path resolution is the issue; if decode, we have malformed JSON. All three wear the same outer wrapper so the existing nous.readCache total stays for trend comparison. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -98,19 +98,36 @@ public struct NousModelCatalogService: Sendable {
|
||||
public func readCache() -> NousModelsCache? {
|
||||
ScarfMon.measure(.diskIO, "nous.readCache") {
|
||||
let transport = context.makeTransport()
|
||||
guard transport.fileExists(cachePath) else { return nil }
|
||||
// Split into separate measure points so the next perf
|
||||
// capture localizes the 60-second observed beach ball
|
||||
// — was it the fileExists probe, the read itself, or
|
||||
// the JSON decode? Each on its own ScarfMon row.
|
||||
let exists = ScarfMon.measure(.diskIO, "nous.readCache.fileExists") {
|
||||
transport.fileExists(cachePath)
|
||||
}
|
||||
guard exists else { return nil }
|
||||
do {
|
||||
let data = try transport.readFile(cachePath)
|
||||
let decoder = JSONDecoder()
|
||||
decoder.dateDecodingStrategy = .iso8601
|
||||
let cache = try decoder.decode(NousModelsCache.self, from: data)
|
||||
guard cache.version == NousModelsCache.currentVersion else {
|
||||
Self.logger.info("nous models cache schema mismatch (got v\(cache.version), expected v\(NousModelsCache.currentVersion)); ignoring")
|
||||
return nil
|
||||
let data = try ScarfMon.measure(.diskIO, "nous.readCache.readFile") {
|
||||
try transport.readFile(cachePath)
|
||||
}
|
||||
ScarfMon.event(.diskIO, "nous.readCache.bytes", count: 1, bytes: data.count)
|
||||
return ScarfMon.measure(.diskIO, "nous.readCache.decode") {
|
||||
let decoder = JSONDecoder()
|
||||
decoder.dateDecodingStrategy = .iso8601
|
||||
do {
|
||||
let cache = try decoder.decode(NousModelsCache.self, from: data)
|
||||
guard cache.version == NousModelsCache.currentVersion else {
|
||||
Self.logger.info("nous models cache schema mismatch (got v\(cache.version), expected v\(NousModelsCache.currentVersion)); ignoring")
|
||||
return Optional<NousModelsCache>.none
|
||||
}
|
||||
return cache
|
||||
} catch {
|
||||
Self.logger.warning("couldn't decode nous models cache: \(error.localizedDescription, privacy: .public)")
|
||||
return Optional<NousModelsCache>.none
|
||||
}
|
||||
}
|
||||
return cache
|
||||
} catch {
|
||||
Self.logger.warning("couldn't decode nous models cache: \(error.localizedDescription, privacy: .public)")
|
||||
Self.logger.warning("couldn't read nous models cache: \(error.localizedDescription, privacy: .public)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user