Skip to content

feat(Async): Add IAsyncConfigurationReader + ParseAsync overload#317

Open
dimension-zero wants to merge 4 commits into
fsprojects:masterfrom
dimension-zero:pr/29-async-config-reader
Open

feat(Async): Add IAsyncConfigurationReader + ParseAsync overload#317
dimension-zero wants to merge 4 commits into
fsprojects:masterfrom
dimension-zero:pr/29-async-config-reader

Conversation

@dimension-zero
Copy link
Copy Markdown
Contributor

feat(Async): Add IAsyncConfigurationReader + ParseAsync overload

  • ConfigReaders.fs:
    • New IAsyncConfigurationReader interface mirroring
      IConfigurationReader with GetValueAsync : string -> Task.
    • ConfigurationReader.AsAsync(reader) wraps any sync reader as async
      via Task.FromResult — useful when callers want to pass existing
      readers through the async parse path.
    • ConfigurationReader.FromAsyncFunction(asyncFn, ?name) builds a
      reader from an F# Async.
  • ArgumentParser.fs new ParseAsync overload: fetches every top-level
    AppSettings key the schema references via the async reader, awaits
    each, then runs the regular sync Parse against a Dictionary-backed
    snapshot. One round-trip per declared key; below ParseAsync, the
    parser stays purely synchronous so existing tests and behaviour are
    unaffected.

Hosts that previously had to block on an async config source can now
use ParseAsync directly:
do! parser.ParseAsync(configurationReader = remoteAsync) |> Async.AwaitTask


test(ParseAsync): Coverage for IAsyncConfigurationReader + ParseAsync

5 new tests:

  • ConfigurationReader.AsAsync wraps a sync reader; the wrapped Task
    resolves to the same value and preserves Name.
  • ParseAsync via AsAsync(sync reader) yields the same parse results as
    the original sync Parse against that reader.
  • ParseAsync pre-fetches each schema-declared AppSettings key exactly
    once (Interlocked-counted via a custom IAsyncConfigurationReader),
    guarding the implementation's contract.
  • ConfigurationReader.FromAsyncFunction adapts an F# Async
    to IAsyncConfigurationReader and parses round-trip.
  • ParseAsync forwards ignoreUnrecognized to the underlying sync Parse
    (CLI tokens not in the schema land in UnrecognizedCliParams).

Net suite size on this branch: 112 -> 117.


dimension-zero and others added 4 commits May 23, 2026 18:24
* ConfigReaders.fs:
  - New IAsyncConfigurationReader interface mirroring
    IConfigurationReader with GetValueAsync : string -> Task<string>.
  - ConfigurationReader.AsAsync(reader) wraps any sync reader as async
    via Task.FromResult — useful when callers want to pass existing
    readers through the async parse path.
  - ConfigurationReader.FromAsyncFunction(asyncFn, ?name) builds a
    reader from an F# Async<string option>.
* ArgumentParser.fs new ParseAsync overload: fetches every top-level
  AppSettings key the schema references via the async reader, awaits
  each, then runs the regular sync Parse against a Dictionary-backed
  snapshot. One round-trip per declared key; below ParseAsync, the
  parser stays purely synchronous so existing tests and behaviour are
  unaffected.

Hosts that previously had to block on an async config source can now
use ParseAsync directly:
    do! parser.ParseAsync(configurationReader = remoteAsync) |> Async.AwaitTask
5 new tests:
* ConfigurationReader.AsAsync wraps a sync reader; the wrapped Task
  resolves to the same value and preserves Name.
* ParseAsync via AsAsync(sync reader) yields the same parse results as
  the original sync Parse against that reader.
* ParseAsync pre-fetches each schema-declared AppSettings key exactly
  once (Interlocked-counted via a custom IAsyncConfigurationReader),
  guarding the implementation's contract.
* ConfigurationReader.FromAsyncFunction adapts an F# Async<string option>
  to IAsyncConfigurationReader and parses round-trip.
* ParseAsync forwards ignoreUnrecognized to the underlying sync Parse
  (CLI tokens not in the schema land in UnrecognizedCliParams).

Net suite size on this branch: 112 -> 117.
risk: LOW (score: 0.0, no analysable symbols)
@nojaf
Copy link
Copy Markdown
Collaborator

nojaf commented May 29, 2026

@bartelink do you have some bandwidth to review these PRs?
I believe you have dealt with the codebase in the past.

@bartelink
Copy link
Copy Markdown
Member

lol, did T-Gro mention I'm atting him too much and need to take a break :D

The PRs thankfully look pretty reviewable but ngl I was hoping they'd magically get merged by 'someone'!

But yes, I do have space atm so I'll chip away at them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants