akka grpc server stream cannot return every result in real time - grpc

First of all, I have a server stream method. In the method, I will request an actor in a loop. I expect that after each request is responded, the application will return the result to the caller. But no, I found that it still waits for all responses to be completed before returning, is this normal?
// The code is as follows, for the convenience of observing the results, I added sleep
override def itKeepsReplying(in: HelloRequest): Source[HelloReply, NotUsed] = {
Source(1 to 10).map(index => {
Thread.sleep(5000)
HelloReply(character.toString)
})
}
In order to confirm whether grpc itself supports, I tried java's implementation of this piece,
If you want to send data to the caller: responseObserver.onNext(responseBuilder.build());,
If you want to end this call: responseObserver.onCompleted(); ,
Data is sent to the caller every time onNext is called.
So my question is:
Is my assumption correct? If akka-grpc can do it
If it can be done, please give an example

Related

Is there a way that we can emit error or success manually on Future dart?

Something like SettableFuture/ListenableFuture java where we can control what to emit to the listener.
What I want to have is :
For example, I have a socket connection active.
I send(request) a message through socket in some function
The request also has its response, but it comes through onData(d) callback some where else not in this request funtion
I store the future in a key-value array after send
After the response on onData(d) I will get the future from the array and make it emit success or error appropriately
Normally you can make an asynchronous function either return a value (success) or throw an exception (either by throwing from a async function or by manually returning a Future.error).
If you have some existing Future that you don't control, you can't force it to succeed or to fail. You instead could make callers wait on a Future that you do control, and you could make your Future depend on the external one.
Completer can simplify some of that for you.

Why Future works after the main function was done?

In the example on dart.dev the Future prints the message after the main function was done.
Why might the Future work after the main function was done? At first glance, after the completion of the main function, the entire work of the program is expected to be completed (and the Future must be cancelled).
The example code:
Future<void> fetchUserOrder() {
// Imagine that this function is fetching user info from another service or database.
return Future.delayed(Duration(seconds: 2), () => print('Large Latte'));
}
void main() {
fetchUserOrder();
print('Fetching user order...');
}
The program prints
Fetching user order...
Large Latte
I've expected just the following
Fetching user order...
This has to do with the nature of futures and asynchronous programming. Behind the scenes, Dart manages something called the asynchronous queue. When you initiate a future (either manually like you did with Future.delayed or implicitly by calling a method marked async, that function's execution goes into the queue whenever its execution gets deferred. Every cycle when Dart's main thread is idle, it checks the futures in the queue to see if any of them are no longer blocked, and if so, it resumes their execution.
A Dart program will not terminate while futures are in the queue. It will wait for all of them to either complete or error out.

How to really terminating a function?

After reading a lot, it seems that I (as well as others) can't really figure out what really terminate a function, and when should you use it.
Send, response, redirect, end, return, and a mix of them.
According to Google :
Always end an HTTP function with send(), redirect(), or end()
Now in many questions here i read that response will end your HTTP function as well.A promise will keep it awake.
I would be happy to understand which does what given this function :
exports.server = functions.https.onRequest((request, response) => {
response.status(200);
response.status(200).end();
return
return response.redirect(someURL);
sendStatus(200);
response.status(200).send(dictionary)
When would you use each of this and which will terminate the function.
It's just too confusing and there is no organized document other than a few sentences saying you must terminate the function.
EDIT:
Now it's even more confusing as I read here that response does not terminate the function and you can do things after your response, but you can't edit the response itself because it ended.
So does response terminate the function ?? things are really not clear.
Why can I execute code after "res.send"?
Since you are answering to an HTTP request, you should definitely use send() with or without status() before to send a HTTP response BUT (and you stated it) it won't stop the rest of the script to execute.
So you have to be extra careful in writing your if/then/else flow so send() can't be called multiple times.
The safest way in my opinion is also to always finish each code part with a return true or return false after calling send().

Cancel Http handler request

I have handlers that respond to https requests. In the handlers I call a function F1() which does some application logic and connects to a mysql db and does a query. I want to know how I can use the golang context package to cancel the Db query if the client cancels the request. Do I need to pass the ctx to F1()? Also the code I have now will take 4 seconds even if F1() returns in less then 4. How can I return as soon as F1() returns?
func handler(w http.ResponseWriter, r *http.Request) {
ctx:= r.context()
F1()
select {
case <-ctx.Done():
case <- time.After( 4*time.Second):
}
w.WriteHeader(http.statusOk)
return
}
To begin, I highly recommend taking a look at the Context blog post to familiarize yourself with contexts, in addition to reading over the context documentation itself.
To address your specific questions:
How can you cancel the database query if the user cancels their quest?
To make this work, there are a few things you want to check:
Ensure that your database driver (if you are using database/sql) supports context cancellation.
Ensure you are using the Context variants of all available methods (e.g. db.QueryContext instead of db.Query).
Ensure that you are passing the context (or a derivative of the context) through the stack from your HTTP request through to the database calls.
Do I need to pass the ctx to F1()?
Per #3 above, yes: you will need to pass the context through all intermediate calls to "connect" the database call with the request context.
How can I return as soon as F1() returns?
The code that you have in your question calls F1 in series, rather than concurrently, with your cancellation/timeout select.
If you want to apply a specific deadline to your database call, use context.WithTimeout to limit how long it can take. Otherwise, you do not need to do anything special: just call F1 with your context, and the rest will happen for you, no select is needed.

Lua producer-consumer pattern with consumers waiting for different data

The problem
One data source generating data in format {key, value}
Multiple receivers each waiting for different key
Example
Getting data is run in loop. Sometimes I will want to get next value labelled with key by using
Value = MyClass:GetNextValue(Key)
I want my code to stop there until the value is ready (making some sort of future(?) value). I've tried using simple coroutines, but they work only when waiting for any data.
So the question I want to ask is something like How to implement async values in lua using coroutines or similar concept (without threads)?
Side notes
The main processing function will, apart from returning values to waiting consumers, process some of incoming data (say, labeled with special key) itself.
The full usage context should look something like:
-- in loop
ReceiveData()
ProcessSpecialData()
--
-- Called outside the loop:
V = RequestDataWithGivenKey(Key)
How to implement async values
You start by not implementing async values. You implement async functions: you don't get the value back until has been retrieved.
First, your code must be in a Lua coroutine. I'll assume you understand the care and feeding of coroutines. I'll focus on how to implement RequestDataWithGivenKey:
function RequestDataWithGivenKey(key)
local request = FunctionThatStartsAsyncGetting(key)
if(not request:IsComplete()) then
coroutine.yield()
end
--Request is complete. Return the value.
return request:GetReturnedValue()
end
FunctionThatStartsAsyncGetting returns a request back to the function. The request is an object that stores all of the data needs to process the specific request. It represents asking for the value. This should be a C-function that starts the actual async getting.
The request will be either a userdata or an encapsulated Lua table that stores enough information to communicate with the C-code that's doing the async fetching. IsComplete uses the internal request data to see if that request has completed. GetReturnedValue can only be called when IsComplete returns true; it puts the value on the Lua stack, so that this function can return it.
Your external code simply needs to handle the async stuff internally. Between resumes of these Lua coroutines, you'll need to pump whatever async stuff is doing the fetching, if there are outstanding requests.

Resources