Slow performance in a second POST request on SAPUI5 - sapui5

the community of SAPUI5 in the world is so small, so i need to see if someone can help me with this problem or an explanation of what may be happening next.
I have a UI5 application which consumes gateway services using the oDataModel,
When I try to make a POST request, the service responds very quickly, but the second time I call the same service the times of the request increase drastically, as in 200%. The strangest thing of all is that the first request and the second are the same.
In my browser, the first request has a success time of approximately 10 seconds, while the second request (which is equal to the first) has a time of 2-3 minutes.
In my browser, THE SECOND REQUEST appears with status of "Pending" for 2-3 minutes, but in gateway the request was completed correctly in like 20 seconds.
this is the way i call the oDataModel the first time and the second time.
SERVICE
var oModel = new sap.ui.model.odata.ODataModel(serviceUrl);
oModel.headers = {
"X-Requested-With": "XMLHttpRequest",
"Accept": "application/atom+xml,application/atomsvc+xml,application/xml,application/atom+xml",
"Content-Type": "application/atom+xml",
"DataServiceVersion": "2.0"
};
oModel.setCountSupported(false);
oModel.setSizeLimit(this._maxSize);
oModel.attachRequestFailed(this.showLoadError);
then, in my controller i do the following.
CONTROLLER
function initializeOrders(){
var oParameters = {
Lgnum: localStorage.Yard,
PlanStatus: "",
Orders: [{}],
Transports: [{}]
};
oModel.create("/IncomingSet", oParameters,
null,
jQuery.proxy(this._readODataOnSuccess, this),
jQuery.proxy(this._readODataOnError, this)
)}
This initializeOrders function is executed when the application is started and it is also executed when I want to refresh the application information if there were changes.
If someone can help me with this question I will be very grateful because not in the sap forums I have not found anything good

I found the problem, it was the rendering of some controls, but the chrome console show like pending because of that. this must be closed, as a solution for all the people who find this problem:
-If you have a control that uses a big amount of data coming from the service always try to use it on demand, the amount of data can block the memory of the browser. In example, a dynamic combobox charged with model
the best practice is just to set the model when you need it
maybe its a bug from Chrome or i dont know, well... its solved... 2 weeks to solve this.

Related

Getting OperationResult when ResultUrl is not in response object?

