Changeset 225486 in webkit


Ignore:
Timestamp:
Dec 4, 2017 12:35:05 PM (6 years ago)
Author:
commit-queue@webkit.org
Message:

Call "Terminate Service Worker" on all workers when all their clients are gone
https://bugs.webkit.org/show_bug.cgi?id=179552

Patch by Youenn Fablet <youenn@apple.com> on 2017-12-04
Reviewed by Chris Dumez.

Tested manually.

When SWServer detects that there is no longer any client for a given client origin,
it iterates through the running workers to terminate them if they have the given client origin.
A timer of 60 seconds is used in case a user closes a tab or a window, and reopens one with the same origin shortly after.

  • workers/service/server/SWServer.cpp:

(WebCore::SWServer::findClientByIdentifier):
(WebCore::SWServer::matchAll):
(WebCore::SWServer::registerServiceWorkerClient):
(WebCore::SWServer::unregisterServiceWorkerClient):

  • workers/service/server/SWServer.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r225485 r225486  
     12017-12-04  Youenn Fablet  <youenn@apple.com>
     2
     3        Call "Terminate Service Worker" on all workers when all their clients are gone
     4        https://bugs.webkit.org/show_bug.cgi?id=179552
     5
     6        Reviewed by Chris Dumez.
     7
     8        Tested manually.
     9
     10        When SWServer detects that there is no longer any client for a given client origin,
     11        it iterates through the running workers to terminate them if they have the given client origin.
     12        A timer of 60 seconds is used in case a user closes a tab or a window, and reopens one with the same origin shortly after.
     13
     14        * workers/service/server/SWServer.cpp:
     15        (WebCore::SWServer::findClientByIdentifier):
     16        (WebCore::SWServer::matchAll):
     17        (WebCore::SWServer::registerServiceWorkerClient):
     18        (WebCore::SWServer::unregisterServiceWorkerClient):
     19        * workers/service/server/SWServer.h:
     20
    1212017-12-04  Antti Koivisto  <antti@apple.com>
    222
  • trunk/Source/WebCore/workers/service/server/SWServer.cpp

    r225457 r225486  
    5353}
    5454
     55static Seconds terminationDelay { 60_s };
     56
    5557SWServer::Connection::Connection(SWServer& server)
    5658    : m_server(server)
     
    323325        return std::nullopt;
    324326
    325     auto& clients = iterator->value;
     327    auto& clients = iterator->value.clients;
    326328    auto position = clients.findMatching([&] (const auto& client) {
    327329        return clientIdentifier == client.identifier;
     
    337339    // FIXME: Support WindowClient additional properties.
    338340
    339     auto clients = m_clients.get(worker.origin());
     341    auto clients = m_clients.find(worker.origin())->value.clients;
    340342
    341343    if (!options.includeUncontrolled) {
     
    616618void SWServer::registerServiceWorkerClient(ClientOrigin&& clientOrigin, ServiceWorkerClientIdentifier identifier, ServiceWorkerClientData&& data)
    617619{
    618     m_clients.ensure(WTFMove(clientOrigin), [] {
    619         return Vector<ServiceWorkerClientInformation> { };
    620     }).iterator->value.append(ServiceWorkerClientInformation { identifier, WTFMove(data) });
     620    auto& clientsData = m_clients.ensure(WTFMove(clientOrigin), [] {
     621        return Clients { };
     622    }).iterator->value;
     623
     624    clientsData.clients.append(ServiceWorkerClientInformation { identifier, WTFMove(data) });
     625    if (clientsData.terminateServiceWorkersTimer)
     626        clientsData.terminateServiceWorkersTimer = nullptr;
    621627}
    622628
     
    626632    ASSERT(iterator != m_clients.end());
    627633
    628     auto& clients = iterator->value;
     634    auto& clients = iterator->value.clients;
    629635    clients.removeFirstMatching([&] (const auto& item) {
    630636        return identifier == item.identifier;
    631637    });
    632     if (clients.isEmpty()) {
    633         // FIXME: We might want to terminate any clientOrigin related service worker.
    634         m_clients.remove(iterator);
    635     }
     638
     639    if (!clients.isEmpty() || m_runningOrTerminatingWorkers.isEmpty())
     640        return;
     641
     642    ASSERT(!iterator->value.terminateServiceWorkersTimer);
     643    iterator->value.terminateServiceWorkersTimer = std::make_unique<Timer>([clientOrigin, this] {
     644        for (auto& worker : m_runningOrTerminatingWorkers.values()) {
     645            if (worker->origin() == clientOrigin)
     646                terminateWorker(worker);
     647        }
     648        m_clients.remove(clientOrigin);
     649    });
     650    iterator->value.terminateServiceWorkersTimer->startOneShot(terminationDelay);
    636651}
    637652
  • trunk/Source/WebCore/workers/service/server/SWServer.h

    r225452 r225486  
    6060struct ServiceWorkerFetchResult;
    6161struct ServiceWorkerRegistrationData;
     62class Timer;
    6263
    6364class SWServer {
     
    185186    HashMap<ServiceWorkerIdentifier, Ref<SWServerWorker>> m_runningOrTerminatingWorkers;
    186187
    187     HashMap<ClientOrigin, Vector<ServiceWorkerClientInformation>> m_clients;
     188    struct Clients {
     189        Vector<ServiceWorkerClientInformation> clients;
     190        std::unique_ptr<Timer> terminateServiceWorkersTimer;
     191    };
     192    HashMap<ClientOrigin, Clients> m_clients;
    188193    HashMap<ServiceWorkerClientIdentifier, ServiceWorkerIdentifier> m_clientToControllingWorker;
    189194
Note: See TracChangeset for help on using the changeset viewer.