Owin- Slow CompatibleWithModel call - entity-framework

I have this line of code within a request of an ApiController of an Azure Mobile App Web API:
var user = t.TrackDependency(() => context.Users.SingleOrDefault(x => x.Email == loginRequest.Id || x.Name == loginRequest.Id), "GetUser");
Here is the result from Application Insights:
We can see that while the line of code took 2613ms, the actual query call to the database took 190ms. While this is an edge case it happens often enough to get complaining users about slow performance.
The thing is I have no idea where the difference could come from. Note this is not due to a cold start, the app was warm when this exact call happened.
The second line is the actual call to the database endpoint. Before that it is not database related.
ps: the graph is from application insights. They capture the call to the database and I add my onwn data through the TrackDependency method.
UPDATE
Today I got more data thanks to Application Insights sampling (great tool!).
Here are the results (this is not the exact request call instance but this is the same problem):
It clearly shows that context.Database.CompatibleWithModel(false) is the culprit. It is called by the call to InitializeDatabase of my custom implementation of IDatabaseInitializer. My custom intializer is set at Startup.
I found another unanswered question on SOF with the same issue
Why does it take so long?
InitializeDatabase is not always called and I don't know when it is called and why.
I found another culprit:
Now we see that EntityConnection.Open is waiting something. Are there some locks on the connection? So far the call to the database endpoint is still not made so we're still on EntityFramework here.
UPDATE 2
There are two issues in that post:
Why is CompatibleWithModel slow? There are many articles about startup time improvements. This is not be adressed in that SOF question.
Why is EntityConnection.Open blocking. This is not related to EntityFramework but is general to getting a connection which takes up to 3 seconds if not called within a 5 minutes windows. I raised that problem in a specific post.
Hence there is no more questions in that post which and it could be deleted but may still be useful as an analysis of tracking down lost time in Web Api calls.

Related

How to perform batch insertion for list of events using Google Calendar API in Dart?

Problem Statement
As a developer, my requirements are to insert a list of events in the Google Calendar with a single call.
Why Batch?
As mentioned here, it helps to reduce the network overheads and increases performance.
Current Scenario
Using the googleapis package, I can only perform a single insert operation as shown in the below snippet :
var eventResponse = await _calendarApi.events
.insert(event, calendarId, sendUpdates: 'all');
From a development perspective, it's not an efficient approach to call this method multiple times.
Also, it would be a bad idea to create an array of the insert method wrapped in Future and use Future.wait() to wait for all the insertion calls to be executed, see below snippet.
Future<List<Event> insertEvents(List<Event> events) async {
var _calendarApi = CalendarApi(_authClient);
List<Future<Event>> _futureEvents = [];
for (int i = 0; i < events.length; i++) {
_futureEvents.add(_calendarApi.events.insert(events[i], calendarId));
}
var _eventResponse =
await Future.wait(_futureEvents).catchError((e) => print(e));
return _eventResponse;
}
As per the official Google Blog, there's no way to perform a batch operation in dart.
Does anyone know a better optimistic solution for this problem?
If you check the Google calendar api documentation for events.insert you will notice that it states.
Creates an event.
There is however the option to use the batching endpoint You should be aware that the only thing batching is going to save you is the HTTP Calls back and forth.
Each call within the batch still counts against your quota it does not count as a single request against your quota. You're limited to 50 calls in a single batch request.
Question: As per the official Google Blog, there's no way to perform a batch operation in dart.
If you check the batching guide it shows how to build up a batching request using HTTP. I would be surprised to find that you could not do this with flutter as well as flutter is capable of a making a HTTP request. I was also unable to find anyone that had gotten it to work. This may just mean that no one has bothered to try or that they just haven't posted the results.
Actually the Batching blog post states that the Dart Client library does not support batching
The Google API Dart Client Library does not support these features.
That does by no means that its not possible at all it just means that your going to have to code it from scratch yourself.
is it worth it.
Again as there is little or no advantage to using batching aside from the HTTP request send limit. You will need to decide if its worth your time trying to get it to work. IMO its not, i have been using these apis for more then 11 years and i have never found batching to be very stable or worth the aggravation it causes.
With batching you tend to get more quota flooding errors as the server things you are sending to many requests at once even sending 5 at once has resulted in flooding errors in my experience and then you have to go back and check which ones made it though to send them again.

Play Framework Database Related endpoints hang after some up time

I have situation which is almost identical to the one described here: Play framework resource starvation after a few days
My application is simple, Play 2.6 + PostgreSQL + Slick 3.
Also, DB retrieval operations are Slick only and simple.
Usage scenario is that data comes in through one endpoint, gets stored into DB (there are some actors storing some data in async fashion which can fail with default strategy) and is served through rest endpoints.
So far so good.
After few days, every endpoint that has anything to do with database stops responding. Application is server on t3-medium on a single instance connected to RDS instance. Connection count to RDS is always the same and stable, mostly idling.
What I have also noticed is that database actually gets called and query gets executed, but request never ends or gets any data.
Simplest endpoint (POST) is for posting feedback - basically one liner:
feedbackService.storeFeedback(feedback.deviceId, feedback.message).map(_ => Success)
This Success thing is wrapper around Ok("something") so no magic there.
Feedback Service stores one record in DB in a Slick preferred way, nothing crazy there as well.
Once feedback post is called, I notice in psql client that INSERT query has been executed and data really ends up in database, but HTTP request never ends and no success data gets returned. In parallel, calling non DB related endpoints which do return some values like status endpoint goes through without problems.
Production logs don't show anything and restarting helps for a day or two.
I suppose some kind of resource starvation is happening, but which and where is currently beyond me.

Proper REST Service Structure For A Q&A Service

I'm creating services that basically issue a set of questions for user authentication (i.e. how old is your pet) and can verify the answers (but must be done within 2 minutes of the questions being presented). The kicker is the question formulation is a long process so I'd like to have a separate call to get it going async.
...call #1
POST \users{user}\challengerequest -- creates the request, takes a few minutes, and returns request ID
...then polls call #2
GET \users{user}\challengerequest{requestID} -- returns the actual questions, the 2 minute timer starts
...call #3
POST \users{user}\challengeresponse{requestID} -- takes the response, verifies the answers, and returns if things are valid or not.
What I don't like about this currently:
- the first time my GET is called, a timer is kicked off and I believe in theory this is like an update which probably shouldn't be done from a GET
- these feel like transient resources and maybe are not good candidates for a RESTful implementation?
I'm interested in hearing your thoughts on implementation. What should I reevaluate? Thanks!
What I don't like about this currently: - the first time my GET is called, a timer is kicked off and I believe in theory this is like an update which probably shouldn't be done from a GET - these feel like transient resources and maybe are not good candidates for a RESTful implementation?
I agree 100%. GET should be idempotent. In this case it is not. I think using a POST to start the questions might be preferred. This also tells down stream servers to not cache the request.

How to design a RESTful api for slow-generated resources or job status?

I am trying to design a RESTful api for a service that accepts a bunch of parameters and generates a large result. This is my first RESTful project. One tricky part is that the server needs some time (up to a few minutes) to generate the result. My current thought is to use POST to send in all the parameters. The server response can be a job id.
I can then retrieve the result using GET /result/{job_id}. The problem is that the result is not available for the first few minutes. Maybe I can return the resource unavailable at the beginning and the result once it is available. But this feels odd and add some odd logic in the client.
An alternative is to retrieve the job status GET /job_status/{job_id}, where the result might be running/error/done, similar to the http status code, where done status also comes with a result_id. Then I can retrieve it with GET /result/{result_id}.
Either case has some problem with what I have read about GET. In both cases, GET result is not fixed and not cacheable at the beginning while the job is still running. On the other hand, I read somewhere that it is OK to do things like GET /currentWhether or Get /currentTime, which are similar to at least my second approach. So my questions are:
Which one is better? Why?
Should I use GET for such situation?
Or neither one is OK? What would you do?
Thank you very much.
Should I use GET?
For long running operations, here is an approach which tells setting expire or max-age headers to your response properly. Here is the example Best practice for implementing long-running searches with REST
But I recommend The RESTy Long-op Protocol for your case.
Your solution will be more robust and more client friendly.

How do you ensure consistent client reads in an eventual consistent system?

I'm digging into CQRS and I am looking for articles on how to solve client reads in an eventual consistent system. Consider for example a web shop where users can add items to their cart. How can you ensure that the client displays items in the cart if the actual processing of the command "AddItemToCart" is done async? I understand the principles of dispatching commands async and updating the read model async based on domain events, but I fail to see how this is handled from the clients perspective.
There are a few different ways of doing it;
Wait at user till consistent
Just poll the server until you get the read model updated. This is similar to what Ben showed.
Ensure consistency through 2PC
You have a queue that supports DTC; and your commands are put there first. They are then; executed, events sent, read model updated; all inside a single transaction. You have not actually gained anything with this method though, so don't do it this way.
Fool the client
Place the read models in local storage at the client and update them when the corresponding event is sent -- but you were expecting this event anyway, so you had already updated the javascript view of the shopping cart.
I'd recommend you have a look at the Microsoft Patterns & Practices team's guidance on CQRS. Although this is still work-in-progress they have given one solution to the issue you've raised.
Their approach for commands requiring feedback is to submit the command asynchronously, redirect to another controller action and then poll the read model for the expected change or a time-out occurs. This is using the Post-Redirect-Get pattern which works better with the browser's forward and back navigation buttons, and gives the infrastructure more time to process the command before the MVC controller starts polling.
Example code from the RegistrationController using ASP.NET MVC 4 asynchronous controllers.
[HttpGet]
[OutputCache(Duration = 0, NoStore = true)]
public Task<ActionResult> SpecifyRegistrantAndPaymentDetails(Guid orderId, int orderVersion)
{
return this.WaitUntilOrderIsPriced(orderId, orderVersion)
.ContinueWith<ActionResult>(
...
);
}
...
private Task<PricedOrder> WaitUntilOrderIsPriced(Guid orderId, int lastOrderVersion)
{
return
TimerTaskFactory.StartNew<PricedOrder>(
() => this.orderDao.FindPricedOrder(orderId),
order => order != null && order.OrderVersion > lastOrderVersion,
PricedOrderPollPeriodInMilliseconds,
DateTime.Now.AddSeconds(PricedOrderWaitTimeoutInSeconds));
}
I'd probably use AJAX polling instead of having a blocked web request at the server.
Post-Redirect-Get
You're hoping that the save command executes on time before Get is called. What if the command takes 10 seconds to complete in the back end but Get is called in 1 second?
Local Storage
With storing the result of the command on the client while the command goes off to execute, you're assuming that the command will go through without errors. What if the back-end runs into an error while processing the command? Then what you have locally isn't consistent.
Polling
Polling seems to be the option that is actually in line with eventual consistency; you're not faking or assuming. Your polling mechanism can be an asynchronous as a part of your page, e.g. shopping cart page component polls until it gets an update without refreshing the page.
Callbacks
You could introduce something like web hooks to make a call back to the client if the client is capable of receiving such. By providing a correlation Id once the command is accepted by the back-end, once the command has finished processing, the back-end can notify the front end of the command's status along with the correlation Id on whether the command went through successfully or not. There is no need for any kind of polling with this approach.