[whatwg] Combining the DedicatedWorker and SharedWorker interfaces

2008/11/13 Jonas Sicking <jonas at sicking.cc>:
> So at this point the main problem with making any changes is that we
> are very close to shipping Firefox 3.1. I.e. it is extremely hard to
> make changes. It is very unfortunate that we have ended up in this
> situation again. We were in a very similar to the window.postMessage
> API where we had to scramble last minute to make changes, the result
> that time was that security issues in the API slipped by since those
> changes happened after we had done our security review of the spec.
> A few months ago representatives from google, apple, and mozilla met
> to try to agree to an API. We came up with a few guidelines, such as
> that it was ok to have a separate API for shared and dedicated workers
> as well as others that I don't specifically remember. At the end of
> the meeting we had a rough sketch of an API. A few days after that
> Hixie published a proposal. At mozilla we were largely fine with the
> proposal modulo some details that we commented on fairly quickly and
> then proceeded to implement.
> Now, months later, both google and apple is asking for some pretty
> significant changes, including reverting things like separate APIs for
> shared and dedicated workers. It is very close to release for us and
> we are already in a very frozen state, so making changes at this point
> is somewhere between risky and impossible.

HIxie's draft after that meeting was August 20
and my reply on this issue was Sep 12
Not stellar turnaround, but not months either. In any case, I can
definitely appreciate the timing is poor for Mozilla and apologize for

> If we really want to make changes to the spec, we better make them
> really fast, ideally within a day or two. And depending on the
> complexity of the changes we might still be able to do them. The other
> alternative is of course removing workers from FF 3.1 and waiting
> until next release (judging by past releases, somewhere between a year
> or two from now). Finally, we can simply stick with the current API,
> none of the complains about the current syntax seems to have been very
> catastrophic, such as "doesn't satisfy use cases", "hard to
> understand", "easy to have hard-to-discover bugs", etc. They mostly
> seem to be syntactic and the case of the matter is as always that
> there is no perfect syntax as the problem is over constrained.

This is true, the worst I can think of happening as a result of the
API Mozilla is planning no shipping would be "frustrating for
developers" or "frustrating for implementors" as more feature are
added that don't fit well.

> I see lots of ideas floating around but many of them are severly
> lacking in detail so it's hard to comment on. Things like 'rename
> startConversation to connect' is very ambiguous as has shown by recent
> discussions. So what follows is an effort to try to focus in on some
> discussed changes more concretely:

Thanks for restating the various proposals so well...

> The main two things that people seem to dislike in the current are
> 1. The many communication mechanisms.
> 2. Different APIs for shared and dedicated workers.
> I've said before that I don't really think 1 is true. There is
> currently one communication mechanism (postMessage/onmessage) and one
> connection mechanism (onconnect). There is also one convenience
> function on top of the communication mechanism (startConversaion), but
> is a stretch to call it a separate communication mechanism. The
> communication mechanism (postMessage/onmessage) does come in two
> flavors though as you for shared workers and dedicated workers call
> the functions on different objects.

Ok, maybe 'mechanism' was not the right word, but there are still
three separate ways to use the external API to workers (not counting
passing a port as an argument). I think this is undesirable.

Here are my preference on changes, in descending order:

> * Add a connect() method to Worker and/or SharedWorker
> There has been lots of talk about this, but I'm still confused as to
> what the exact proposals are due to lack of details. But here is my
> interpretation
> Details:
>  - Make instantiating a SharedWorker *not* fire a 'connect' event automatically.
>  - Remove the .port property from SharedWorker
>  - Remove the postMessage/onmessage functions from Worker and
> DedicatedWorkerGlobalScope
>  - Add a onconnect property on WorkerGlobalScope
>  - Add a connect() method on AbstractWorker. The function fires a
> 'connect' even on the WorkerGlobalScope, the event has a .port
> property which is a MessagePort. This MessagePort is entangled with
> another MessagePort which is the value from the connect() function.
> Comments:
> Compared to just doing the other above proposals I think this adds
> needless complexion for value that I don't quite see. If you want to
> have several 'conversations', I.e. several separate MessagePorts, with
> a dedicated worker you can use postMessage and |new MessageChannel|
> (or the startConversation shorthand) to accomplish that. If you want
> several conversations with a dedicated worker you can do the same
> thing, or even call |new SharedWorker| multiple times.

I think this is the best API because it offers the most functionality
with the smallest area. I also like that the API for dedicated and
shared workers is identical because it means that one you learn to use
dedicated workers, you already know how to use shared workers.

> * Remove startConversation
> Details:
> Simply remove the startConversaion function on all interfaces where it
> is defined. Since it doesn't define any new events no other changes
> are needed.
> Comments:
> There seemed to be opinions before on that it should definitely be
> removed, however it sounds like that is less the case now. I don't
> really care about this one. startConversation is just a convenience
> function on top of postMessage anyway. If there still is any
> disagreement about its neccessity or the fact that it adds to that we
> have too many communication mechanisms i'd prefer we remove it for now
> and then discuss it once we've agreed on the rest of the API, or we
> can let it be for this version of the spec. Others have commented that
> startConversation is a red herring in these discussions, I agree.
>  (This would be no problem for us since we don't implement
> startConversation yet).

If we don't make the above change, I think that we should remove
startConversation(). It doesn't offer enough different functionality
over passing a |new MessageChannel().port2| to be worth the extra API

> * Make the external API for shared workers that of the current dedicated worker
> Details:
> Move the postMessage/onmessage functions from the SharedWorker.port
> object to the SharedWorker object. The SharedWorker would act as a
> MessagePort that is entangled with the port that is provided to the
> SharedWorkerGlobalScope through already specified 'connect' event that
> is fired when a SharedWorker is created.
> Comments:
> The result of this would be that on the outside shared workers and
> dedicated workers have exactly the same API to the outside world,
> except that dedicated workers have a terminate() function (formerly
> known as close(), changed in the latest version of the spec).
> I think this is a good idea all around and we should make this change.
> (This would be no problem for us since we don't implement shared
> workers yet).
> Hixie expressed some dislike about the fact that we'd end up with
> MessagePort entangled with something that isn't a MessagePort. This
> can result in uglyness if the MessagePort is passed out outside the
> SharedWorker, and then passed on anywhere. A page could create a setup
> where calling postMessage on a SharedWorker object actually resulted
> in onmessage being called inside another window rather than inside a
> worker global scope.
> I don't really think this is a big deal though, you have a very
> similar situation today where calling postMessage on a
> SharedWorker.port object can do exactly the same thing.

I don't have a strong opinion on this.

> * Make dedicated workers receive a 'connect' event when they are created
> Details:
> Make the internal communication API for a dedicated worker exactly
> that of what a shared worker is currently specced as. This means
>  - Once a dedicated worker is instantiated automatically fire a
> 'connect' event which contains a MessagePort object (accessible
> through event.port).
>  - Make the Worker object entangled with this MessagePort.
>  - Remove the postMessage/onmessage functions from DedicatedWorkerGlobalScope
> Comments:
> I don't feel super strongly about this. From a purely dedicated worker
> perspective this doesn't really add any value but rather just
> complexity. Everyone using dedicated workers will have to set up a
> dummy function that just listens for a 'connect' event and sets a
> global port variable. The upside is that combined with the above
> change it makes the API for dedicated and shared workers exactly the
> same.
> We are currently looking in to if this is doable without adding too
> much risk to FF3.1. The big concern here is more objects means more
> chances of leak bugs since we can't reuse the same leak prevention
> mechanisms as we do on the main thread since that one isn't
> threadsafe. Anyhow, it's an implementation detail, but it is a big
> part of why making even small at this stage is non-trivial.

I don't have a strong opinion on this.

- a

Received on Thursday, 13 November 2008 12:53:24 UTC