Bug 903441 (ServiceWorkers)

[meta] Implement Service Workers

NEW
Unassigned

Status

()

task
P2
normal
6 years ago
25 days ago

People

(Reporter: Ehsan, Unassigned)

Tracking

(Depends on 9 bugs, Blocks 1 bug, {dev-doc-needed, meta})

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [games:p1][platform-rel-Games], )

Attachments

(26 obsolete attachments)

No description provided.

Comment 1

6 years ago
Is there a spec somewhere? Or is it an internal thing?
Its an experimental API right now. Updated URL to relevant discussion, but everything else is hand-wavy.
OS: Mac OS X → All
Hardware: x86 → All
A cleaned up patch bent sent me that is required before applying the event page/service patch.
Posted patch Patch 2: Service (obsolete) — Splinter Review
This is a first pass of Services that doesn't do a lot, but might be useful to Ehsan to figure out Navigation Controller and also a good time to layout my thoughts about further implementation.

What this code does do right now:
Inherits SharedWorker, to expose a Service() constructor to DOM (we could call it EventPage I guess, depending on how it gets used). This starts a (shared )worker, with the addition of a `mIsService` flag. A service is *not* immediately killed when all referring windows are closed. In fact, right now its lifetime is completely isolated from referring windows (which is not how it should be!). When it's event loop Dispatch() receives no events for some time (right now 13 seconds for no real reason), it cancels the service.

The rest of the discussion is in dev.platform (will paste link here).
Attachment #789292 - Flags: feedback?(mounir)
Attachment #789292 - Flags: feedback?(jonas)
Attachment #789292 - Flags: feedback?(ehsan)
Comment on attachment 789292 [details] [diff] [review]
Patch 2: Service

Jonas and Ehsan's feedbacks should be enough.
Attachment #789292 - Flags: feedback?(mounir)
Comment on attachment 789292 [details] [diff] [review]
Patch 2: Service

Review of attachment 789292 [details] [diff] [review]:
-----------------------------------------------------------------

Feedback on the concept level issues given on the dev.webapi thread.

::: dom/workers/RuntimeService.cpp
@@ +2091,5 @@
> +    }
> +
> +    if (!windowArray->Contains(workerPrivate)) {
> +      windowArray->AppendElement(workerPrivate);
> +    }

Can this be refactored into a helper method?

::: dom/workers/RuntimeService.h
@@ +155,5 @@
>  
> +  nsresult
> +  CreateBackgroundService(JSContext* aCx, nsPIDOMWindow* aWindow,
> +                          const nsAString& aScriptURL, const nsAString& aName,
> +                          Service** aSharedWorker);

Nit: please prefer returning an already_AddRefed<Service> if possible.

::: dom/workers/Service.cpp
@@ +20,5 @@
> +} // anonymous namespace
> +
> +Service::Service(nsPIDOMWindow* aWindow,
> +                           WorkerPrivate* aWorkerPrivate)
> +: SharedWorker(aWindow, aWorkerPrivate)

Not sure if you're looking for whitespace nits quite yet.  ;-)

