In my Rails controller method, which is executed when the user submits a form, there is a Ruby code sleep(60), telling it to wait for a minute. One user submits the form, and while the execution is "sleeping", another user submits the form. Will the second user have to wait for the first user to finish, or will the execution of the controller start for the second user?
Both users will wait for 60 seconds only, they will not depend on each other.
As request will be processed separately for each other.
Hence no dependency
Related
What am trying to achieve is:
1. User pressess button and starts time-limited form.
2. Timer starts.
3. After X time when timer reaches 0 and user did not finish the form, rails create a record in database and do some session cleaning actions (Model.create and session.delete).
This timer will work like safety measure if user starts the form and then becomes unavailable (closes web brower or shuts PC).
Could you point to me to right direction? Where I should start? What language/framework should I use to do that?
You can use timestamps to record when something happened. Rails already has a great example of this in the updated_at and created_at fields.
You can re-use this concept to store when the user first started filling out the form, perhaps on the resource's new route, which usually coincides with the opening of the form.
As for performing the cleanup, you have two options that would could even both work together, depending on the situation:
If the cleanup isn't security-sensitive, you could have a timer kick off on the front-end and then send an AJAX request to the back-end when it expires.
If the cleanup isn't time-sensitive, you could run a task every few minutes or so, which performs the cleanup on any forms that haven't been cleaned up yet. It would look at the timestamps to determine this.
Aside from those suggestions, we'd have to know more about your use cases to answer more questions.
Is the cleanup time-sensitive?
Is the cleanup security-sensitive?
There are more options - you could run the task more granularly or more securely.
Tight timing
One option if your timing is very tight (down to seconds) is to implement both options above, and in addition the following functionality:
Use ActionCable to keep a web socket open with the user. Periodically have them ping the server to check their status.
In a before_filter, probably in ApplicationController, check first if they have permission to continue the action, i.e. the timestamp hasn't expired yet. If the timestamp has expired, and the cleanup hasn't been performed yet, then perform it now.
Limitations of this approach:
If the user closes the website entirely, the cleanup is not going to happen until the next cleanup task happens.
There are vulnerabilities on the front-end. The user can disable the front-end checks, and then avoid submitting the form, which will delay the cleanup in the same way as #1.
I have long running data processing on one page. It takes 3 minutes - that is an operation done by the admin and it is not executed very often.
What will happen if the user closes the page? I suppose if that user have more tabs or pages opened to the same site, the execution will continue otherwise will stop. Is that correct thinking?
When an ASP.NET page runs, the page goes through a life cycle in which it performs a series of processing steps. These include initialization, instantiating controls, restoring and maintaining state, running event handler code, and rendering.
All your code will be running no matter if the client is there or not to receive it . as #DLeh mentioned in his comment The server doesn't know and doesnt' care if the browser has closed the page.
check this out for more info MS Link
I have a locking challenge in my application. There is an invoice which gets created automatically when a timesheet is approved. The invoice needs to be adapted manually by an employee (adding VAT code, contact data, etc), so he clicks the adapt button. At that moment the timesheet gets the status locked so no changes can be made anymore to the timesheet.
This all works fine, except for one edge case: the employee clicks the adapt button but then doesn't do anything to the invoice. E.g. it goes to another screen, forgets about the invoice, etc. In that case the timesheet stays in locked state forever, while it should be unlocked.
What can I do to solve this? My current idea is to create a rake task which checks timesheets in locked state at a certain interval and removes the locked state when there is more than an hour gone between the current time and the timesheet updated_at time.
But maybe there is another strategy that can handle this case much better?
You can use the approach of gmail eg(when you leave the page before finishing your email he asks if you are really sure you want to leave this page if yes he discards the message)
in your case you should do the same and send an ajax request to unlock the record
In all cases you will need to do the rake task just to handle cases shut as power switch off or browser crashing. but it would give better convenience to avoid locking a record for a whole hour except in very special cases such these
The current strategy you're using is a pessimistic one, I'd recommend using an optimistic strategy:
http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html
The result is if someone opens the page, goes to lunch and in the meantime another user updates the record, then when the user gets back from lunch and submits the form an exception will occur.
The next question will be how do you handle the exception? Tell the user this has already been dealt with? Show the user the conflicts so they can resolve them?
I am trying to figure out a strategy for triggering a method to run every 30 minutes if a user is logged in to my site.
I currently have a method called signed_id? which checks if the user is signed in, and I am currently using the delayed_job gem to handle some other background processes in my application.
I've heard about the whenever and cron gems, but I'm not sure what would be best for my particular need. Is there something that works well with delayed_job ?
Well, you could keep a database record for each user of the timestamp that the method was last triggered (the first time would just be whenever they logged in), and have a cron that runs every minute.
You would keep a server-side record of when the client first logged in, and keep pinging (maybe with ajax) to make sure the user is still logged in. You would make Javascript execute an action (that goes to the server to execute your method) every 30 minutes, of course being calculated based on the server-side record of when you first logged in. This count would reset every 30 minutes as well, continuing the cycle.
I hope this helps.
Yes with cron it is more flexible and easy to use
cron on ruby
Suppose I have a Rails controller method, which is executed when the user submits a form. Now, the user submits the form, and while the method is running (and hasn't rendered the next page to the user), the user hits "Refresh". What is going to happen? Will the method stop running and restart, or will there be another thread to run the method once more?
I had to find the answer out for this myself, here is what I found (using Network tab on chrome inspector)
The browser sends the following requests:
GET /profile/123/edit (user brings up edit form)
PUT /profile/123 (user submits form)
The users hits refresh, which causes:
GET /profile/123/edit
In other words, it doesn't re-submit the form, it re-brings up the edit form.
Now... if instead of hitting refresh they hit submit a second time, that will send a second
PUT /profile/123
which will call your controller method a second time.
If that is a problem, you may need to add some logic to ignore or otherwise handle subsequent submits (simple state machine?). Remember the days when e-commerce sites had a message like "Do not hit submit twice" after you bought something... they didn't have that logic :)