I have a Grails app that downloads a file that's generated from a database query that takes about a minute. How can I implement a sort of hourglass (or something prettier) so the user knows the request is being processed ?
The corresponding link calls a controller method that does the processing and uses the response object.
I think you want to do something like a spinner notification while an operation is being processed.
you can check this out
Related
I have an application where a user can request something of another user. Using a model called Request it contains an order and the assigned user to which it applies.
What I would like to do is when the user receives a new request to notify them immediately, they should be able to accept or deny. Which is currently stored as a bool value in Request.accepted the default is nil.
This obviously requires back-end and front-end work. Have anybody done this or have experience with anything similar? Most ideal would be to display a bootstrap modal when a request appears, where they can accept or deny it.
It depends which version of rails you are using. More than one way is possible, also depends on the size of users and requests you are processing.
Add a after_save callback and call a mailers model
or add the request to a queue and run later a [1] ActiveJob
[1] http://edgeguides.rubyonrails.org/active_job_basics.html
Basically, what i need is:
When user press button "Parse" it sends request to the server (using ajax) and execute controller action with loop. It must be done asynchronous and user must get response how many percentage is finished (like loader...)
What is the best method of implementing this?
The most difficult task with what you're describing is updating the loader to show the right percentage. If you can do without, I suggest you do. If you really want a loader because the parsing takes a lot of time, I can see 3 options:
Use websockets to send the percentage to the user once it is updated. Rails will be including Actioncable in Rails 5 to easily do this but you can try it out now: https://github.com/rails/actioncable
Use a third party service such as https://pusher.com/ to easily implement this without managing your own websocket server
Or save the percentage in Redis and create an endpoint that you'll ping every second or so to update the loader. It feels a bit hacked but sometimes it's enough.
Good luck!
I have an application that makes API requests to salesforce using restforce.
Specifically the application finds a contact object, returns IDs for all related objects and then pulls the full record for every related object based on their ID.
This takes a long time for two reasons:
There are a lot of request to an external API, usually takes a few fractions of a second for each to reply and for some there can be +500 individual requests.
There is often a large amount of data being pulled back via each request.
All requests currently fall within the salesforce rest API limits but I'm getting timeout errors from my development server as it can take 5+ minutes for some of these requests to process.
Rails 4.2 - How best to handle this?
My question is how do I best get rails to handle this?
I can fire the API requests either from the controller (which definitely violates the skinny controllers) or from the view (via helper methods, which seems like a dodgy hack).
Ideally I'd like to get it running in a background job, but i'm unsure if I can just include all the authentication and other methods in a job in the same way I can include helper methods?
Even if I could get it to work in a background job, I'm unsure what best practice might be for the user experience. Ideally I'd like to route them to a page telling them to "hang tight, go get a coffee" with a progress bar, and then auto route them to the final page once the request is complete...
But I'm unsure how to generate a temporary display until a job has been completed?
Could anyone recommend any gems or strategies that might help me digest this problem?
You should definitely use a background job for this.
Give a database object to the job, which it will update to signal that is has finished, and maybe from time to time to indicate progress.
On the user side, simply tell them that the background job is working, with eventually a progress indicator, and display the result once the database object giving to the job tells you it's ready.
I have a controller with three actions: index, iframe, and result. The way it works is the user visits the index action via GET request. This renders a view that includes a form. The form is simply a button that POSTs to result. My result action simply renders a page that includes a jQuery progress bar and an iframe, the content of which is the iframe action. The iframe action does some long-running processing and eventually returns the result to the result view. (The whole reason I need to do this in an iframe is so the result action returns quickly with a progress bar so the user doesn't think the application crashed.)
Previously the form consisted solely of a button that POSTed to result. In this scenario, the iframe action downloads a ~100MB file from a static URL and does some processing on it, then updates the parent page (result) with the result of the processing.
Now I need to provide the option of uploading a file to process instead of always using the static URL to download from. Basically, if a user provides a file, use that file; otherwise, use the static URL. I have modified my form to accept a file upload and this part is working fine. My problem is how to pass this uploaded file, which is ~100MB, from result to iframe. It is far too big to put in the session. The uploaded file does not need to be saved between runs.
In addition to the implementation detail, you should update your question with a bit more of the background of the problem - what kind of files are you uploading? What kind of processing do you do? What is the purpose of the system from an end-users perspective? It'll help people understand the problem you're trying to solve.
I'm making some assumptions about the purpose of your system here, but here's what I'd do:
I'd upload files and store them in the file system, and also create a new record in a database table indicating the location of the file within the system, and wether the file is "processed" or not. You can use the Carrier Wave gem for this: https://github.com/carrierwaveuploader/carrierwave
I'd then use some kind of background job tool to do the actual processing. So, when a file is uploaded, you add it to the 'queue of stuff to be processed', then return a message to the user saying "the job has been added to the queue for processing and will be finished soon". The ID of the row you saved in the database table can serve as the identifier for which file needs to be processed. Once it's processed, you update the "processed" column in the database to be true. There are several gems to choose from when it comes to background jobs - one popular one is SideKiq - http://sidekiq.org/
At that point, it's basically up to you in terms of how smooth you want to make the process from your end user's perspective. A simplest case would be:
When you return the message "the job has been added to the queue for processing and will be finished soon," you could also say "It should be complete within a few mintues. Refresh this page to see if your job is complete". Each refresh, if the processing is complete, you'd let them know.
A more sophisticated way would be: Once the "job has been added to the queue" page is shown, you could display a timer counting how long it's been, and use a javascript timer to regularly make AJAX requests to the server every couple of seconds to check if the job has been completed. Once the job has been completed, update the page to indicate that, using AJAX.
I want to have a form saved every 10 seconds or so, or maybe onchange. I'm using rails and have tried observe_fields and periodic_remote_call, but I don't know how to send a full full parameter with periodic and how to send a full form with observer.
There's a nice post here: http://www.elevatedcode.com/articles/2006/12/20/using-observe_form/
observe_form seems to be your solution. Read the documentation for the parameters (so it does what you want, since it seems not very clear yet) and it will send updates upon changes or timed periods to your controller.
Also add an action method to the controller which processes the information send to it, by storing it somewhere.