Can't await work on a computation other than functions in python3.5? - asynchronous

Does it have to be a function we are not blocking ?
Why isn't this working?
async def trivial(L):
await [num**2 for num in L]
So "Object list can't be used in 'await' expression", Am I correct in assuming it's only looking for a function or is there something that's possible to await??

Per the documentation, await will:
Suspend the execution of coroutine on an awaitable object.
You're in a coroutine, but a list is not awaitable, it isn't "a coroutine or an object with an __await__() method."
Note that the list comprehension is fully evaluated, resulting in a list, before it gets passed to await, so there's no work left to be done at that point anyway. If you were doing something more complex than num**2 inside the loop, you could consider rewriting the process as an "asynchronous iterator" and using async for, as follows:
async def trivial(L):
result = []
async for item in process(L):
result.apend(item)
This would allow other pending tasks to be run between iterations of your process over L.

Related

F#: How can I wrap a non-async value in Async<'T>?

In F#, I'm implementing an interface that returns Async<'T>, but my implementation does not require any async method calls. Here's an example of my current implementation:
type CrappyIdGeneratorImpl() =
interface IdGenerator with
member this.Generate(): Async<Id> = async {
return System.Guid.NewGuid().ToString()
}
Is this the "best" way to wrap a non-Async<> value in Async<>, or is there a better way?
Put another way, I'm looking for the Async equivalent of System.Threading.Tasks.Task.FromResult().
Yes, that's the best way.
Note that, as stated in the comment, another way would be to do async.Return but it's not exactly the same thing, and in your use case it won't work, due to eager evaluation of the argument.
In your case you're interested in calling the .NewGuid() method each time the async is run, but if you use async.Return alone it will be evaluated once and the async computation will be created with that result as a fixed value.
In fact the equivalent of the CE is async.Delay (fun () -> async.Return (.. your expression ..))
UPDATE
As Tarmil noted, this can be interpreted as intended, given that the code resides in a method.
It might be the case that you created a method because that's the way you do with tasks, but Asyncs can be created and called independently (hot vs cold async models).
The question of whether the intention is delaying the async or creating an async at each method call is not entirely clear to me, but whichever is the case, the explanation above about each approach is still valid.

How to make async function yield on block?

I just started learning asynchronous Rust, so this is propably not a difficult question to answer, however, I am scratching my head here.
I am not trying to run tasks in parallel yet, only trying to get them to run concurrently.
According to the guide at https://rust-lang.github.io/async-book/,
The futures::join macro makes it possible to wait for multiple different futures to complete while executing them all concurrently.
So when I create 2 Futures, I should be able to "await" both of them at once. It also states that
Whereas calling a blocking function in a synchronous method would block the whole thread, blocked Futures will yield control of the thread, allowing other Futures to run.
From what I understand here, if I await multiple Futures with join!, should the first one be blocked, the second one will start running.
So I made a very simple example where I created 2 async fns and tried to join! both, making sure the first one gets blocked. I used a mpsc::channel for the blocking, since the docs stated that thread::sleep() should not be used in async fns and that recv()
will always block the current thread if there is no data available
However, the behavior is not what I expected, as calling the blocking function will not yield control of the thread, allowing the other Future to run, like I would expect from the second quote I provided. Instead, it will just wait untill it is no longer blocked, finish the first Future and only then start the second. Pretty much as if they were synchronous and I would have just called one after the other.
My complete example code:
use std::{thread::{self}, sync::{mpsc::{self, Sender, Receiver}}, time::Duration};
use futures::{executor}; //added futures = "0.3" in cargo.toml dependencies
fn main(){
let fut = main_async();
executor::block_on(fut);
}
async fn main_async(){
let (sender, receiver) = mpsc::channel();
let thread_handle = std::thread::spawn(move || { //this thread is just here so the f1 function gets blocked by something and can later resume
wait_send_function(sender);
});
let f1 = f1(receiver);
let f2 = f2();
futures::join!(f1, f2);
thread_handle.join().unwrap();
}
fn wait_send_function(sender: Sender<i32>){
thread::sleep(Duration::from_millis(5000));
sender.send(1234).unwrap();
}
async fn f1(receiver: Receiver<i32>){
println!("starting f1");
let new_nmbr = receiver.recv().unwrap(); //I would expect f2 to start now, since this is blocking
println!("Received nmbr is: {}", new_nmbr);
}
async fn f2(){
println!("starting f2");
}
And the output is simply:
starting f1
Received nmbr is: 1234
starting f2
My question is what am I missing here, why does f2 only start after f1 is completed and what would I need to do to get the behavior I want (completing f2 first if f1 is blocked and then waiting for f1)?
Maybe the book is a little misleading, but when it refers to "a blocked future", it does not mean in the sense of blocking synchronous code (if that was the case, there would be no problem to use std::thread::sleep()), but rather, it means that the future is waiting to be polled by the executor.
Thus, std::mpsc that blocks the thread will not have the desired effect (definitely not on a single-threaded executor like future's, but it's a bad idea on multi-threaded executors too). Use futures::channel::mpsc and everything will work.

