Round Algorithm with Parallel Algorithm with F # and Task <T>

I have a C # API like this:

Task<T> Foo(serverUri)

      

Let's say I have 4 possible servers. I want to implement a function that will return the DiscUnionBar type:

type DiscUnionBar of T =
    Safe of T | Weak of T | ConnectionError

      

The implementation will have the following requirements:

  • Make 3 (max) simultaneous calls to Foo () with 3 different servers.
  • Select the 2 most successful answers. If they give the same result T1 and T2 (being T1 == T2), stop executing parallel queries and ignore / cancel the queries that are running and return Safe of T. If T1! = T2, keep making more queries (or looking at the responses) until two equal answers are found.
  • If any of the requests failed (throwing a ServerException), try with a serverUri that was not previously requested.
  • If all requests to all 4 servers fail, return a ConnectionError.
  • If there is only 1 request, return the Weak of T.

Is this easy to do if I can't use F # Async and have to stick with using C # Task? I lost it a bit.

+3


source to share


1 answer


If there is a reason you cannot use Async

anywhere in your code, and the only limitation is what you Foo

have to return Task

, you should have no trouble converting Task

caused by the call Foo

to Async

c Async.AwaitTask

.

This way you can build logic with F # async evaluation expressions as if it Foo

returnedAsync



let simpleComputation serverUri = async {
    let! fooResult = Foo(serverUri) |> Async.AwaitTask
    (* here you can work with the T returned by Foo task *)
}

      

I also have good experience with a library FSharp.Control.FusionTasks

that allows you to use Task

async computation directly in expressions, without having to call AwaitTask

explicitly, and helps in combining Async / Task as a whole. Although some may not like that he is trying to hide tasks.

+6


source







All Articles