Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only poll from one tab when multiple tabs are open #145

Open
PVince81 opened this issue Mar 6, 2018 · 8 comments
Open

Only poll from one tab when multiple tabs are open #145

PVince81 opened this issue Mar 6, 2018 · 8 comments

Comments

@PVince81
Copy link
Contributor

PVince81 commented Mar 6, 2018

If multiple browser tabs are open the polling code will run in each one of them.

Ideal would be to have a mechanism in place to only have one of the browser tabs do the polling and somehow notify the other ones that it already did so and also whether there were new notifications (store the number of notifications).

One idea would be to use localStorage. As soon as one browser tab initiates the call, it stores the current timestamp in localStorage.notifications.lastCallTime. Other tabs will check this value before initiating a request. If lastCallTime is older than 30 seconds + x (or whatever polling interval was configured), it will initiate the call again.

Optionally there could be another value to represent a lock (with timeout) that prevent other tabs to do a request. The problem with a lock is that tabs could get closed or the browser could get closed but the value still exists. So the timeout value would help with that.

Additionally a value localStorage.notifications.count would contain the result of the last query, telling other tabs what number to display on the bell icon. That number would get read by all tabs at the time where they would normally do the server query.

Not sure if it would be possible and accurate to have a counter for the number of open tabs that get decreased in window.onunload.

@jvillafanez

@PVince81
Copy link
Contributor Author

PVince81 commented Mar 6, 2018

Once we switch to web sockets, this would still remain a problem as every browser tab would open their own sockets. Maybe not as bad as polling though.

@jvillafanez
Copy link
Member

I have my doubts about this...

First I don't have a clear use case where multiple tabs over the same ownCloud server should be used. If the tabs points to different ownCloud servers, then it's valid to poll from several tabs (polling performance is another topic to be discussed)

Second, after a quick search about how we can communicate among tabs, I haven't seen a reliable method to do this properly:

  • Broadcast channel (https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API) can't be used because we're bound to race conditions happening among the tabs. In addition, some browser don't support it

  • Localstorage API can't be used neither. The specification doesn't provide access to lock mechanisms nor guarantee an exclusive access to the shared resource. (https://html.spec.whatwg.org/multipage/webstorage.html#dom-localstorage)

    The localStorage attribute provides access to shared state. This specification does not define the interaction with other browsing contexts in a multiprocess user agent, and authors are encouraged to assume that there is no locking mechanism.

    Race conditions might happen due to the lack of a shared locking mechanism.

@PVince81
Copy link
Contributor Author

PVince81 commented Mar 6, 2018

use case where multiple tabs over the same ownCloud server

Some people like to have their file manager open in multiple different folders. The same could happen with ownCloud pages. Also if you use multiple apps like calendar, contacts, you could also have them in different tabs. Remember, some people have 100+ tabs often as they tend to open what they want to view in new tabs.

@PVince81
Copy link
Contributor Author

PVince81 commented Mar 6, 2018

The specification doesn't provide access to lock mechanisms nor guarantee an exclusive access to the shared resource.

The lock mechanism can be implemented ourselves with semaphores (or use a library that does so), but under the assumption that primitives like integer and boolean can be updated atomically. If they didn't then browser would likely crash with weird side effects.

@DeepDiver1975
Copy link
Member

First I don't have a clear use case where multiple tabs over the same ownCloud server should be used. If the tabs points to different ownCloud servers, then it's valid to poll from several tabs (polling performance is another topic to be discussed)

I have always two pinned tabs open: one with the mail app and the other one with my calendar. In addition the files app will be opened in a additional tab as needed.

@DeepDiver1975
Copy link
Member

My initial guts feeling reaction to this: tabs should be treated isolated - can one tab even access data of the other tab? This should not be possible.

In case of chrome (and afaik also recent firefox) each tab is executed in it's own process to improve the isolation.

No idea if we want to walk this way ....

@PVince81
Copy link
Contributor Author

PVince81 commented Mar 6, 2018

It's not really about accessing data from other tabs but more about using localStorage as a shared location to store some minimal state. I wouldn't store the notifications there but only the information about whether there are new notifications or not and how many for updating the bell icon. If the user clicks on the bell icon we would again do a server call to retrieve the details.

@jvillafanez
Copy link
Member

There are mainly 2 "safe" mechanism to provide access to shared resources: using locks to get exclusive access to the shared resource, or using atomic operations to make sure the operation isn't interrupted. None of those are provided by any API in javascript.

I think we should consider race conditions as something that will happen, and make plans to minimize the effects.
It might be possible to pull it off, but we need careful planning for this. We also need to consider how easy / difficult will be to test this: we should make sure that only one notification is shown regardless of the scenario, not just the easiest one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants