What is the difference between call_cq and notification_cq in gRPC? - grpc

https://github.com/grpc/grpc/blob/master/examples/cpp/helloworld/greeter_async_server.cc#L91
service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
this);
The two occurrences of cq_ look strange to me so I dig into the source code which leads me to
https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/service_type.h#L92
void RequestAsyncUnary(int index, ServerContext* context, Message* request,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag, request);
}
So what's the difference between call_cq and notification_cq? What are the potential uses/benefits for using difference completion queues?

Here's a quote from the google-groups forum for grpc when this same question was asked.
https://groups.google.com/forum/#!topic/grpc-io/V4NAQ77PMEo
Notification_cq gets the tag back indicating a call has started. All subsequent operations (reads, writes, etc) on that call report back to call_cq. For most async servers my recommendation is to use the same cq. Places where you might not:
Our sync API creates a cq per call under the covers... So it posts a general event >queue for notification_cq, and it's specific queue as call_cq.
If you want to be able to control when you accept incoming calls vs when you don't (by suspending polling on a notification_cq)
I'm sure folks can think of others.
This allows fine-grained control over which threads handle which kinds of events (based on which queues they are polling). Like you may have a master thread polling the notification_cq and worker threads all polling their own call_cqs, or something like that.

Related

Returning multiple items in gRPC: repeated List or stream single objects?

gRPC newbie. I have a simple api:
Customer getCustomer(int id)
List<Customer> getCustomers()
So my proto looks like this:
message ListCustomersResponse {
repeated Customer customer = 1;
}
rpc ListCustomers (google.protobuf.Empty) returns (ListCustomersResponse);
rpc GetCustomer (GetCustomerRequest) returns (Customer);
I was trying to follow Googles lead on the style. Originally I had returns (stream Customer) for GetCustomers, but Google seems to favor the ListxxxResponse style. When I generate the code, it ends up being:
public void getCustomers(com.google.protobuf.Empty request,
StreamObserver<ListCustomersResponse> responseObserver) {
vs:
public void getCustomers(com.google.protobuf.Empty request,
StreamObserver<Customer> responseObserver) {
Am I missing something? Why would I want to go through the hassle of creating a ListCustomersResponse when I can just do stream Customer and get the streaming functionality?
The ListCustomersResponse is just streaming the whole list at once vs streaming each customer. Googles preference seems to be to return the ListCustomersResponse style all of the time.
When is it appropriate to use the ListxxxResponse vs the stream response?
This question is hard to answer without knowing what reference you're using. It's possible there's a miscommunication, or that the reference is simply wrong.
If you're looking at the gRPC Basics tutorial though, then I might have an inkling as to what caused a miscommunication. If that's indeed your reference, then it does not recommend returning repeated fields for streamed responses; your intuition is correct: you would just want to stream the singular Customer.
Here is what it says (screenshot intentional):
You might be reading rpc ListFeatures(Rectangle) as meaning an endpoint that returns a list [noun] of features. If so, that's a miscommunication. The guide actually means an endpoint to list [verb] features. It would have been less confusing if they just wrote rpc GetFeatures(Rectangle).
So, your proto should look more like this,
rpc GetCustomers (google.protobuf.Empty) returns (stream Customer);
rpc GetCustomer (GetCustomerRequest) returns (Customer);
generating exactly what you suspected made more sense.
Update
Ah I see, so you're looking at this example in googleapis:
// Lists shelves. The order is unspecified but deterministic. Newly created
// shelves will not necessarily be added to the end of this list.
rpc ListShelves(ListShelvesRequest) returns (ListShelvesResponse) {
option (google.api.http) = {
get: "/v1/shelves"
};
}
...
// Response message for LibraryService.ListShelves.
message ListShelvesResponse {
// The list of shelves.
repeated Shelf shelves = 1;
// A token to retrieve next page of results.
// Pass this value in the
// [ListShelvesRequest.page_token][google.example.library.v1.ListShelvesRequest.page_token]
// field in the subsequent call to `ListShelves` method to retrieve the next
// page of results.
string next_page_token = 2;
}
Yeah, I think you've probably figured the same by now, but here they have chosen to use a simple RPC, as opposed to a server-side streaming RPC (see here). I emphasize this because, I think the important choice is not the stylistic difference between repeated versus stream, but rather the difference between a simple request-response API versus a more complex and less-ubiquitous streaming API.
In the googleapis example above, they're defining an API that returns a fixed and static number of items per page, e.g. 10 or 50. It would simply be overcomplicated to use streaming for this, when pagination is already so well-understood and prevalent in software architecture and REST APIs. I think that is what they should have said, rather than "a small number." So the complexity of streaming (and learning cost to you and future maintainers) has to justified, that's all. Suppose you're actually fetching thousands of (x, y, z) items for a Point Cloud or you're creating a live-updating bid-ask visualizer for some cryptocurrency, e.g.
Then you'd start asking yourself, "Is a simple request-response API my best option here?" So it just tends to be that, the larger the number of items needing to be returned, the more streaming APIs start to make sense. And that can be for conceptual reasons, e.g. the items are a live-updating stream in time like the above crypto example, or architectural, e.g. it would be more efficient to start displaying results in the UI as partial data streams back. I think the "small number" thing you read was an oversimplification.

How to make command to wait until all events triggered against it are completed successfully

I have came across a requirement where i want axon to wait untill all events in the eventbus fired against a particular Command finishes their execution. I will the brief the scenario:
I have a RestController which fires below command to create an application entity:
#RestController
class myController{
#PostMapping("/create")
#ResponseBody
public String create(
org.axonframework.commandhandling.gateway.CommandGateway.sendAndWait(new CreateApplicationCommand());
System.out.println(“in myController:: after sending CreateApplicationCommand”);
}
}
This command is being handled in the Aggregate, The Aggregate class is annotated with org.axonframework.spring.stereotype.Aggregate:
#Aggregate
class MyAggregate{
#CommandHandler //org.axonframework.commandhandling.CommandHandler
private MyAggregate(CreateApplicationCommand command) {
org.axonframework.modelling.command.AggregateLifecycle.apply(new AppCreatedEvent());
System.out.println(“in MyAggregate:: after firing AppCreatedEvent”);
}
#EventSourcingHandler //org.axonframework.eventsourcing.EventSourcingHandler
private void on(AppCreatedEvent appCreatedEvent) {
// Updates the state of the aggregate
this.id = appCreatedEvent.getId();
this.name = appCreatedEvent.getName();
System.out.println(“in MyAggregate:: after updating state”);
}
}
The AppCreatedEvent is handled at 2 places:
In the Aggregate itself, as we can see above.
In the projection class as below:
#EventHandler //org.axonframework.eventhandling.EventHandler
void on(AppCreatedEvent appCreatedEvent){
// persists into database
System.out.println(“in Projection:: after saving into database”);
}
The problem here is after catching the event at first place(i.e., inside aggregate) the call gets returned to myController.
i.e. The output here is:
in MyAggregate:: after firing AppCreatedEvent
in MyAggregate:: after updating state
in myController:: after sending CreateApplicationCommand
in Projection:: after saving into database
The output which i want is:
in MyAggregate:: after firing AppCreatedEvent
in MyAggregate:: after updating state
in Projection:: after saving into database
in myController:: after sending CreateApplicationCommand
In simple words, i want axon to wait untill all events triggered against a particular command are executed completely and then return to the class which triggered the command.
After searching on the forum i got to know that all sendAndWait does is wait until the handling of the command and publication of the events is finalized, and then i tired with Reactor Extension as well using below but got same results: org.axonframework.extensions.reactor.commandhandling.gateway.ReactorCommandGateway.send(new CreateApplicationCommand()).block();
Can someone please help me out.
Thanks in advance.
What would be best in your situation, #rohit, is to embrace the fact you are using an eventually consistent solution here. Thus, Command Handling is entirely separate from Event Handling, making the Query Models you create eventually consistent with the Command Model (your aggregates). Therefore, you wouldn't necessarily wait for the events exactly but react when the Query Model is present.
Embracing this comes down to building your application such that "yeah, I know my response might not be up to date now, but it might be somewhere in the near future." It is thus recommended to subscribe to the result you are interested in after or before the fact you have dispatched a command.
For example, you could see this as using WebSockets with the STOMP protocol, or you could tap into Project Reactor and use the Flux result type to receive the results as they go.
From your description, I assume you or your business have decided that the UI component should react in the (old-fashioned) synchronous way. There's nothing wrong with that, but it will bite your *ss when it comes to using something inherently eventually consistent like CQRS. You can, however, spoof the fact you are synchronous in your front-end, if you will.
To achieve this, I would recommend using Axon's Subscription Query to subscribe to the query model you know will be updated by the command you will send.
In pseudo-code, that would look a little bit like this:
public Result mySynchronousCall(String identifier) {
// Subscribe to the updates to come
SubscriptionQueryResult<Result> result = QueryGateway.subscriptionQuery(...);
// Issue command to update
CommandGateway.send(...);
// Wait on the Flux for the first result, and then close it
return result.updates()
.next()
.map(...)
.timeout(...)
.doFinally(it -> result.close());
}
You could see this being done in this sample WebFluxRest class, by the way.
Note that you are essentially closing the door to the front-end to tap into the asynchronous goodness by doing this. It'll work and allow you to wait for the result to be there as soon as it is there, but you'll lose some flexibility.

ASP.NET Core, overkilling Task.Run()?

Lets say we have an ASP.NET Core receiving a string as a payload, size order of couple of megabytes. First method implementation:
[HttpPost("updateinfos")]
public async Task UpdateInfos()
{
var len = (int)this.Request.ContentLength;
byte[] b = new byte[len];
await this.Request.Body.ReadAsync(b,0,len);
var content = Encoding.UTF8.GetString(b);
.....
}
Body is read with ReadAsync, this is good since we have I/O stuff on socket and having it asynchronous is for free due to the nature of the call itself. But if we have a look after, the GetString() method, is purely CPU, is blocking with linear complexity. Anyway this affect somehow the performance since other clients wait for my bytes to get converted in string. I think to avoid this the solution is to run GetString() on the thread pool, by this:
[HttpPost("updateinfos")]
public async Task UpdateInfos()
{
var len = (int)this.Request.ContentLength;
byte[] b = new byte[len];
await this.Request.Body.ReadAsync(b,0,len);
var content = await Task.Run(()=>ASCIIEncoding.UTF8.GetString(b));
.....
}
please don't mind the return right now, something more has to be done in the function.
So the question, is the second approach overkilling? If so, what is the boundary to discriminate what could be run as blocking and what has to be moved to another thread?
You are very much abusing Task.Run there. Task.Run is used to off-load work onto a different thread and asynchronously wait for it to complete. So every Task.Run call will cause thread context switches. Of course, that is usually a very bad idea to do for things that should not run on their own thread.
Things like ASCIIEncoding.UTF8.GetString(b) are really fast. The overhead involved in creating and managing a thread that encapsulates this is much larger than just executing this directly on the same thread.
You should generally use Task.Run only to off-load (primarily synchronous) work that can benefit from running on its own thread. Or in cases, where you have work that would take a bit longer but block the current execution.
In your example, that is simply not the case, so you should just call those methods synchronously.
If you really want to reduce the work for that code, you should look at how to work properly streams. What you do in your code is read the request body stream completely and only then you work on it (trying to translate into a string).
Instead of separating the process of reading the binary stream and then translating it into a string, you could just read the stream as a string directly using a StreamReader. That way, you can read the request body directly, even asynchronously. So depending on what you actually do with it afterwards, that may be a lot more efficient.

Can a thread in ASP.NET work keep continue after Response.End?

I want to make a tcp connection to a device and keep continously retrieve data from device. I want to start this with a simple request and keep it working background even Page response completed. Is this possible in asp.net?
Can a thread in ASP.NET work keep continue after Response.End?
Yes, you can if you do not care or do not need the result.
For example, in the following code, you call AddLogAsync and insert a log, but you not care whether insert successful or not.
public Task AddLogAsync(Log log)
{
return Task.Run(() => AddLog(log));
}
private void AddLog(TraceLog traceLog)
{
// Do something here.
}
I want to make a tcp connection to a device and keep continously
retrieve data from device. I want to start this with a simple request
and keep it working. Is this possible in asp.net?
I'm not really understanding above question. After Response.End, you cannot return anything, although you can continue work on something in different thread.

Is HttpApplicationState.RemoveAll() thread safe?

In my asp.net application, i want to cache some data in the HttpApplicationState.
My code to set the data looks like this:
Application.Lock();
Application.Set("Name", "Value");
Application.UnLock();
When I read the documentation, it says that HttpApplicationState is implicitly thread safe. But on many blogs it's written that we should use Application.Lock() and Application.Unlock() while writing data to the HttpApplicationState.
On the other hand, I could not find any documentation which says that we should use lock while reading data from HttpApplicationState or while clearing it (using Application.RemoveAll()) method.
My questions are:
Should not we take care of thread-safety when we are calling RemoveAll? In my application, it's possible that one thread is reading a data from HttpApplicationState whereas other thread could call RemoveAll.
In this case when reading and clearing HttpApplicationState is possible from two different threads at the same time, should reading too not be thread safe?
You only need the lock if you are doing more than one operation against the application state. In you case you are just doing one operation, so it's perfectly safe without the lock:
Application.Set("Name", "Value");
If you do more than one operation, and they rely on each other, you need the lock. For example:
Application.Lock();
string name = Application.Get("Name");
if (name == null) {
Application.Set("Name", "Value");
}
Application.UnLock();
As far as I can tell, the RemoveAll is thread safe as it calls the Clear method internally.
The Clear method calls HttpApplicationStateLock.AcquireWrite and then calls the base.BaseClear and finally releases the lock.
Also have a look at
HttpApplicationState - Why does Race condition exist if it is thread safe?

Resources