I am turning to the community as I haven't found anything in the official documentation.
As the title says, I am having troubles fetching the operation result. I am creating an operation by calling the Project - Create REST endpoint. The HTTP call is responding with the operation reference, as the operation is successfully queued. While the operation is running (States NotSet, Queued, InProgress), I am polling the operation at an 300 ms interval. After several seconds, the operation results in a success state.
As the operation was successful, I would expect that the resultUrl property of the Operation is populated with the URL pointing to the created resource (in my case in the form of https://dev.azure.com/{organization}/_apis/projects/{projectId}?api-version=6.0). However, resultUrl is not part of the response of the GET call at all.
Is there anything I am missing or misinterpreting? Any help is appreciated, thanks in advance.
The problem is not clear in your question. If you create a new project, you know its name. The URL to projects is stable:
https://dev.azure.com/{organization}/_apis/projects/{projectNAME}?api-version=6.0
You can get ProjectState in the answer and any over information like the project URL (TeamProject).

Project Reactor and Server Side Events

I'm looking for a solution that will have the backend publish an event to the frontend as soon as a modification is done on the server side. To be more concise I want to emit a new List of objects as soon as one item is modified.
I've tried implementing on a SpringBoot project, that uses Reactive Web, MongoDB which has a #Tailable cursor that publish an event as soon as the capped collection is modified. The problem is that the capped collection has some limitation and is not really compatible with what I want to do. The thing is I cannot update an existing element if the new one has a different size(as I understood this is illegal because you cannot make a rollback).
I honestly don't even know if it's doable, but maybe I'm lucky and I'll run into a rocket scientist right here that will prove otherwise.
Thanks in advance!!
*** EDIT:
Sorry for the vague question. Yes I'm more focused on the HOW, using the Spring Reactive framework.
When I had a similar need - to inform frontend that something is done on the backend side - I have used a message queue.
I have published a message to the queue from the backend and the frontend consumed the message.
But I am not sure if that is what you're looking for.
if you are using webflux with spring reactor, I think you can simply have a client request with content-type as 'text/event-stream' or 'application/stream+json' and You shall have API that can produce those content-type. This gives you SSE model without too much effort.
#GetMapping(value = "/stream", produces = {MediaType.TEXT_EVENT_STREAM_VALUE, MediaType.APPLICATION_STREAM_JSON_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE})
public Flux<Message> get(HttpServletRequest request) {
Just as an idea - maybe you need to use a web socket technology here:
The frontend side (I assume its a client side application that runs in a browser, written in react, angular or something like that) can establish a web-socket communication with the backend server.
When the process on backend finishes, the message from backend to frontend can be sent.
You can do emitting changes by hand. For example:
endpoint:
public final Sinks.Many<SimpleInfoEvent> infoEventSink = Sinks.many().multicast().onBackpressureBuffer();
#RequestMapping(path = "/sseApproach", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<SimpleInfoEvent>> sse() {
return infoEventSink.asFlux()
.map(e -> ServerSentEvent.builder(e)
.id(counter.incrementAndGet() + "")
.event(e.getClass().getName())
.build());
}
Code anywhere for emitting data:
infoEventSink.tryEmitNext(new SimpleInfoEvent("any custom event"));
Watch out of threads and things like "subscribeOn", "publishOn", but basically (when not using any third party code), this should work good enough.

Facebook Messenger Bot Proactive/Push Notifications using Azure

I am building a bot for for Facebook Messenger using Microsoft Bot Framework. I am planning to use CosmosDB for State Management and also as my backend data store. (I am not stuck to CosmosBD and can use any other store if needed)
I need to send daily/weekly proactive messages(push notifications) to users based on their time preference. I will capturing their time preference when they first interact with the bot.
What is the best way to deliver these notifications?
As I will be storing these preferences in CosmosDB, I am thinking using ComosDB trigger of creating an Azure Function and schedule it based on the user time preference. This Azure function will make a call to my webhook which will deliver these messages. If requried, I will change Function schedule when a user changes his/her preference.
My questions are:
Is this a good approach?
Are there any other alternatives (Notifications Hub?)
I should be able to set specific times for notifications (like at the top of the hour or something like that), does it make sense to schedule an Azure Function to run at these hours rather than creating a function based on user preference (I can actually combine these two approaches too)
Thank you in advance.
First, I don't think there's any "right" answer to be given here; it's going to depend a lot on your domain's specific needs. Scale is going to play a major factor in the design of this. Will you have 100 users? 10000 users? 1mil users? I'm going to assume you want to design for maximum scale up front, but it could be overkill.
First, based on what you've described, I don't think a CosmosDB trigger is necessarily the solution to your problem because that's only going to fire when the preference data is created/updated. I assume that, from that point forward, your function needs to continuously fire at the time slot they've opted into, correct?
So let's pretend you let people choose from the 24hrs in the day. A naïve approach would be to simply use a scheduled trigger that fires up every hour, queries the CosmosDB for all the documents where the preference is set to that particular hour and then begins sending out notifications from there. The problem is how you scale from there and deal with issues of idempotency in the face of failures.
First off, a timer trigger only ever spins up one instance. If you were to just go query the CosmosDB documents and start processing them one by one in the scope of that single trigger, you'd hit a ceiling relatively quickly on how many notifications you can scale to. Instead what you'd want to do is use that timer trigger to fan out the notifications to as many "worker" function instances as possible. The timer trigger can act as the orchestrator in the sense that it can own the query against the CosmosDB and then turn each document result it finds for that particular notification time window into a message that it places on a queue to be processed by a separate function which will scale out on its own.
There are actually a couple ways you can accomplish this with Azure Functions, it really depends on how early an adopter of technology you are comfortable with being.
The first is what I would call the "manual" way which would be done by simply using the existing Azure Storage Queue extension by taking an IAsyncCollector<YourNotificationWorkerMessage> as a parameter to the timer function that's bound to the worker queue and then pumping out the messages through that. Then you write a second companion function which uses a QueueTrigger, bind it to that same queue, and it will take care of processing each message. This second function is where you get the scaling, enabling process all of the queued messages as quickly as possible based on whatever scaling parameters you choose to configure. This is the "simplest" approach
The second approach would be to adopt the newer Durable Functions extension. With that model, you don't have to directly think about creating a worker queue. You simply kick off a new instance of your orchestrator function from the timer function and the orchestrator fans out the work by invoking N "concurrent" calls to an action for each notification. Now, it happens to distribute those calls using queues under the covers, but that's an implementation detail that you need no longer maintain yourself. Additionally, if the work of delivering the notification requires more involved work and/or retry logic, you might actually consider using a sub-orchestration instead of a simple action. Finally, another added benefit of this approach, is that you can "fan back in" to your main orchestrator function once all the notifications are delivered to do some follow up work... even if that's simply some kind of event logging that the notification cycle has completed for this hour.
Now, the challenge with either of these approach is actually dealing with failure in initially fetching the candidates for notification from CosmosDB, paging through the results and making sure you actually fan all of them out in an idempotent manner. You need to deal with possible hiccups as you page and you need to deal with the fact that your whole function could be torn down and you might have to restart. Perhaps on the initial run of the 8AM notifications you got through page 273 out of 371 pages and then you got hit with a complete network connectivity fail or the VM your function was running on suffered a power failure. You could resume, but you'd need to know that you left off on page 273 and that you actually processed the 27th record out of that page and start from there. Otherwise, you risk sending double notifications to your users. Maybe that's something you can accept, maybe it's not. Maybe you're ok with the 27 notifications on that page being duplicated as long as the first 272 pages aren't. Again, this is something you need to decide for your domain, but if you want to avoid this issue your orchestrator function will need to track its progress to ensure that it doesn't send out dupes. Again I would say Durable Functions has a leg up here as it comes with the ability to configure retries. Maintaining the state of a particular run is left up to the author in either approach though.
I use pro-active dialog extensively with botframwork and messenger without any issue. During your facebook approval process you simply need to inform them you will be sending notifications trough messenger with your bot. Usually if you use it to inform your user and stay away from promotional content you should be fine.
I also use azure function to trigger the pro-active dialog from a custom controller endpoint.
Bellow sample code for azure function:
public static void Run(TimerInfo notificationTrigger, TraceWriter log)
{
try
{
//Serialize request object
string timerInfo = JsonConvert.SerializeObject(notificationTrigger);
//Create a request for bot service with security token
HttpRequestMessage hrm = new HttpRequestMessage()
{
Method = HttpMethod.Post,
RequestUri = new Uri(NotificationEndPointUrl),
Content = new StringContent(timerInfo, Encoding.UTF8, "application/json")
};
hrm.Headers.Add("Authorization", NotificationApiKey);
log.Info(JsonConvert.SerializeObject(hrm));
//Call service
using (var client = new HttpClient())
{
Task task = client.SendAsync(hrm).ContinueWith((taskResponse) =>
{
HttpResponseMessage result = taskResponse.Result;
var jsonString = result.Content.ReadAsStringAsync();
jsonString.Wait();
if (result.StatusCode != System.Net.HttpStatusCode.OK)
{
//Throw what ever problem as an exception with details
throw new Exception($"AzureFunction - ERRROR - HTTP {result.StatusCode}");
}
});
task.Wait();
}
}
catch (Exception ex)
{
//TODO log
}
}
Bellow sample code for starting the pro-active dialog:
public static async Task Resume<T, R>(string resumptionCookie) where T : IDialog<R>, new()
{
//Deserialize reference to conversation
ConversationReference conversationReference = JsonConvert.DeserializeObject<ConversationReference>(resumptionCookie);
//Generate message from bot to user
var message = conversationReference.GetPostToBotMessage();
var builder = new ContainerBuilder();
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
//From a cold start the service is not yet authenticated with dev bot azure services
//We thus must trust endpoint url.
if (!MicrosoftAppCredentials.IsTrustedServiceUrl(message.ServiceUrl))
{
MicrosoftAppCredentials.TrustServiceUrl(message.ServiceUrl, DateTime.MaxValue);
}
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(CancellationToken.None);
//This is our dialog stack
var task = scope.Resolve<IDialogTask>();
T dialog = scope.Resolve<T>(); //Resolve the dialog using autofac
try
{
task.Call(dialog.Void<R, IMessageActivity>(), null);
await task.PollAsync(CancellationToken.None);
}
catch (Exception ex)
{
//TODO log
}
finally
{
//flush dialog stack
await botData.FlushAsync(CancellationToken.None);
}
}
}
Your dialog needs to be registered in autofac.
Your resumptionCookie needs to be saved in your db.
You might want to check FB policy regarding proactive messages
There’s a 24h limit but it might not be totally screwed in your case
https://developers.facebook.com/docs/messenger-platform/policy/policy-overview#standard_messaging

