Closed wilsonpage closed 9 years ago
So just for the records, I'll dump here what I said on IRC:
Manager
feels like an additional library that should be built on top of the core library if consumer wants advanced (memory-)management; For that purpose core lib should provide good extension points if not already.var client = threads.client('my-service', self);
when we know that service defined in the same context (window, worker) without relying on BroadcastChannelAPI
? Not sure how to deal with it better, maybe internal service registry? Potential use cases I can imagine is when we define two separate services hosted in window/ServiceWorker that need super-fast communication channel in between. Although it's more like a temporary exception, but still we have such case currently in Messages when service and client are defined in the same window. Or maybe it's just a very bad idea and such edge cases should never happen?Bringing in @steveck-chung who's also actively working with threads/bridge at the moment.
I spoke with Vivien about this topic. His reasons for wanting to keep the Manger is because he wants to abstract the Service location from the code using the Client.
Sometimes Services may live in threads under completely different origins, in which case we would be interfacing with a something like navigator.connect()
instead of Worker
. If this complexity is kept inside the Manager, then we leave the options for type of endpoint open.
I spoke with Vivien about this topic. His reasons for wanting to keep the Manger is because he wants to abstract the Service location from the code using the Client.
Yeah, I'm not opposed to Manager per se either. I just think that Manager is a separate layer that should live in a separate lib: while threads.js provides bare, but powerful communication between different contexts (that is why we still call it a Bridge in Messages app :) ), Manager lib/plugin could provide smart way of managing those service origins.
I'm not sure about architectural requirements for the threads.js and can't see full picture, but I thought that potentially we can have more than one Manager, depending on environment/platform/requirement so that developer can write its own Manager if needed something smarter/dumber comparing to our default one (based on small/easy/high-performant threads/bridge.js).
Or maybe I'm just too skeptical about idea to have one-for-all magic lib, IMO it sounds good, handy and performmant on paper until we use it in real world scenario or in slightly different conditions :) We still can try!
Threads.js is becoming bloated, this is largely to do with the 'magic' we support under the hood, including:
This issue aims to discuss whether we should kill the
Manager
component, simplify the library and pass a little more responsibility over to the library user.Right now the
Manager
is the middleman betweenClient
andService
. In order to establish a connection we must go through the following steps:Client
to theManager
Manager
must create the thread (eg.new Worker('foo.js')
)Manager
waits for theService
to become 'ready'.Manager
forwards the connect request.Service
accepts the connection.Manager
receives confirmation of the connectionManager
responds to theClient
to tell it it's connected.During critical path of app startup, every millisecond counts. All this message passing is slow when the main thread is busy doing stuff like script parse, network requests, layout/paint, etc.
Deciding where the manager should live
It's tricky to know where the manager should live. Right now it has to live in the thread that persists for the lifetime of your app. With the 'content wrapper' that would have been the index.html. Now that the content wrapper is dying, it could be a dedicated client spawned via new ServiceWorker
.openWindow()
API. But that could take time to instantiate during app startup, and could severely punish our critical path.If we kill
Manager
this problem goes away.When we do have a reference
A lot of the time
Client
s have a direct reference to a thread. In these cases we can greatly optimize the connection flow by bypassing theManager
altogether.None of these use-cases depend on
BroadcastChannel
, which is good, as right now it's only in Gecko (bad for web).When we don't have reference
There will still be cases when a thread reference is out of reach from a
Client
. For example aClient
in a window wanting to connect to aService
in aWorker
that has been spawned from aServiceWorker
.We can still support this case. We can just omit the second argument, and let
BroadcastChannel
attempt to find theService
within a certain timeout period.What about contracts?
Contracts will have to be attached to the
Service
when it's created.When do threads get terminated?
If the user is responsible for creating threads, they should probably be responsible for killing them. Alternatively we could
.terminate()
orport.close()
when the user callsclient.disconnect()
and automatically call this onunload
.What about dynamic thread architecture (issue #12)?
By removing the
Manager
we remove the ability to dictate the thread architecture behind the scenes. IMO it would be too opinionated to go down this path, and add even more complex logic to an already large library (20kb minified). IMO it is the job of the browser engine to make optimizations based on devices capabilities, not the app's (more discussion in issue #12).Summary
Client
it should probably be aSharedWorker
. This means that we won't encounter issue #7, as we pass the responsibility over to the browser to decide when to terminate the worker.Client
you should useWorker
.BroadcastChannel
in most cases to improve cross-browser support and use fasterwindow/worker.postMessage()
.