f# async cancel or continue - asynchronous

How do I implement an async function that will check each result of multiple parallel async functions and cancels them all if a certain result is found (say a bool returns false). Otherwise it will let all the async functions complete then return the final result (say bool true). I have tried Async.Choice from the F# snippets site, but it uses Async.FromContinuations that will only let you call the continuation once.

Related

Testing Async Functions

I am using Wasm-Pack and I need to write a unit test for a asynchronous function that references a JavaScript Library. I tried using the futures::executor::block_on in order to get the asynchronous function to return so I could make an assert. However, blocking is not supported in the wasm build target. I can't test in a different target because the asynchronous function I am testing is referencing a JavaScript library. I also don't think I can spawn a new thread and handle the future there, because it need to return to the assert statement in the original thread. What is the best way to go about testing this asynchronous function?
Code being tested in src/lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub async fn func_to_test() -> bool {
return some_long_running_fuction().await;
}
Testing code in tests/web.rs
#![cfg(target_arch = "wasm32")]
extern crate wasm_bindgen_test;
use test_crate;
use futures::executor::block_on;
#[wasm_bindgen_test]
fn can_return_from_async(){
let ret = block_on(test_crate::func_to_test());
assert!(ret);
}
How do I test an async function if I can't use any blocking?
Rust can handle tests that are async functions themselves. Just change the test fuction to be async and throw in an await.
#[wasm_bindgen_test]
async fn can_return_from_async(){
let ret = test_crate::func_to_test().await
assert!(ret);
}

Is there a way to poll several futures simultaniously in rust async

I'm trying to execute several sqlx queries in parallel given by a iterator.
This is probably the closest I've got so far.
let mut futures = HahshMap::new() // placeholder, filled HashMap in reality
.iter()
.map(async move |(_, item)| -> Result<(), sqlx::Error> {
let result = sqlx::query_file_as!(
// omitted
)
.fetch_one(&pool)
.await?;
channel.send(Enum::Event(result)).ignore();
Ok(())
})
.clollect();
futures::future::join_all(futures);
All queries and sends are independent from each other, so if one of them fails, the others should still get processed.
Futthermore the current async closure is not possible like this.
Rust doesn't yet have async closures. You instead need to have the closure return an async block:
move |(_, item)| async move { ... }
Additionally, make sure you .await the future returned by join_all in order to ensure the individual tasks are actually polled.

Pass method reference as an async call in Dart

Is it possible to pass an async method as an async call in Dart?
For example, if I want to simplify this code:
...
void myFunc() async {
await myLib.work();
}
...
RaisedButton(
onPressed: () async { await myFunc(); },
)
to this:
...
void myFunc() async {
await myLib.work();
}
...
RaisedButton(
onPressed: myFunc,
)
Passing myFunc just as a reference and still maintain that each time myFunc is called from onPressed as a callback, it will be an asynchronous call.
In short: Yes. The two pieces of code that you show are almost completely equivalent. Both call myLib.work and complete a future when the call's asynchronous computation completes.
You could probably also just write:
RaisedButton(
onPressed: myLib.work,
)
and it would still do the same thing.
However, I am not absolutely sure I understand what you mean by an "asynchronous call".
Dart function objects are not split into asynchronous functions and non-asynchronous functions that are called differently. They can be split into those returning Futures and those which don't, but you call them the same way. I assume that myLib.work returns a Future. You may then choose to await the result, but that's not part of the call.
Calling a function is not itself asynchronous, it's always synchronous - it returns a value before computation continues. That value might be a Future which will be completed later when an asynchronous computation has completed, but the function returns synchronously.
So, when you bind a void Function() method to the onPressed event, it will eventually call that function, ignore the return value, and continue synchronously.
If that function is myLib.work, then it calls myLib.work and ignores the returned Future. When the asynchronous work of work is done, it will complete the returned future, which nobody will notice.
If the function is myFunc, then it calls myFunc which immediately calls myLib.work and remembers the returned future. Then myFunc synchronously returns a new Future (which is ignored) and starts waiting (because of the await) on the future returned by myLib.work. When that future completes the await is done, and then the myFunc body is done, and finally the new Future is also completed. Again, nobody notices.
If the function is () async => await myFunc() then that function is called. It immediately calls myFunc, which immediately calls myLib.work, which returns a Future that myFunc starts waiting for and then returns a Future, which the function expression starts waiting for and then returns a Future, which is then ignored.
Eventually all these functions are completed, and nobody notices.
"If a future completes and nobody is listening, does it make an event?"

Flutter multiple async methods for parrallel execution