Should a RESTful API avoid requiring the client to know the resource hierarchy?

Our API's entry point has a rel named "x:reports" (where x is a prefix defined in the HAL representation, by way of a curie - but that's not important right now).
There are several types of reports. Following "x:report" provides a set of these affordances, each with a rel of its own - one rel is named "x:proofofplay". There is a set of lookup values associated with this type of report (and only this type of report). The representation returned by following "x:proofofplay" has a rel to this set of values "x:artwork".
This results in the following hierarchy
reports
proofofplay
artwork
While the "x:artwork" resource is fairly small, it does take some time to fetch it (10 sec). So the client has opted to async load it at app launch.
In order to get the "x:artwork"'s href the client has to follow the links. I'm not sure whether this is a problem. It seems potentially unRESTful, as the client is depending on out-of-band knowledge of the path to this resource. If ever path to artwork changes (highly unlikely) the client will break (though the hrefs themselves can change with impunity).
To see why I'm concerned, the launch function looks like this:
launch: function () {
var me = this;
Rest.getLinksFromEntryPoint(function(links) {
Rest.getLinksFromHref(links["x:reports"].href, function(reportLinks){
Rest.getLinksFromHref(reportLinks["x:proofofplay"].href, function(popLinks){
me.loadArtworks(popLinks["x:artwork"].href);
});
});
});
}
This hard-coding of the path simultaneously makes me think "that's fine - it's based on a published resource model" and "I bet Roy Fielding will be mad at me".
Is this fine, or is there a better way for a client to safely navigate such a hierarchy?
The HAL answer to this is to embed the resources.
Depending a bit on your server-side technology, this should be good enough in your case because you need all the data to be there before the start of the application, and since you worry about doing this sequentially, you might parallelize this on the server.
Your HAL client should ideally treat things in _links and things in _embedded as the same type of thing, with the exception that in the second case, you are also per-populating the HTTP cache for the resources.
Our js-based client does something like this:
var client = new Client(bookMarkUrl);
var resource = await client
.follow('x:reports')
.follow('x:proofofplay')
.follow('x:artwork')
.get();
If any of these intermediate links are specified in _links, we'll follow the links and do GET requests on demand, but if any appeared in _embedded, the request is skipped and the local cache is used. This has the benefit that in the future we can add new things from _links to _embedded, and speeding up clients who don't have to be aware of this change. It's all seamless.
In the future we intend to switch from HAL's _embedded to use HTTP2 Push instead.

How to write/update session data before a request end in Perl Catalyst MVC Framework

How can I write or update session data before a request ends in Perl MVC Catalyst Framework.
I am using Session::State::Cookie and Session::Store::FastMap
I need to ensure that the data is available before the long-running request completes
This is what worked for me.
To ensure the information is updated at the time it is set in the long running request, I do a $c->finalize_session just after updating some importante information related to the session:
$c->session->{important_info} = "new value";
$c->finalize_session;
I verified that the other requests are gathering the right value after that.
I did not observed any side effects calling $c->finalize_session many times during a request just to ensure the session data to be updated, but I am not certained about this.
One of the informations that I am setting in this way is a counter to update a progress bar to feedback the user (because this task takes a long time). I do not know if it is the best way to do that, I will appreciate any suggestion.
You can do some last-second processing just before a request is completed and the response sent to the client by overriding the handle_request method in your application's main module or a plugin.
sub handle_request {
my ($c, #args) = #_;
my $status = $c->next::method(#args);
# Do some last minute processing before the request is completed.
return $status;
}
I've overridden this method before to collect stats about a request or restart a worker process if it uses too much memory. Let me know if this is helpful or if you have more questions about it.