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.
source to share
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.
source to share