F#: Synchronously start Async within a SynchronizationContext

Async.SwitchSynchronizationContext allows an Async action to switch to running within a given SynchronizationContext. I would like to synchronously begin an Async computation within a SynchronizationContext, rather than switching inside the Async.
This would ensure that Async actions are run in the desired order, and that they are not run concurrently.
Is this possible? The documentation for Async.SwitchSynchronizationContext mentions using SynchronizationContext.Post, but no such functionality is exposed for Async.
I have not tested this, but I think the easiest way to achieve what you want is to combine the SynchronizationContext.Send method (mentioned in the comments) with the Async.StartImmediate operation. The former lets you start some work synchronously in the synchronization context. The latter lets you start an async workflow in the current context.
If you combine the two, you can define a helper that starts a function in a given synchronization context and, in this function, immediately starts an async workflow:
let startInContext (sync:SynchronizationContext) work =
SynchronizationContext.Current.Send((fun _ ->
Async.StartImmediate(work)), null)
For example:
async {
printfn "Running on the given sync context"
do! Async.Sleep(1000)
printfn "Should be back on the original sync context" }
|> startInContext SynchronizationContext.Current

Questions about Future in Dart

The tutorial on async programming here talks about async await, but avoids discussing the Future API. I could find more information about the Future API here, but still I have some questions. These tutorials made me raise some questions, ideally I should have placed one for each questions, but since they are small and related I preferred to ask them all in one place.
What triggers/starts a Future execution?
From the text I can only conclude that once an async method returns the Future will be immediately triggered by the runtime.
What's the difference between Future.wait() and Future.then().then().then()?
Are return await myFuture; and return myFuture the same?
The text says an async method will return an incomplete Future once it sees an await or a return.
The text says:
Important: Async functions return Futures. If you don’t want your function to return a future, then use a different solution. For example, you might call an async function from your function.
How can we call an async function, get its return value, and not await, thus, not be an async function?
What triggers/starts a Future execution?
The code block for a Future is placed into the event queue, so it's executed when its turn in the event queue comes up. The Flutter in Focus Futures video has some good visuals about how this works.
What's the difference between Future.wait() and Future.then().then().then()?
They are different ways of handling multiple futures, but the differences are subtle. Future.wait handles errors slightly differently, and its values are returned as a list rather than in sequential code blocks, but in practice, the difference might not matter for your situation.
Are return await myFuture; and return myFuture the same?
No. In the first instance, execution is paused at the await until the Future is processed in the event queue. In the second instance, the Future itself is returned to the caller and execution continues as the caller wishes (probably until the Future is given a chance to be handled).
await is a language feature the essentially waits on the Future to complete at that point, whereas return simply returns the Future itself to the caller.
How can we call an async function, get its return value, and not await, thus, not be an async function?
If you need the return value, then you'd call the async function and then use it's Future directly rather than use await. Here's a silly example:
Future<int> getAsyncInt() async {
return 0;
}
void testAsync() {
getAsyncInt().then((value) {
print("Got an async int: $value");
});
}
In the above example, you can see we use an async function, but testAsync does not await the value (rather uses a Future, so the end result is the same).
If you don't need the return value though, you can just call the async function directly though:
Future<int> getAsyncInt() async {
return 0;
}
void testAsync() {
getAsyncInt();
}
In this second case, in fact, getAsyncInt() will indeed be called, even though it's return value is ignored by the caller.
These are good questions, BTW, hope that helps. async/await can be rather mysterious, but thinking of them as event queues really helps to understand in the flow of execution IMHO.

Why do functions have to be async in order to use await within them?

If I want to await a function, why does that have to be done in an async function only?
If I have this:
Function myFunc() {
return await myOtherFunc();
}
I get an error saying: “await expression is only allowed within an asynchronous function.”
I can understand if myOtherFunc() had to be asynchronous (it doesn't make sense to await an asynchronous function), but why does it care if the calling function is asynchronous or not. You can have a fork in a process within a synchronous function due to a call to an asynchronous function, right? So then why can’t you await that asynchronous function within the synchronous function?
NOTE: my question is NOT a duplicate of Javascript Await/Async Feature - What if you do not have the await word in the function?.
^ that question is asking what happens if await is not used in an async function. I'm asking why the function has to be async in order to use await. My response to DougBug below explains why they are different.
The picture in the following article might help explain it to you a bit.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/index
The basic idea though is that the async keyword allows the function to yield its execution up to a calling function.
As such any function that implements await must be marked async so that it can traverse back up the calling path until the first caller is only waiting on it to complete what it needs to do.

Resources