Commit 6a96cb6a authored by Makoto Shimazu's avatar Makoto Shimazu Committed by Commit Bot

ServiceWorker: call StopWorker when the network service crashes

This CL is to stop service workers when the network service crashes. This might
drop inflight events, but given that the frequency is quite
low, it's acceptable. When another event is dispatched to the service worker, it
starts the worker again and it should work.

Bug: 884007
Change-Id: I2da4bd05c6a89f70b623da8e29a89488fd5a9cf3
Reviewed-on: https://chromium-review.googlesource.com/1235593
Commit-Queue: Makoto Shimazu <shimazu@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593150}
parent 66aa370d
......@@ -625,11 +625,7 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, MultipleWorkerFetch) {
}
// Make sure fetch from service worker context works after crash.
//
// Disabled since service workers don't support recovery from a NS crash:
// https://crbug.com/884007.
IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
DISABLED_ServiceWorkerFetch) {
IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, ServiceWorkerFetch) {
StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
BrowserContext::GetDefaultStoragePartition(browser_context()));
ServiceWorkerStatusObserver observer;
......
......@@ -67,6 +67,10 @@ class EmbeddedWorkerInstanceClientImpl
// Called from ServiceWorkerContextClient.
void WorkerContextDestroyed();
// mojom::EmbeddedWorkerInstanceClient implementation (partially exposed to
// public)
void StopWorker() override;
private:
EmbeddedWorkerInstanceClientImpl(
scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner,
......@@ -74,7 +78,6 @@ class EmbeddedWorkerInstanceClientImpl
// mojom::EmbeddedWorkerInstanceClient implementation
void StartWorker(mojom::EmbeddedWorkerStartParamsPtr params) override;
void StopWorker() override;
void ResumeAfterDownload() override;
void AddMessageToConsole(blink::WebConsoleMessage::Level level,
const std::string& message) override;
......
......@@ -171,6 +171,13 @@ class StreamHandleListener
blink::mojom::ServiceWorkerStreamCallbackPtr callback_ptr_;
};
bool IsOutOfProcessNetworkService() {
return base::FeatureList::IsEnabled(network::features::kNetworkService) &&
!base::FeatureList::IsEnabled(features::kNetworkServiceInProcess) &&
!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSingleProcess);
}
WebURLRequest::RequestContext GetBlinkRequestContext(
blink::mojom::RequestContextType request_context_type) {
return static_cast<WebURLRequest::RequestContext>(request_context_type);
......@@ -605,6 +612,21 @@ ServiceWorkerContextClient::ServiceWorkerContextClient(
std::move(instance_host), main_thread_task_runner_);
if (subresource_loaders) {
if (IsOutOfProcessNetworkService()) {
// If the network service crashes, this worker self-terminates, so it can
// be restarted later with a connection to the restarted network
// service.
// Note that the default factory is the network service factory. It's set
// on the start worker sequence.
network_service_connection_error_handler_holder_.Bind(
std::move(subresource_loaders->default_factory_info()));
network_service_connection_error_handler_holder_->Clone(
mojo::MakeRequest(&subresource_loaders->default_factory_info()));
network_service_connection_error_handler_holder_
.set_connection_error_handler(base::BindOnce(
&ServiceWorkerContextClient::StopWorker, base::Unretained(this)));
}
loader_factories_ = base::MakeRefCounted<HostChildURLLoaderFactoryBundle>(
main_thread_task_runner_);
loader_factories_->Update(std::make_unique<ChildURLLoaderFactoryBundleInfo>(
......@@ -1792,6 +1814,12 @@ bool ServiceWorkerContextClient::RequestedTermination() const {
return context_->timeout_timer->did_idle_timeout();
}
void ServiceWorkerContextClient::StopWorker() {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
if (embedded_worker_client_)
embedded_worker_client_->StopWorker();
}
void ServiceWorkerContextClient::AddServiceWorkerObject(
int64_t version_id,
WebServiceWorkerImpl* worker) {
......
......@@ -368,6 +368,9 @@ class CONTENT_EXPORT ServiceWorkerContextClient
// process. It does this due to idle timeout.
bool RequestedTermination() const;
// Stops the worker context. Called on the main thread.
void StopWorker();
// Keeps the mapping from version id to ServiceWorker object.
void AddServiceWorkerObject(int64_t version_id, WebServiceWorkerImpl* worker);
void RemoveServiceWorkerObject(int64_t version_id);
......@@ -428,6 +431,11 @@ class CONTENT_EXPORT ServiceWorkerContextClient
// A URLLoaderFactory instance used for subresource loading.
scoped_refptr<HostChildURLLoaderFactoryBundle> loader_factories_;
// Out-of-process NetworkService:
// Detects disconnection from the network service.
network::mojom::URLLoaderFactoryPtr
network_service_connection_error_handler_holder_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextClient);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment