Browser Tab/Window tracking pattern? - javascript

Is there an accepted pattern for tracking that a page is being loaded by the same tab/window?
There are certain processes (like stepped submission processes), which can greatly benefit from a ability to verify that the same tab is asking for execution.
For example, there are places where (between steps) we store intermediate data in memcache, but this can cause a problem without the ability to scope that data to this process, as opposed to if the user opens another tab/window on the same process.
This holds true for many actions/processes.
Some brainstorming has not come up with anything dependable.
Ideas anyone?

You could maintaining the state of a multi-step process using query parameters (if you use GET requests) or hidden fields (if you use POST requests) or both (if you POST-then-redirect, to allow the user to refresh her browser).
If you maintain state on the server (e.g. in a DB or memcached) you could just keep a "transaction key" in a query parameter or hidden field.
Be wary, though - in my experience, it's possible to design such a stateful multi-stage process fairly cleanly, but it may be tricky to implement and to maintain a non-surprising user experience. For example, what happens when you move back and forth between the stages? You could allow this explicitly, or the user could use the back button, but the process should still make sense.
EDIT:
As a concrete example:
User clicks "Start multi-step process", which does a POST to the server
Server then
initializes state for a process
gives it unique key "A"
keeps it in a temporary store (e.g. memcached)
redirects the user to "/process/A/step/1"
The next step for the process would be "/process/A/step/2"
User, in a different tab, clicks "Start multi-step process" again
Server does the same but
uses a unique key "B"
redirects to "/process/B/step/1"
The next step for this second process would be "/process/B/step/2"
The two processes now have independent server-side state

Related

Updating localStorage when there's new data from server?

After logging into an app (React.js), I am caching the member data in localStorage as a lot of my components are using it and request only needs to be done upon log-in, ideally.
However, a few properties in this member object may be changed in the backend manually so the frontend doesn't have a way to know whether the member object has changed at all. (Again, ideally, any change to the member object should go through some form submission that directly changes the DB, with which an update can be triggered for the localStorage, but this is not an option at this time.)
Example scenario: There's a generic form in the app to request for additional credits. Customer service will receive an email regarding the request. Credits would be manually updated for Customer A (in DB). If Customer A doesn't re-login (where the get request for member is done), localStorage will still show the old no. of credits.
If this is the situation, what's the best way to go about it?
Don't store member data in localStorage at all so as to keep the data fresh. Just call the endpoint whenever it's needed.
Use sessionStorage instead?
Trigger a refetch when the user refreshes the page / app (although user may not know that they need to do this to update the data).
Suggestions?
Calling the endpoint whenever its needed is ideal if the data is going to change based on things outside of the user's control.
Session Storage is just local storage that gets wiped when the browsing session ends, you'll still have the exact same issue
This doesn't really solve the problem, and it's typically a bad user experience to require the user to perform regular maintenance tasks in order to use your application to the best of its ability
I'd go with just getting the data fresh.
At a high level, you have two choices:
Poll (periodically call the back end to refresh the data)
Open a persistent connection (like a web socket) to the server, and have the server push updates to clients.
The latter option would require a lot of changes, and it changes the scalability of your app, so the former choice seems like the most reasonable option for you.
It's smart to keep using localStorage so you have an offline copy of the data and aren't blocking rendering during page load; you can have a background periodic refresh process that doesn't disrupt the user in the meantime. If your data is mirrored in something like redux or context, then your UI could seemlessly update if/when the data changes.
If you do not know when member has been updated, don't store it. You should query the back end every time you need member. That is the only way to keep the data sync with your database.

Make button enabled for only one user on webpage

I'm developing a website that is suppoused to control some devices that rotate when pushing one button. However, I only want one user at a time to be able to push the button.
That is, when a user enters the page, check if it is the "first" or only user that is there. In case he is, he can use the button freely. In case he isn't, the button appears as disabled.
What would be the best way to implement this? I'm using a classic design of html+js+php.
Thank you.
This is a design question, and still, you should have already tried something and post that something before asking here.
You should use a lock system:
create an endpoint with php, to call with Ajax that checks over a variable globally shared (better if on db) that acts like a semaphore, the first who arrive make it red and 'acquire the lock'.
If the lock is acquired, the client can do the action,
If the lock is not acquired, someone else took it already.
Do not forget to release the lock after the action.
You can use the same call to acquire the lock, do the action and release the lock. If the lock is not acquired the call return an error message and the user will know which is the issue.
P.S.
If you was thinking about a real time system, you may consider using websockets or just the system above with different calls for acquire the lock and do the action (and poll for the lock status).
To track a user on a website is not that difficult, but check if and when he/she leaves is the challenge.
If this is not time crucial you can do this with timeouts.
First, you need to be able to track the current user on your site (maybe with sqlite, textfile, mysql/mariadb) (maybe identified by IP) wich is updated a user loads the page.
After a timeout the tracking storage can be updated and the next or new one can hold the button.
If you need this realtime, you need a bit more to do. In this case I would use Websockets or NodeJS to keep connections to your page wich in fact you can use to keep track on active users and wich one should be able to keep the button.
Just keep it like a realtime online chat without texting. There you need to keep track of online users as well.
(Websockets or NodeJS are here only a example, there are alot technique to archive realtime "collaboration".)

How do I give users imidiate feedback in a CQRS web application

I have a CQRS application with eventual consistency between the event store and the read model. In it I have a list of items and under the list a "Create new" button. When a user successfully creates a new item he is directed back to the list but since the read model has not been updated yet (eventual consistency) the item is missing in the list.
I want to fake the entry in the list until the read model has been updated.
How do I best do that and how do I remove it when the new item is present in the actual list? I expect delays of about 60 seconds for the read model to catch up.
I do realize that there are simpler ways to achieve this behavior without CQRS but the rest of the application really benefits from CQRS.
If it matters the application is a c# mvc4 application. I've been thinking of solutions involving HTML5 Web Storage but want to know what the best practice is for solving this kind of problem.
In this situation, you can present the result in the UI with total confidence. There is no difference in presenting this information directly and reading it from the read model.
Your domain objects are up to date with the UI and that's what really matters here. Moreover, if you valid correctly your AR state in every operation and you keep track of the concurrency with the AR's version then you're safe and your model will be protected against invalid operations.
At the end, what are the probability of your UI going out of sync? This can happen if you there are many users modifying the information you're displaying at the same time. This can be avoided by creating task based UI and following the rule 'one command/operation in the AR per request'.
The read model can be unsynced until the denormalizers do their job.
In the other hand, if the command will generate a conversation (long running operation) between a saga and AR's then you cannot do this and must warn the user about it.
It doesn't matter that's a asp.net mvc app. The only solution I see, besides just telling the user to wait a bit, is to have another but this time synchronous event handler that generate the same model (of course the actual model generation should be encapsulated in a service) and sends it to a memory cache.
Being everything in memory makes it very fast and being synchronous means it's automatically executed before the request ends. I'm assuming the command is executed syncronously too.
Then in your query repository you also consider results from cache, removing it if that result is already returned by the db.
Personally, for things that I know I want to be available to the user and where the read model generation is trivial, I would use only synchronous event handlers. The user doesn't mind waiting a few seconds when submitting something and if updating a read model takes a few seconds, you know you have a backend problem.
I see that eventual consistency is applicable to application only if application environment has multiple front-end servers hosting application and all these servers has own copy of read model. All servers uses same copy of event store.
When something is changed to event store, read model that is used to read result to user must be updated in sync with event store. Rest of servers and read models managed by them can be updated using eventual consistency.
This way result to user (list of items) can be read from local read model copy because it is already updated in sync. No need for special complex fake updates/rollbacks.
Only case when user can see incomplete list is that user hits F5 to refresh list after update change and load balancing directs user request to front-end server which read model is not yet updated (60 second delay), but this can be avoided so that load balancing does not change users server in middle of session.
So, if application has only one front-end server, eventual consistency is not very usable or it does not give any benefits without some special fake updates/rollbacks with read model...

How to detect moving to different domain page?

I have a ruby on rails app and I want to detect user moving to different domain page
while in model creating wizard.
I stored model-data to DB at first-step of wizard and redirect_to second-step of wizard.
And I want to destroy it if user moving to different domain page while in second-step.
I already find a way to hook onbeforeload event to show warning to user.
But I want to warn it only if user moving to different domain page but not to third-step.
And if user want to moving different domain page then I want to destroy stored data.
What is a best solution to do this? Is there any way to detect where user want to go?
EDIT:
In second-step I want to create model from user upload file(ajax upload with jQuery File Uploader) and associate with first-step's model. So if I can get which id will assign to first-step's model then I can easily associate with it. This is why I want to store data in first-step.
And I don't want to expire unfineshed model until user explicitly leaving wizard.
Then can I detect whether user still opening wizard and just stopping very long time or
already leaving wizard page?
(I want to build app just like a desktop application so user can have unsaved file until explicity leaving wizard on multiple browser window)
That's is not possible. Once your page is unloaded you cannot do anything else. If the user is loading another domain page then that domain has control over the page, not you.
What you should do is store the data of the wizard pages not in db but on session state or even in a cookie, this is the good practice. Then, when user reach the final step of the wizard you read the data from cookie/session and write to db at once.
You cannot determine the user's intended destination within the onbeforeunload event, or any other. You also can't stop a user's request to load another page and instead redirect them to some destroy action before sending them off on their way.
If you are content with storing data into the database on each step as the user progresses through your wizard, you can look into setting up a cron job to run a rake task you create which can go through and delete incomplete wizards that are older than a certain age.
The cron (or equivalent) actually is something I'd consider doing even if you could detect a user leaving your site.

How to create a guided tutorial for a web-page using JavaScript?

Certain websites (notably Facebook games) have a step by step tutorial for new users, where JavaScript is used to create a pop-up which tells the user where to click next and what is happening.
How does one create such a system? What sort of architecture is required?
I suppose that a script is loaded if a flag is a tutorial flag is set, and that stored within the user's state there's a 'pointer' which indicate which step in the tutorial the user is at. That script would echo out the relevant JavaScript for pop-ups and highlight and whatever.
The question, I guess, is how does one detects when the user has performed the required action and that the tutorial is to proceed to the next step?
On Edit : The 'action required to proceed to the next step' could involve the user clicking on a link itself, or submitting a value through a form. So the state must be able to persists and the script must be able to detect interactions on different UI elements throughout the page.
I think solution will depend on which technologies you are using.
Simply - you can store user's tutorial progress in a cookie file, and on each his action (e.g. button click) call javaScript handler, which will update it's status.
You can prototype your tutorial as Finite State Machine. I think this tutorial data presentation will be very helpful.

Categories

Resources