Flink Stateful Functions 2.0 Multiple Calls During Asynchronous Wait - apache-flink

Flink Stateful Functions 2.0 has the ability to make asychronous calls, for example to an external API:
[https://ci.apache.org/projects/flink/flink-statefun-docs-release-2.0/sdk/java.html#completing-async-requests][1].
Function execution is then paused until the call completed with Success, Failure, or Unknown. Unknown is:
The stateful function was restarted, possibly on a different machine,
before the CompletableFuture was completed, therefore it is unknown
what is the status of the asynchronous operation.
What happens when there is a second call with the same ID to the paused/waiting function?
Does the callee then wait on the called function's processing of
its async result so that this second call executes with a clean,
non-shared post-async state?
Or does the second call execute on a
normal schedule, and thus on top of the state that was current as of
the async call, and then when the async call completes it continues
processing using the state that was updated while the async call was
pending?
Or maybe the call counts as a "restart" of the called
function - in which case what is the order of execution: the
"restart" runs and then the async returns with "restart" to execute
from the now updated state, or this order is reversed?
Or something else?

Function execution does not pause while an async request is completing. The instance for that id will continue to process messages until the request completes. This means the state can change while the future is running.
Think of your future as an ad-hoc function that you message and that then messages you back when it has a result. Functions can spawn multiple asynchronous requests without issue. Whichever future completes first will be processed first by the function instance, not necessarily the order in which they were spawned.

Related

SqlConnection.OpenAsync() hangs when there are no active connections

When I run this:
using(SqlConnection connection = new SqlConnection(connectionString)){
await connection.OpenAsync();
}
It hangs on the connection.OpenAsync() line.
If I look in Sql Server Management Studio how many connections are active for the database, there's only one: probably the one that this code uses. So, I'm not sure it is that I'm running out of connections from the app pool.
What am I doing wrong?
The problem was not the connection at all. The problem was that I shot myself in the foot with a deadlock on my threads. I was trying to make a synchronous call to the method containing the connection.OpenAsync(), like this:
Task task = MyAsyncMethod();
task.Wait();
By calling task.Wait() I was blocking the thread. When await connection.OpenAsync() returns, the rest of the method wants to run on the same thread I just blocked, so the task never finishes and task.Wait() never returns.
The solution:
Because in my async method I had nothing requiring me to stick to the same thread that called it, I simply used await connection.OpenAsync().ConfigureAwait(false), to make it run the remainder of the method in a different thread other than the one I block with task.Wait().
Another reason it could hang is because the implementation is bad. OpenAsync(CancellationToken) doesn't even use the cancellation token for the Open operation, so you can't actually cancel it. You have to wait for it to timeout. All it does is return a cancelled task if the cancellationToken was already set when you called the method, something you could check yourself without any special implementation. So this "async" overload is actually useless.

What happens differently when you add a task Asynchronously on GAE?

Google's doc on async tasks assumes knowledge of the difference between regular and asynchronously added tasks.
add_async(task, transactional=False, rpc=None)
Asynchronously add a Task or a list of Tasks to this Queue.
How is adding tasks asynchronously different to adding them regularly.
I.e. what is the difference between using add(task, transactional=False) and add_async(task, transactional=False, rpc=None)
I've heard that adding tasks regularly blocks certain things. Any explanation of what it blocks and how, and how async tasks don't block would be greatly appreciated.
tasks are scheduled and run elsewhere.
The async bit refers to the fact the call returns immediately (your code does not wait for the round trip of the RPC that submits the task to a queue) however you still have to check/wait for the result at the end of the request, but it means you can be doing work and then check that the call completed before you exit.

What if I never call get on the future from an Async Data Store operation?

If I call an async data store operation such as the one shown below but then end the request without calling get on the future, what will happen?
Will my operation still execute?
Will me response be sent before the operation has completed execution?
AsyncDatastoreService datastore = DatastoreServiceFactory.getAsyncDatastoreService();
Entity entity = new Employee("Employee", "Alfred");
// ... populate entity properties
// Make a sync call via the async interface
datastore.put(key)
//Return response
The rpc will be sent immediately; when your app is ready to send a response to the client, it will block until the rpc is done.
I've done this in python by accident and the result was nothing was written to the datastore.
Your operation may still execute but it seems that'll happen only if the response handler is still active when it decides to execute. If not, nothing seems to happen at all.
Yes, the response will be sent before the operation has completed execution - this is the main feature of a future, it's non-blocking.

How do I cancel an asynchronous operation in Silverlight/WCF?

I am calling an asynchronous service from my Silverlight app and I want to be able to cancel that call after it is made. There is an option for e.Cancelled once the service has finished (i.e. If e.Cancelled Then), but how to you set that cancelled to true after you have called it? How do you cancel that asynchronous call?
Let me clarify a bit... what I am trying to do is call the SAME method twice, one right after the other, and get the results of the last call into my collection. If I call an asynchronous method twice there is no guarantee that the second call will return first, so I may end up with the results of the first call coming in last and having the wrong results in my collection. So what I would like to do is cancel the first call when I make the second so I don't get results back from the first call. Seeing as how there is a Cancelled flag in the completed event args I figure you should be able to do this. But how?
It's async... the transfer is passed off to a remote server and it does not return until the server is done with it.
Basically the server will keep going, but you don't have to wait for the response. Disconnect your service completed event handler and pretend it was never called. That will give the effect of cancelling the operation.
If you really need to cancel something in progress on the server you would need to make another call to the server to cancel the first call. Assuming the first call is a very slow one, this might be possible.
Update (as question changed)
In the case you specify, it will be up to the server to cancel a operation in progress if a second one comes through, not up to the client. e.Cancelled is set server-side.
However... :)
You have exposed a client usability issue. Shouldn't you also delay sending any service request until an idle delay has passed. That way rapid selections will not result in multiple service calls.
Also... :>
You may also want to send a sequence number to your service calls and return that as part of the result. Then you will know if it is the latest request or not.
It sounds like what you really want to do is ignore the responses of all but the most recent call.
Set a unique ID (could be request #, a Guid, timestamp, or whatever) with the request, and make sure the service sends that same value back. Keep around the ID of the most recent request and ignore response that don't match that ID.
This will be safer than cancelling the first request, since if the service has already started sending the response before the cancel request happens, you still get your error condition.

App Engine: Is it possible to enqueue tasks asynchronously?

Many of my handlers add a task to a task queue to do non-critical background processing. Since this processing isn't critical, if the call to taskqueue.add() throws an exception, my code just ignores it.
Tonight the task queue seemed to be down for around half an hour. Although my handlers correctly ignored the failure, they took about 5 seconds for the taskqueue.add() call to timeout and move on to processing the rest of the page. This therefore made my site run very slowly.
So, is it possible to enqueue a task asynchronously - meaning a way to add a task, without waiting to see if the addition succeeded?
Alternatively, is there a way to reduce that timeout from 5 seconds down to eg 1 second?
Thanks.
You can use the new taskqueue methods create_rpc and add_async. If you don't care if the add succeeds, simply call add_async and ignore the result. If you care, but only want to wait 1 second, set the deadline when calling create_rpc, and use the return value as the RPC argument to add_async. Call get_result to find out if the tasks were successfully added.
I think you can't do anything about it because the RPC call underneath the add method is a synchronous blocking API call.
You could try to add some check using the Capabilities API.
I am pretty sure GAE announced that TQ adds will be async with the next release (experimental feature).

Resources