This documentation is also published as Markdown for efficient machine reading: the whole site is indexed at /llms.txt, and every page has a clean Markdown copy under /_llms/. These are generated from the same source and cost far fewer tokens to read than this rendered HTML.

Skip to main content Skip to navigation

CorpusFetchScope Pennington.Infrastructure

Runtime tripwire for the b719d73 deadlock class: a single-flight corpus task (the site projection) awaited from work its own materialization spawned is a task-level circular wait that hangs forever. Two flags mark the dangerous regions so SiteProjection can throw a descriptive exception instead of deadlocking:

  • InsideCorpusFetch — this request IS a projection-issued page self-fetch. RenderedHtmlFetcher stamps HeaderName on every fetch (an AsyncLocal alone would not cross the Kestrel loopback socket in dev), and UsePennington enters the scope when the header is present.
  • InsideMaterialization — the projection's materialization is on the current async flow; re-entering it (e.g. from a content service's discovery) would await a task that is waiting on the caller.

Properties

InsideCorpusFetch bool
True while processing a request the projection issued to render a page.
InsideMaterialization bool
True while the projection's corpus materialization is on the current async flow.

Fields

HeaderName string
Default: "X-Pennington-Corpus-Fetch"
Header stamped on projection-issued self-fetches. Dev-only surface: a client sending it manually gets the fail-fast exception on any page whose render path consumes the projection — which is exactly the bug the exception describes.

Methods

EnterCorpusFetch

#
public static IDisposable EnterCorpusFetch()

Marks the current async flow as a projection-issued page fetch until disposed.

Returns

IDisposable

EnterMaterialization

#
public static IDisposable EnterMaterialization()

Marks the current async flow as projection materialization until disposed.

Returns

IDisposable

Pennington.Infrastructure.CorpusFetchScope

namespace Pennington.Infrastructure;

/// Runtime tripwire for the b719d73 deadlock class: a single-flight corpus task (the site projection) awaited from work its own materialization spawned is a task-level circular wait that hangs forever. Two flags mark the dangerous regions so SiteProjection can throw a descriptive exception instead of deadlocking: 
  • InsideCorpusFetch — this request IS a projection-issued page self-fetch. RenderedHtmlFetcher stamps HeaderName on every fetch (an AsyncLocal alone would not cross the Kestrel loopback socket in dev), and UsePennington enters the scope when the header is present.
  • InsideMaterialization — the projection's materialization is on the current async flow; re-entering it (e.g. from a content service's discovery) would await a task that is waiting on the caller.
public class CorpusFetchScope { /// Marks the current async flow as a projection-issued page fetch until disposed.
public static IDisposable EnterCorpusFetch()
; /// Marks the current async flow as projection materialization until disposed.
public static IDisposable EnterMaterialization()
; /// Header stamped on projection-issued self-fetches. Dev-only surface: a client sending it manually gets the fail-fast exception on any page whose render path consumes the projection — which is exactly the bug the exception describes.
public static const string HeaderName
; /// True while processing a request the projection issued to render a page.
public static bool InsideCorpusFetch { get; }
/// True while the projection's corpus materialization is on the current async flow.
public static bool InsideMaterialization { get; }
}