I am uploading multiple files using javascript.
After I upload the files, I need to run several processing functions.
Because of the processing time that is required, I need a UI on the front telling the user the estimated time left of the entire process.
Basically I have 3 functions:
/upload - this is an endpoint for uploading the files
/generate/metadata - this is the next endpoint that should be triggered after /upload
/process - this is the last endpoint. SHould be triggered after /generate/metadata
This is how I expect the screen to look like basically.
Information such as percentage remaining and time left should be displayed.
However, I am unsure whether to allow server to supply the information or I do a hackish estimate solely using javascript.
I would also need to update the screen like telling the user messages such as
"currently uploading"
if I am at function 1.
"Generating metadata" if I am at function 2.
"Processing ..." if I am at function 3.
Function 2 only occurs after the successful completion of 1.
Function 3 only occurs after the successful completion of 2.
I am already using q.js promises to handle some parts of this, but the code has gotten scarily messy.
I recently come across Backbone and it allows structured ways to handle single page app behavior which is what I wanted.
I have no problems with the server-side returning back json responses for success or failure of the endpoints.
I was wondering what would be a good way to implement this function using Backbone.js
You can use a "progress" file or DB entry which stores the state of the backend process. Have your backend process periodically update this file. For example, write this to the file:
{"status": "Generating metadata", "time": "3 mins left"}
After the user submits the files have the frontend start pinging a backend progress function using a simple ajax call and setTimeout. the progress function will simply open this file, grab the JSON-formatted status info, and then update the frontend progress bar.
You'll probably want the ajax call to be attached to your model(s). Have your frontend view watch for changes to the status and update accordingly (e.g. a progress bar).
Long Polling request:
Polling request for updating Backbone Models/Views
Basically when you upload a File you will assign a "FileModel" to every given file. The FileModel will start a long polling request every N seconds, until get the status "complete".
Related
I have a webapp created with Node.js/Express.js/Pug that runs a bash script(mostly an Nmap scan) and displays the results. I'd like to implement some sort of page in between the start and the results to signify the system is working on the task.
I tried to just add another res.render(...) at the beginning of the route that starts the scan, but I ran into the problem that HTTP cannot send headers twice. Effectively, I can't send two http responses for one request; please let me know if I'm wrong here.
I'm still not very familiar with this stuff; I'm working with a group and this job fell to me, any help is appreciated.
Typically the route handler would:
trigger the long running script asynchronously
return an "in progress" page
Then the "in progress" page would ask the server if it was done yet via:
Websocket
Ajax polling
Meta refresh polling
You'd need to have the callback to the original asynchronous process keep track of where the response should go to (possibly using a GUID that would be passed to it and also returned as data in the "in progress" page).
I have a subroutine in my Controller
<HttpPost>
Sub Index(Id, varLotsOfData)
'Point B.
'By the time it gets here - all the data has been accepted by server.
What I would like to do it capture the Id of the inbound POST and mark, for example, a database record to say "Id xx is receiving data"
The POST receive can take a long time as there is lots of data.
When execution gets to point B I can mark the record "All data received".
Where can I place this type of "pre-POST completed" code?
I should add - we are receiving the POST data from clients that we do not control - that is, it is most likely a client's server sending the data - not a webbrowser client that we have served up from our webserver.
UPDATE: This is looking more complex than I had imagined.
I'm thinking that a possible solution would be to inspect the worker processes in IIS programatically. Via the IIS Manager you can do this for example - How to use IIS Manager to get Worker Processes (w3wp.exe) details information ?
From your description, you want to display on the client page that the method is executing and you can show also a loading gif, and when the execution completed, you will show a message to the user that the execution is completed.
The answer is simply: use SignalR
here you can find some references
Getting started with signalR 1.x and Mvc4
Creating your first SignalR hub MVC project
Hope this will help you
If I understand your goal correctly, it sounds like HttpRequest.GetBufferlessInputStream might be worth a look. It allows you to begin acting on incoming post data immediately and in "pieces" rather than waiting until the entire post has been received.
An excerpt from Microsoft's documentation:
...provides an alternative to using the InputStream propertywhich waits until the whole request has been received. In contrast, the GetBufferlessInputStream method returns the Stream object immediately. You can use the method to begin processing the entity body before the complete contents of the body have been received and asynchronously read the request entity in chunks. This method can be useful if the request is uploading a large file and you want to begin accessing the file contents before the upload is finished.
So you could grab the beginning of the post, and provided your client-facing page sends the ID towards the beginning of its transmission, you may be able to pull that out. Of course, this would be reading raw byte data which would need to be decoded so you could grab the inbound post's ID. There's also a buffered one that will allow the stream to be read in pieces but will also build a complete request object for processing once it has been completely received.
Create a custom action filter,
Action Filters for executing filtering logic either before or after an action method is called. Action Filters are custom attributes that provide declarative means to add pre-action and post-action behavior to the controller's action methods.
Specifically you'll want to look at the
OnActionExecuted – This method is called after a controller action is executed.
Here are a couple of links:
http://www.infragistics.com/community/blogs/dhananjay_kumar/archive/2016/03/04/how-to-create-a-custom-action-filter-in-asp-net-mvc.aspx
http://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/understanding-action-filters-vb
Here is a lab, but I think it's C#
http://www.asp.net/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-custom-action-filters
Just want to understand the usage of busy indicator does it alternate to timeout/putting wait etc.
for example have following line of code in mainfunct()
1. busy.show();
2. callcustom(); --asynch function without callback this is calling xmlhttpRequest etc.
3. busy.hide();
4. callanothercustom(); -- asynch function without callback
now question is
does line 4 will be executed only when busy.hide() completes and
line 3 only when line 2 is completed while without busy all (2,4)
will be called inside mainfunct() without waiting line 2 to
complete...
when busy.hide() is being called is there any timer setup which
holds until line 2 finishes and then hide and call line 4.
A busyIndicator's show and hide functions only control when to display the indicator and when to hide the indicator. They have no effect what-so-ever on anything else going on in your code.
In other words your code is basically:
callcustom()
callanothercustom()
In your customcode you can still make sure that callanothercustom will be called only when it's finished by adding your own callback... I assume this is AJAX inside of it, so: jQuery ajax success callback function definition
function callcustom() {
$.ajax({
url : 'example.com',
type: 'GET',
success : callanothercustom
})
}
And then in callanothercustom you can busy.hide...
Or any other combination of business logic - it really depends on what's going on in your code.
In my opinion, the only main use case for using a busy indicator is a Long running synchronous task that's blocking UI. Let's say greater than 2 seconds long. Hopefully, these are few are far between.
If you have asynch tasks, then the UI is not blocked and user can interact. If you are relying on the results for next steps as you imply above, then you must have a callback/promise to trigger the next steps. If you want the user to be blocked until the async task is complete, then treat it as a synch task and show the Busy.
Be aware, use of Busy Indicator is now seen mostly as an anti-pattern. Its basically yelling at your user "See how slow this app is!". Sometimes you cannot avoid dead time in your app, such as fetching a large block of data to generate a view, but there are many ways to mitigate this. An example may be to -- get something on the view as fast as possible (< 1 sec), and then backfill with larger data. Just always ask yourself WHY you need this Busy, and can I work out a way to avoid it, but not leave the user wondering what the app is doing.
My problem is:
HTTP request gets cancelled after 2 minutes but server side processing still continues.
I have large data processing and my database contains huge data.So i am using a normal form submit method for a processing screen and when i checked the browser console the request status becomes cancelled.But on the server the process is continuing after this request cancelling.Also when the request is cancelled a file wil be downloaded automatically which cannot be opened,also the file extension is not there.I have made the maximum execution time limit to unlimited using
set_time_limit(0);
,but it didnt changed the situation.In my code i have writted some code to write contents into a file.So after the request gets cancelled the file writing operation continues.I am trying to resolve this error but didnt find any solution.Please help me.
I am using apache server.
Screenshots
Process i am doing:
1.Selecting large number of data from a table which contains large number of data.
2.Checks whether each record matches certian conditions
3.Matching records are written into a file and that file is report generation
4.Allowing the user to download the file after the process completion.
I have heared that if the client did'nt recive any response after a particular time then it will cancel the request to the server.Is this the issue with me.If so how can i resolve it.?
Php doesn't find out the request is cancelled until it tries to send data to client. You should be able to resolve this by doing this at regular intervals:
echo ' '; flush();
This will end your script if ignore_user_abort is false.
My application in Django can create some very big SQL queries. I currently use a HttpRequest object, for the data I need, then a HttpResponse, to return what I want to show the User.
Obviously, I can let the User wait for a minute whilst these many sets of queries are being executed and extracted from the database, then return this monolothic HTML page.
Ideally, I'd like to update the page when I want, something like:
For i,e in enumerate(example):
Table.objects.filter(someObjectForFilter[i]).
#Return the object to the page.
#Then Loop again, 'updating' the response after each iteration.
Is this possible?
I discovered recently that an HttpResponse can be a generator:
def myview(request, params):
return HttpResponse(mygenerator(params))
def mygenerator(params):
for i,e in enumerate(params):
yield '<li>%s</li>' % Table.objects.filter(someObjectForFilter[i])
This will progressively return the results of mygenerator to the page, wrapped in an HTML <li> for display.
Your approach is a bit flawed. You have a few different options.
The first is probably the easiest - use AJAX and HTTPRequest. Have a series of these, each of which results in a single Table.objects.filter(someObjectForFilter[i]).. As each one finishes, the script completes and returns the results to the client. The client updates the UI and initiates the next query via another AJAX call.
Another method is to use a batch system. This is a bit heftier, but probably a better design if you're going for real "heavy lifting" in the database. You'll need to have a batch daemon running (a cron probe works just fine for this) scanning for incoming tasks. The user wants to perform something, so their request submits this task (it could simply be a row in a database with their paramters). The daemon grabs it, processes it completely offline - perhaps even by a different machine - and updates the task row when it's complete with the results. The client can then refresh periodically to check the status of that row, via traditional or AJAX methods.