diff --git a/genode/runtimes/blob_service/runtime b/genode/runtimes/blob_service/runtime index 45b5af0..a88725b 100644 --- a/genode/runtimes/blob_service/runtime +++ b/genode/runtimes/blob_service/runtime @@ -3,6 +3,7 @@ + @@ -27,6 +28,7 @@ + diff --git a/genode/runtimes/blobsets_fs/runtime b/genode/runtimes/blobsets_fs/runtime index 28bf5df..9f86c90 100644 --- a/genode/runtimes/blobsets_fs/runtime +++ b/genode/runtimes/blobsets_fs/runtime @@ -2,6 +2,7 @@ + diff --git a/genode/src/blobsets_fs.nim b/genode/src/blobsets_fs.nim index 322f1aa..b50a4fe 100644 --- a/genode/src/blobsets_fs.nim +++ b/genode/src/blobsets_fs.nim @@ -3,7 +3,7 @@ import std/tables, std/xmltree, std/strtabs, std/strutils, std/streams, std/xmlp import genode, genode/signals, genode/parents, genode/servers, genode/roms -import blobsets, blobsets/filestores, ./private/filesystemsession +import blobsets, blobsets/filestores, ./private/filesystemsession, ./private/store_reporter const currentPath = currentSourcePath.rsplit("/", 1)[0] @@ -297,8 +297,8 @@ componentConstructHook = proc(env: GenodeEnv) = var policies = newSeq[XmlNode](8) sessions = initTable[ServerId, SessionRef]() - let store = newFileStore("/store") - # Use the file-system as the store backend + let store = env.newStoreReporter(newFileStore("/store")) + # Use the file-system as the store backend, with a reporter wrapper proc createSession(env: GenodeEnv; store: BlobStore; id: ServerId; label: string; setId: SetId; txBufSize: int) = let diff --git a/genode/src/private/store_reporter.nim b/genode/src/private/store_reporter.nim new file mode 100644 index 0000000..07aac21 --- /dev/null +++ b/genode/src/private/store_reporter.nim @@ -0,0 +1,47 @@ +import blobsets +import genode, genode/reports +import std/asyncdispatch, std/asyncfutures, std/streams, std/xmltree + +type + StoreReporter = ref StoreReporterObj + StoreReporterObj = object of BlobStoreObj + store: BlobStore + reporter: ReportClient + xml: XmlNode + # TODO: put missing objects in a table and add + # a weight value that increase for each miss + +proc reportMissing(sr: StoreReporter; id: BlobId; kind: BlobKind) = + sr.xml.add <>blob(id=id.toHex, kind=($kind)) + sr.reporter.submit do (str: Stream): + str.writeLine(sr.xml) + +proc xContains(s: BlobStore; id: BlobId; kind: BlobKind): Future[bool] {.async.} = + var sr = StoreReporter(s) + let r = await sr.store.containsImpl(sr.store, id, kind) + if not r: + sr.reportMissing(id, kind) + return r + +proc xOpenBlobStream(s: BlobStore; id: BlobId; size: BiggestInt; kind: BlobKind): BlobStream = + var sr = StoreReporter(s) + try: + result = sr.store.openBlobStreamImpl(sr.store, id, size, kind) + except KeyError: + sr.reportMissing(id, kind) + raise newException(KeyError, "blob missing blob reported") + +proc xOpenIngestStream(s: BlobStore; size: BiggestInt; kind: BlobKind): IngestStream = + var sr = StoreReporter(s) + sr.store.openIngestStreamImpl(sr.store, size, kind) + +proc newStoreReporter*(env: GenodeEnv; store: BlobStore): BlobStore = + ## Create a new store that reports missing blobs via a Report session. + StoreReporter( + containsImpl: xcontains, + openBlobStreamImpl: xopenBlobStream, + openIngestStreamImpl: xopenIngestStream, + store: store, + reporter: env.newReportClient("missing"), + xml: <>missing(), + )