@@ +27,5 @@
> +}
> +
> +Service::~Service()
> +{
> +  AssertIsOnMainThread();

It's not immediately clear to me what guarantees this...

::: dom/workers/SharedWorker.h
@@ +47,5 @@
>    nsRefPtr<MessagePort> mMessagePort;
> +
> +  /**
> +   * Used to dispatch a Resume() event back to the SharedWorker itself.
> +   * XXXnsm I'm not sure why this has to be done using a Runnable.

Perhaps because we want to keep the object alive until the desired method is called on it?

@@ -80,5 @@
>  
>    virtual nsresult
>    PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
>  
> -private:

Nit: please make these protected.

::: dom/workers/Worker.cpp
@@ +105,5 @@
>  
>    static JSObject*
>    Construct(JSContext* aCx, WorkerPrivate* aParentObj,
>              const nsAString& aScriptURL, bool aIsChromeWorker,
> +            const nsAString& aSharedWorkerName, bool aIsService);

Nit: an enum would probably make the call sites more readable than a bool.

::: modules/libpref/src/init/all.js
@@ +89,5 @@
>  // Whether or not Shared Web Workers are enabled.
>  pref("dom.workers.sharedWorkers.enabled", true);
>  
> +// Whether or not Background Service Workers are enabled.
> +pref("dom.workers.service.enabled", true);

This should obviously default to false when you get to land this...
Attachment #789292 - Flags: feedback?(ehsan) → feedback+
Comment on attachment 789292 [details] [diff] [review]
Patch 2: Service

Review of attachment 789292 [details] [diff] [review]:
-----------------------------------------------------------------

Nikhil, sadly I won't have time to go over this very soon. Especially as I'm heading out for vacation for a week and then it's the B2G workweek. Feel free to poke me after that if you want my feedback on the code. But I'd prefer to just go over the API instead.
Attachment #789292 - Flags: feedback?(jonas) → feedback?
This is a much simplified patch over the earlier 'ugliness'. It:

* Does not present a DOM facing constructor or access to these workers.
* Does not require Shared Workers patches
* Almost entirely avoids modifying any existing worker code.
* Adds a single interface nsIServiceWorkerManager with a SendEvent() method that always creates a new Worker and sends the event to it. The plan is to make this do caching and stuff and integrate it with existing worker infrastructure.

Ehsan,
If you have the time, can you fiddle with integrating this into Necko in some tiny sense? intercepting a http request and feeding it to this as an event. SendEvent() does not currently accept data, just an event name.
Attachment #789277 - Attachment is obsolete: true
Attachment #789292 - Attachment is obsolete: true
Attachment #789292 - Flags: feedback?
Flags: needinfo?(ehsan)
Alarm API with certain security checks disabled that enables it on web pages on Firefox Desktop, and uses nsIServiceWorkerManager rather than system messages.
Forgot to point out that the patch hard codes the Service Worker being at http://localhost:8000. Change the paths when you compile. Patches to fix this will come later.

Small test page https://github.com/nikhilm/serviceworker-demo which served from |python -m SimpleHTTPServer| will work with the localhost:8000 thing.
Nikhil, Josh is now working on NavController.  Josh, please see comment 8.  Thanks!
Flags: needinfo?(ehsan) → needinfo?(josh)
Summary: Implement Event Pages → Implement Service Workers
Posted patch ServiceWorkerManager (obsolete) — Splinter Review
Creates a window-less Worker.

RegisterServiceWorker() will load the URL and send it an install event.

SendEvent() can be used to send events. This will spawn a new Worker for every event, which is not what we want if the previous worker is alive (which it is since this does not terminate service workers yet).
Attachment #801003 - Attachment is obsolete: true
Useful for doing service worker specific stuff like introducing Cache APIs.

Josh, could you write a small WebIDL wrapper around your work in the Navigation Controller bug to create a simple Cache or SameOriginResponse and introduce it into the worker scope of a Service Worker?
Posted patch Promises on Workers. (obsolete) — Splinter Review
Assignee: nsm.nikhil → josh
Status: NEW → ASSIGNED
This is still missing some glue to create a FetchEvent, since we need to pass it a channel. In theory calling respondWith and passing a SameOriginResponse would do the right thing, however.
Marked Promises on worker bug as blocking this. That patch may be updated on bug 915233.

I have a WIP patch that adds InstallPhaseEvent and InstallEvent and some changes to existing patches.Since ServiceWorkers introduces these new events that may be dispatched on the Worker global, we need to wait for the conversion of WorkerPrivate and WorkerScope to use the main thread EventTarget infrastructure rather than implement custom events on the current code. khuey has a WIP patch for this, but he is on pseudo-vacation.
Depends on: 915233
Comment on attachment 814940 [details] [diff] [review]
Promises on Workers.

Obsoleting this patch as it does not make Promises 'usable' (runnable dispatch) on workers, while patch in referenced bug does.refer
Attachment #814940 - Attachment is obsolete: true

Updated

6 years ago
Blocks: 922363

Comment 19

6 years ago
(In reply to Nikhil Marathe [:nsm] from comment #17)
> … we need to wait for the conversion of WorkerPrivate and WorkerScope to
> use the main thread EventTarget infrastructure rather than implement 
> custom events on the current code. khuey has a WIP patch for this, but
> he is on pseudo-vacation.

Can you add the bug to the dependency list then, please?

Comment 20

6 years ago
Ah sorry, I misunderstood your comment. I just saw that Bug 915233 depends on Bug 914762 which you probably meant in Comment 18, right?
(In reply to Florian Bender from comment #20)
> Ah sorry, I misunderstood your comment. I just saw that Bug 915233 depends
> on Bug 914762 which you probably meant in Comment 18, right?

I did mean 915233 in comment 18. As for Kyle's patch, I don't know the bug number.
Unfinished, since the whole bit about actually creating and dispatching the FetchEvent is unclear to me. However, this should theoretically intercept document navigations for documents with active service workers.
Flags: needinfo?(josh)
I stole this by accident.
Assignee: josh → nsm.nikhil
Josh, ' Add Response, Request, SameOriginResponse, and FetchEvent implementations.' is missing FetchEvent.cpp. Could you update the patch? Thanks!
Flags: needinfo?(josh)
(please use Gecko coding style in content/ and dom/* code)
Attachment #814942 - Attachment is obsolete: true
Assignee: nsm.nikhil → josh
More interception, along with deducing fetch type and top level-ness.
Assignee: josh → nsm.nikhil
Flags: needinfo?(josh)
Hanging off tasks off this as I think of them.
Summary: Implement Service Workers → [meta] Implement Service Workers
Integrates into the SharedWorker infrastructure (needs more work) and dispatches the "install" event. Will be split into more bugs soon.
Unbitrot, add support for querying domain info about service worker.
Comment on attachment 830923 [details] [diff] [review]
Intercept images, fonts, objects, stylesheets, and XHRs.

Review of attachment 830923 [details] [diff] [review]:
-----------------------------------------------------------------

::: image/src/imgLoader.cpp
@@ +434,5 @@
>                       aPolicy);
>    if (NS_FAILED(rv))
>      return rv;
>  
> +  newChannel = aLoadingDocument->InterceptFetch(newChannel, nsIDocument::Fetch);

This needs a null check.
Added hashtables to keep track of ServiceWorkers.
Various Runnables to pass requests to and from workers.
Mark a document as being controlled in StartDocumentLoad.
Comment on attachment 8343448 [details] [diff] [review]
Make document navigation cause a ServiceWorker fetch event.

Review of attachment 8343448 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/base/src/nsDocument.cpp
@@ +2474,5 @@
>    }
>  
> +  bool dummy;
> +  nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID);
> +  swm->StartInterception(this, &dummy);

How do we plan to make use of the success value in the future?

::: dom/interfaces/base/nsIServiceWorkerManager.idl
@@ +17,5 @@
> +  void sendFetchEvent(in nsIDocument aDocument, in nsIAlternateSourceChannel aChannel, in nsIURI aPageURI);
> +  bool isControlled(in nsIDocument aDocument);
> +  // Returns a ServiceWorker or null.
> +  nsISupports GetServiceWorker(in nsIDocument aDocument);
> +  bool startInterception(in nsIDocument aDocument);

The return value needs documentation.

::: dom/workers/ServiceWorkerManager.cpp
@@ +355,5 @@
> +    JS::Rooted<JSObject*> jsGlobal(aCx, target->GetWrapper());
> +    GlobalObject globalObject(aCx, jsGlobal);
> +
> +    mozilla::dom::RequestInit init;
> +    init.mUrl.Construct(NS_ConvertUTF8toUTF16(mResourceURL));

I'm not convinced that using this URL across threads is safe. I would be inclined to store the spec and create a new URL here.

@@ +468,5 @@
> +  return NS_OK;
> +}
> +
> +static nsresult
> +GetDocumentDomain(nsIDocument* aDoc, nsCString& domain, JSContext* cx = nullptr)

This method feels like it should reside elsewhere (like in document code), but that's just my gut feeling.

@@ +520,5 @@
> +ServiceWorkerManager::IsControlled(nsIDocument* aDoc, bool* aControlled)
> +{
> +  MOZ_ASSERT(NS_IsMainThread());
> +  nsCString domain;
> +  nsresult rv = GetDocumentDomain(aDoc, domain);

rv is ignored

@@ +560,5 @@
> +ServiceWorkerManager::StartInterception(nsIDocument* aDoc, bool* aSuccess)
> +{
> +  MOZ_ASSERT(NS_IsMainThread());
> +  nsCString domain;
> +  nsresult rv = GetDocumentDomain(aDoc, domain);

rv is ignored.

@@ +821,5 @@
> +    return NS_OK;
> +  }
> +
> +  nsCString domain;
> +  nsresult rv = aDocument->GetDocumentURI()->GetHost(domain);

rv is ignored
Various rebases, spec updates and minor things to make these usable.
Depends on: 1032521

Updated

5 years ago
Depends on: 1038973
Depends on: 1045257
Depends on: 1053483
Depends on: 1056702
Depends on: 1065216
Depends on: 1065515
Depends on: 1065367
Depends on: 1065366
Depends on: 1078808
Depends on: 1080109
Depends on: 1080110
Whiteboard: [dependency: marketplace-partners]

Updated

5 years ago
Depends on: 1109680
jdm, are any of the attachments here relevant any longer? Otherwise I'll obsolete all of them.
Flags: needinfo?(josh)
Wow. No.
Flags: needinfo?(josh)
Assignee: nsm.nikhil → nobody
Status: ASSIGNED → NEW
Depends on: 1194562

Updated

4 years ago
See Also: → 1227104
Whiteboard: [dependency: marketplace-partners] → [dependency: marketplace-partners][games:p1]
Whiteboard: [dependency: marketplace-partners][games:p1] → [dependency: marketplace-partners][games:p1][platform-rel-Games]
platform-rel: --- → ?
No longer depends on: ServiceWorkers-B2G
No longer blocks: sw-devtools
Whiteboard: [dependency: marketplace-partners][games:p1][platform-rel-Games] → [games:p1][platform-rel-Games]
I've attempted to clean up this bug to use as a meta for ongoing service worker efforts.  I've hung some child meta bugs for different efforts underneath it:

  Bug 1226983 (ServiceWorkers-compat): Spec compatibility issues
  Bug 1262699 (ServiceWorkers-devtools): Make it easier for web devs to build service workers
  Bug 1328391 (ServiceWorkers-data): Add telemetry to support data driven development
  Bug 1328622 (ServiceWorkers-perf): Performance testing and optimizations
  Bug 1328614 (ServiceWorkers-tests): Issues with service worker related tests
  Bug 1283191 (ServiceWorkers-streams): Integrate WHATWG streams API into service workers
  Bug 1212882 (ServiceWorkers-foreign): Implement foreign fetch
I also added:

  Bug 1328631 (ServiceWorkers-stability): To track crashes, assertions, or other stability issues
platform-rel: ? → ---

Updated

11 months ago
Priority: -- → P2
Component: DOM → DOM: Core & HTML
Product: Core → Core
Type: defect → task

Comment 50

27 days ago

The task is meanwhile 6 years in progress and service workers are not enabled in the esr release versions per default.
When can you expect them enabled per default?

I've filed bug 1547023 to track enabling ServiceWorkers in ESR. I think there's a discussion still to be had there, but my presumption right now is that they would not be enabled on ESR 68. If you're aware of any ESR installations that would benefit from ServiceWorkers support and why the installations can't use non-ESR Firefox, I believe that would be useful information that would inform the decision-making process.

Depends on: ServiceWorkers-ESR
You need to log in before you can comment on or make changes to this bug.