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

Client.postMessage should return a Promise #677

Closed
johnmellor opened this issue Apr 10, 2015 · 11 comments
Closed

Client.postMessage should return a Promise #677

johnmellor opened this issue Apr 10, 2015 · 11 comments
Milestone

Comments

@johnmellor
Copy link

Client.postMessage can fail for various reasons, for example:

  • user or JS closed the tab
  • user or JS navigated* the tab to a non-same-origin URL
  • tab is still open, but browser evicted it from RAM

As suggested in #609 (comment) and #626 (comment), it would be useful if Client.postMessage returned a Promise that would be resolved once the message event has been fired on the client, or rejected if the client ceases to exist before the message event can be fired.

Example use case from @jakearchibald:

After a push message, a SW may find a focused & visible client and post a message to it, but that fails because the tab has since been closed. Developers should be able to catch that case and show a notification instead.

@annevk is concerned that this would expose GC, but it remains unclear why it's bad for JS to be able to tell which tabs are still open/alive - especially since this can already be achieved by polling. So far, these concerns don't seem to outweigh the utility of the use case above.

*: some browsers have a back-forward cache (a.k.a. fastback) feature like https://wiki.mozilla.org/DocShell:Fastback - in such cases navigation doesn't destroy a client, it merely pauses all timers. In such cases where timers are paused, I guess the promise should neither resolve nor reject, but instead wait until the timers are resumed (e.g. because the user returns to the cached page) or the client ceases to exist (e.g. because the client is evicted from the back-forward cache).

@nikhilm
Copy link
Contributor

nikhilm commented Apr 10, 2015

*: some browsers have a back-forward cache (a.k.a. fastback) feature like https://wiki.mozilla.org/DocShell:Fastback - in such cases navigation doesn't destroy a client, it merely pauses all timers. In such cases where timers are paused, I guess the promise should neither resolve nor reject, but instead wait until the timers are resumed (e.g. because the user returns to the cached page) or the client ceases to exist (e.g. because the client is evicted from the back-forward cache).

As an implementer I'd rather that this just failed. We can't even guarantee that the SW itself will stay alive by the time the page is restored.

@jungkees
Copy link
Collaborator

Apologies to have closed #609 without this issue being addressed.

So the use case is clear, but I'm a bit unclear about how to spec this bit:

tab is still open, but browser evicted it from RAM

even after having gone through #626. Some kind of "Note" will do for it?

@mfalken
Copy link
Member

mfalken commented Apr 21, 2015

Tracked in crbug.com/461416 but needs spec decision.

@jakearchibald
Copy link
Contributor

@jungkees if we expose evicted clients, I think they should be another type that doesn't have postMessage #626 (comment)

@jakearchibald
Copy link
Contributor

@annevk would it be wrong to make this return a promise given it doesn't elsewhere on the platform?

@jakearchibald jakearchibald added this to the Version 1 milestone Oct 28, 2015
@jakearchibald
Copy link
Contributor

Setting this as v1, as we can't go from a method that throws to one that returns a promise, so this needs deciding soon.

@annevk
Copy link
Member

annevk commented Nov 1, 2015

How can you figure things out by polling without the other side cooperating?

@hsablonniere
Copy link

I used postMessage in many ways for various multi-screen projects and experimentations : window.open, SharedWorker, BroadcastChannel, manual MessageChannel ports... It always felt like UDP to me and when I needed some kind of "TCP ACK", I had to build it myself.

I would prefer the postMessage API to behave the same as the rest of the platform. I see three possibilities :

  1. Make SW postMessage return a promise and update other specs (there's a lot of them) to behave the same way.
  2. Use a different function name in SW and this one would return a promise. IIRC, the presentation API renamed postMessage to something more like the WebRTC API.
  3. Just do nothing. Stay low level and let devs build stuffs like this.

@jakearchibald
Copy link
Contributor

F2F: it isn't worth changing this one instance of postMessage. You can do this pretty easy in library land.

@nolanlawson
Copy link
Member

Yo: https://github.com/nolanlawson/promise-worker 😃

Not saying this solves every use case (e.g. it can't send ArrayBuffers or raw JSON), but I think it demonstrates this is indeed pretty easy to solve in userland.

@jakearchibald
Copy link
Contributor

Not dissimilar https://github.com/jakearchibald/svgomg/blob/master/src/js/page/worker-messenger.js

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

8 participants