Grpc async bidirectional client using c++ - asynchronous

I am using bidirectional grpc between my client and server. I would like to implement async bidi on both client and server i.e., client opens a stream and starts sending arbitrary messages to server, while another thread continues receiving server responses. This example below demonstrates the server side async bidi https://groups.google.com/forum/m/#!topic/grpc-io/DuBDpK96B14.
Has anyone tried async bidi on client side?

There's a codelab for it with both client and server at https://grpc.io/docs/tutorials/async/helloasync-cpp/
Async client
To use an asynchronous client to call a remote method, you first create a channel and stub, just as you do in a synchronous client. Once you have your stub, you do the following to make an asynchronous call:
Initiate the RPC and create a handle for it. Bind the RPC to a CompletionQueue.
CompletionQueue cq;
std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
stub_->AsyncSayHello(&context, request, &cq));
Ask for the reply and final status, with a unique tag
Status status;
rpc->Finish(&reply, &status, (void*)1);
Wait for the completion queue to return the next tag. The reply and status are ready once the tag passed into the corresponding Finish() call is returned.
void* got_tag;
bool ok = false;
cq.Next(&got_tag, &ok);
if (ok && got_tag == (void*)1) {
// check reply and status
}
You can see the complete client example in greeter_async_client.cc.

Related

What is the type of data we receive from signalr hub?

I am writing a streaming component by sending mediarecorder blob(event.data) to a SignalR hub and return the same blob to other users connected using SendAsync method. But, the object I receive from hub is different from what I passed to hub. Because, my client side JS code does not recognize it like an event.data object.
My question is how the object will change after passing to hub? Here is the hub code and how I can turn it to initial value after receiving back from hub
public async Task SendBlob(Object blob)
{
await Clients.All.SendAsync("ReceivingBlob", blob);
}

Spring WebFlux Broken Stream Error Handling

I'm struggling to find any good examples on how to implement error handling with Spring WebFlux.
The use case I want to handle is notifying HTTP clients that a stream has terminated unexpectedly. What I have found it that with the out of the box behaviour, when a stream is terminated, for example by raising a RuntimeException after x items have been processed, is handled too gracefully! The client is flushed all items up until the exception is raised, and then the connection is closed. As far as the client is concerned the request was successful. The following code shows how this has been setup:
public Mono<ServerResponse> getItems(ServerRequest request) {
Counter counter = new Counter(0);
return ServerResponse
.ok()
.contentType(MediaType.APPLICATION_STREAM_JSON)
.body(operations.find(query, Document.class, "myCollection")
.map(it -> {
counter.increment();
if(counter.getCount() > 500) {
throw new RuntimeException("an error has occurred");
}
return it;
}), Document.class);
}
What is the recommended way to handle the error and notify the HTTP client that the stream terminated unexpectedly?
It really depends on how you'd like to communicate that failure to the client. Should the client display some specific error message? Should the client reconnect automatically?
If this is a "business error" that doesn't prevent you from writing to the stream, you could communicate that failure using a specific event type (look at the Server Sent Events spec).
Spring WebFlux supports ServerSentEvent<T>, which allows you to control various fields such as event, id, comment and data (the actual data). Using an Flux::onErrorMap operator, you could write a specific ServerSentEvent that has an "error" event type (look at the ServerSentEvent.builder() for more).
But this is not transparent to the client, as you'd have to subscribe to specific events and change your JavaScript code otherwise you may display error messages as regular messages.

Spring Job Response To Client

Spring batch job runs to completion successfully with following code:
#RestController
#RequestMapping(value = "api/jobs")
public class JobLaunchingController {
#Autowired
private JobOperator jobOperator;
#RequestMapping(value = "/pay/{paymentPeriod}", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.ACCEPTED)
public void launchPaymentJob(#PathVariable Integer paymentPeriod) throws Exception {
this.jobOperator.start("paymentJob", String.format("paymentPeriod=%s,time=" + System.currentTimeMillis(), paymentPeriod));
}
}
I am using JavaFX client where the endpoint is used to send request for the job to be launched. Basically, with the help of jersey client http request is sent like so
Client client = ClientBuilder.newBuilder().build();
WebTarget webTarget = client.target(getBaseUri()).path(path);
Response response = webTarget.request().get(Response.class);
The problem is i don't have a way for the client to know when the job is complete. How can client be notified by server when job is done
Any help is highly appreciated.
This is more of a architectural question than coding. You can solve this by multiple ways, I will suggest you below three
Simplest -> If your jobs doesn't take long - make your client wait for the outcome of job. Send them final status back in response.
Send job reference number immediately to client and introduce another endpoint where client can check with reference number if jobs is done - This involves your client having some polling mechanism.
Use something like Server Sent Events/Websockets - Thanks cerp0
How can client be notified by server when job is done?
Try to use Websokets to send data from server to client. Here is a pretty good guide how to do it with Spring.
On the client side I believe you can use this approach: https://github.com/nickebbutt/stomp-websockets-java-client

Request Flow in Asynchronous Controller Spring MVC

I was trying to understand Asynchronous Controller implementation from one of links:
http://shengwangi.blogspot.in/2015/09/asynchronous-spring-mvc-hello-world.html
I was puzzled on point that Controller thread received request and exists. Then service method received the request for further processing.
#RequestMapping("/helloAsync")
public Callable<String> sayHelloAsync() {
logger.info("Entering controller");
Callable<String> asyncTask = new Callable<String>() {
#Override
public String call() throws Exception {
return helloService.doSlowWork();
}
};
logger.info("Leaving controller");
return asyncTask;
}
Since, Controller exists it and pass the control to appropriate handler mapping/ jsp. What will be seen on the browser for the user ?
Browser waits for the response to process it.
Asynchronous process takes place only at the server end and it has nothing to do with the browser. Browser sends the request and waits for the server to write the response back.
Since you returned Callable doesnt mean that controller exists the flow. Spring`s response handlers will wait for async task to get executed to write the response back.
Please go through AsyncHandlerMethodReturnValueHandler which handles Asynchronous response returned from the controller.
if you return callable then it will be handled by CallableHandlerMethodReturnvaluehandler :
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
}
Callable<?> callable = (Callable<?>) returnValue;
WebAsyncUtils.getAsyncManager(webRequest).startCallableProcessing(callable, mavContainer);
}
I had cleared my doubt from this link:
https://dzone.com/articles/jax-rs-20-asynchronous-server-and-client
However, they used different way to accomplish the asynchronous processing but the core concept should be the same for every approach.
Some important part of the article:
The idea behind asynchronous processing model is to separate
connection accepting and request processing operations. Technically
speaking it means to allocate two different threads, one to accept the
client connection and the other to handle heavy and time consuming
operations. In this model, the container dispatched a thread to accept
client connection (acceptor), hand over the request to processing
(worker) thread and releases the acceptor one. The result is sent back
to the client by the worker thread. In this mechanism client’s
connection remains open. May not impact on performance so much, such
processing model impacts on server’s THROUGHPUT and SCALABILITY a lot.

Does Meteor.call in server side without callback block server?

For example:
server/method.js
Meteor.methods({
insertPost: function(post) {
//call another method
var ret = Meteor.call('longTimeMethod', post.data); // A
// ...
}
})
Meteor doc says
If you do not pass a callback on the server, the method invocation will block until the method is complete.
since nodejs is single thread, if A costs 60 seconds, the whole server will not response to any requests during this 60s?
No, not the whole server will block, only the fiber running for this particular client. If you don't want that, then you can simply call this.unblock() before your method call, and a new fiber will be used for future method calls from that client, see http://docs.meteor.com/#/full/method_unblock.

Resources