I'm still struggeling with the async/await pattern so I'm here to ask you some precisions.
I saw this page explaining the async/await pattern pretty well. I'm posting here the example that bother me :
import 'dart:async';
Future<String> firstAsync() async {
await Future<String>.delayed(const Duration(seconds: 2));
return "First!";
}
Future<String> secondAsync() async {
await Future<String>.delayed(const Duration(seconds: 2));
return "Second!";
}
Future<String> thirdAsync() async {
await Future<String>.delayed(const Duration(seconds: 2));
return "Third!";
}
void main() async {
var f = await firstAsync();
print(f);
var s = await secondAsync();
print(s);
var t = await thirdAsync();
print(t);
print('done');
}
In this example, each async method is called one after another, so the execution time for the main function is 6 seconds (3 x 2 seconds). However, I don't understand what's the point of asynchronous function if they are executed one after another.
Are async functions not supposed to execute in the background ? Is it not the point of multiple async functions to fastens the process with parrallel execution ?
I think I'm missing something about asynchronous functions and async/await pattern in flutter so if you could explain me that, it would be very appreciated.
Best
Waiting on multiple Futures to complete using Future.wait()
If the order of execution of the functions is not important, you can use Future.wait().
The functions get triggered in quick succession; when all of them complete with a value, Future.wait() returns a new Future. This Future completes with a list containing the values produced by each function.
Future
.wait([firstAsync(), secondAsync(), thirdAsyncC()])
.then((List responses) => chooseBestResponse(responses))
.catchError((e) => handleError(e));
or with async/await
try {
List responses = await Future.wait([firstAsync(), secondAsync(), thirdAsyncC()]);
} catch (e) {
handleError(e)
}
If any of the invoked functions completes with an error, the Future returned by Future.wait() also completes with an error. Use catchError() to handle the error.
Resource:https://v1-dartlang-org.firebaseapp.com/tutorials/language/futures#waiting-on-multiple-futures-to-complete-using-futurewait
The example is designed to show how you can wait for a long-running process without actually blocking the thread. In practice, if you have several of those that you want to run in parallel (for example: independent network calls), you could optimize things.
Calling await stops the execution of the method until the future completes, so the call to secondAsync will not happen until firstAsync finishes, and so on. If you do this instead:
void main() async {
var f = firstAsync();
var s = secondAsync();
var t = thirdAsync();
print(await f);
print(await s);
print(await t);
print('done');
}
then all three futures are started right away, and then you wait for them to finish in a specific order.
It is worth highlighting that now f, s, and t have type Future<String>. You can experiment with different durations for each future, or changing the order of the statements.
If anyone new in this problem use the async . Dart has a function called FutureGroup. You can use it to run futures in parallel.
Sample:
final futureGroup = FutureGroup();//instantiate it
void runAllFutures() {
/// add all the futures , this is not the best way u can create an extension method to add all at the same time
futureGroup.add(hello());
futureGroup.add(checkLocalAuth());
futureGroup.add(hello1());
futureGroup.add(hello2());
futureGroup.add(hello3());
// call the `.close` of the group to fire all the futures,
// once u call `.close` this group cant be used again
futureGroup.close();
// await for future group to finish (all futures inside it to finish)
await futureGroup.future;
}
This futureGroup has some useful methods which can help you ie. .future etc.. check the documentation to get more info.
Here's a sample usage Example One using await/async and Example Two using Future.then.
you can always use them in a single future
final results = await Future.wait([
firstAsync();
secondAsync();
thirdAsync();
]);
results will be an array of you return type. in this case array of strings.
cheers.
Try this resolve.
final List<Future<dynamic>> featureList = <Future<dynamic>>[];
for (final Partner partner in partnerList) {
featureList.add(repository.fetchAvatar(partner.uid));
}
await Future.wait<dynamic>(featureList);
If want parallel execution you should switch to multi thread concept called Isolates
mix this with async/await concepts . You can also check this website for more
https://buildflutter.com/flutter-threading-isolates-future-async-and-await/
Using async / await like that is useful when you need a resource before executing the next task.
In your example you don't do really useful things, but imagine you call firstAsync, that gives you a stored authorization token in your phone, then you call secondAsync giving this token get asynchronously and execute an HTTP request and then checking the result of this request.
In this case you don't block the UI thread (user can interact with your app) and other tasks (get token, HTTP request...) are done in background.
i think you miss understood how flutter works first flutter is not multi threaded.....!
second if it isn't multi threaded how can it executes parallel tasks, which doesnt happen....! here is some links that will help you understand more https://webdev.dartlang.org/articles/performance/event-loop
https://www.dartlang.org/tutorials/language/futures
flutter doesn't put futures on another thread but what happens that they are added to a queue the links that i added are for event loop and how future works. hope you get it , feel free to ask me :)

How does C# 5.0 async work?

I'm trying to grok how C# 5's new async feature works. Suppose I want to develop an atomic increment function for incrementing an integer in a fictitious IntStore. Multiple calls are made to this function in one thread only.
async void IncrementKey(string key) {
int i = await IntStore.Get(key);
IntStore.Set(key, i+1);
}
It seems to me that this function is flawed. Two calls to IncrementKey could get the same number back from IntStore (say 5), and then set it to 6, thus losing one of the increments?
How could this be re-written, if IntStore.Get is asynchronous (returns Task) in order to work correctly?
Performance is critical, is there a solution that avoids locking?
If you are sure you are calling your function from only one thread, then there shouldn't be any problem, because only one call to IntStore.Get could be awaiting at at time. This because:
await IncrementKey("AAA");
await IncrementKey("BBB");
the second IncrementKey won't be executed until the first IncrementKey has finished. The code will be converted to a state machine. If you don't trust it, change the IntStore.Get(key) to:
async Task<int> IntStore(string str) {
Console.WriteLine("Starting IntStore");
await TaskEx.Delay(10000);
return 0;
}
You'll see that the second Starting IntStore will be written 10 seconds after the first.
To quote from here http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspx The “await” operator ... means “if the task we are awaiting has not yet completed then sign up the rest of this method as the continuation of that task, and then return to your caller immediately; the task will invoke the continuation when it completes.”

Resources