fsharp.core.extensions icon indicating copy to clipboard operation
fsharp.core.extensions copied to clipboard

Added `AsyncSeq.recoverWith`

Open Swoorup opened this issue 3 years ago • 0 comments

let recoverWith (f: exn -> AsyncSeq<'a>) (upstream: AsyncSeq<'a>): AsyncSeq<'a> =
    let e = upstream.GetAsyncEnumerator()
    { new AsyncSeq<'a> with
        member __.GetAsyncEnumerator (cancel) =
            let outer = upstream.GetAsyncEnumerator(cancel)
            let mutable inner = Unchecked.defaultof<IAsyncEnumerator<'a>>
            
            { new IAsyncEnumerator<'a> with
                member __.Current =
                  if isNull inner
                  then outer.Current
                  else inner.Current
                member __.DisposeAsync() = unitVtask {
                    let mutable step = 0
                    try
                        do! outer.DisposeAsync()
                        step <- 1
                        if not (isNull inner) then
                            do! inner.DisposeAsync()
                        step <- 2
                    with ex ->
                        if step < 2 then
                            do! inner.DisposeAsync()
                        return rethrow ex
                  }
                member __.MoveNextAsync() = vtask {
                    if isNull inner then 
                      try
                        return! outer.MoveNextAsync()
                      with ex ->
                        inner <- (f ex).GetAsyncEnumerator(cancel)
                        return! inner.MoveNextAsync()
                    else return! inner.MoveNextAsync()
                } }}

This should be handy, for recovering from errors.

Swoorup avatar Jul 19 '22 10:07 Swoorup