Commit 5e4f0f6a authored by Makoto Shimazu's avatar Makoto Shimazu Committed by Commit Bot

ServiceWorker: Implement SWInstalledScriptsSender

This is 7th patch of script streaming project split off from
https://chromium-review.googlesource.com/c/538477.
Design doc:
https://docs.google.com/document/d/1BbETxB2K1GeGUv4XIvGGforAJRRgYSNX5x4vPTGsCPU/edit

This patch implements SWInstalledScriptsSender to push the installed scripts
over mojo pipes from the browser to the renderer. The sender is started when
ServiceWorkerVersion asks EmbeddedWorkerInstance to start the worker. That
means that scripts will be received on the io thread immediately after binding
the Mojo interface.

From this patch, "--enable-features=ServiceWorkerScriptStreaming" takes effect.
When LayoutTests under virtual/service-worker-script-streaming fail, please add
TestExpectations and report it to https://crbug.com/683037.

Bug: 683037
Change-Id: I5aef2cff6026ae3afa004932f77064f24ba8bfc7
Reviewed-on: https://chromium-review.googlesource.com/563144
Commit-Queue: Makoto Shimazu <shimazu@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488576}
parent ec0a0ebf
...@@ -9,13 +9,20 @@ ...@@ -9,13 +9,20 @@
namespace content { namespace content {
struct HttpResponseInfoIOBuffer;
class ServiceWorkerContextCore;
class ServiceWorkerVersion;
// ServiceWorkerInstalledScriptsSender serves the service worker's installed // ServiceWorkerInstalledScriptsSender serves the service worker's installed
// scripts from ServiceWorkerStorage to the renderer through Mojo data pipes. // scripts from ServiceWorkerStorage to the renderer through Mojo data pipes.
// ServiceWorkerInstalledScriptsSender is owned by ServiceWorkerVersion. It is // ServiceWorkerInstalledScriptsSender is owned by ServiceWorkerVersion. It is
// created for worker startup and lives as long as the worker is running. // created for worker startup and lives as long as the worker is running.
class ServiceWorkerInstalledScriptsSender { class CONTENT_EXPORT ServiceWorkerInstalledScriptsSender {
public: public:
ServiceWorkerInstalledScriptsSender(); ServiceWorkerInstalledScriptsSender(
ServiceWorkerVersion* owner,
const GURL& main_script_url,
base::WeakPtr<ServiceWorkerContextCore> context);
~ServiceWorkerInstalledScriptsSender(); ~ServiceWorkerInstalledScriptsSender();
// Creates a Mojo struct (mojom::ServiceWorkerInstalledScriptsInfo) and sets // Creates a Mojo struct (mojom::ServiceWorkerInstalledScriptsInfo) and sets
...@@ -23,8 +30,54 @@ class ServiceWorkerInstalledScriptsSender { ...@@ -23,8 +30,54 @@ class ServiceWorkerInstalledScriptsSender {
// on the renderer. // on the renderer.
mojom::ServiceWorkerInstalledScriptsInfoPtr CreateInfoAndBind(); mojom::ServiceWorkerInstalledScriptsInfoPtr CreateInfoAndBind();
// Starts sending installed scripts to the worker.
void Start();
private: private:
class Sender;
enum class Status {
kSuccess,
kNoHttpInfoError,
kCreateDataPipeError,
kConnectionError,
kResponseReaderError,
kMetaDataSenderError,
};
enum class State {
kNotStarted,
kSendingMainScript,
kSendingImportedScript,
kFinished,
};
void StartSendingScript(int64_t resource_id);
// Called from |running_sender_|.
void SendScriptInfoToRenderer(
std::string encoding,
std::unordered_map<std::string, std::string> headers,
mojo::ScopedDataPipeConsumerHandle meta_data_handle,
mojo::ScopedDataPipeConsumerHandle body_handle);
void OnHttpInfoRead(scoped_refptr<HttpResponseInfoIOBuffer> http_info);
void OnFinishSendingScript();
void OnAbortSendingScript(Status status);
const GURL& CurrentSendingURL();
ServiceWorkerVersion* owner_;
const GURL main_script_url_;
int main_script_id_;
mojom::ServiceWorkerInstalledScriptsManagerPtr manager_; mojom::ServiceWorkerInstalledScriptsManagerPtr manager_;
std::unique_ptr<Sender> running_sender_;
State state_;
std::map<int64_t /* resource_id */, GURL> imported_scripts_;
std::map<int64_t /* resource_id */, GURL>::iterator imported_script_iter_;
base::WeakPtr<ServiceWorkerContextCore> context_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerInstalledScriptsSender);
}; };
} // namespace content } // namespace content
......
...@@ -260,6 +260,7 @@ class CONTENT_EXPORT ServiceWorkerStorage ...@@ -260,6 +260,7 @@ class CONTENT_EXPORT ServiceWorkerStorage
friend class ServiceWorkerContextRequestHandlerTest; friend class ServiceWorkerContextRequestHandlerTest;
friend class ServiceWorkerReadFromCacheJobTest; friend class ServiceWorkerReadFromCacheJobTest;
friend class ServiceWorkerRequestHandlerTest; friend class ServiceWorkerRequestHandlerTest;
friend class ServiceWorkerInstalledScriptsSenderTest;
friend class ServiceWorkerURLRequestJobTest; friend class ServiceWorkerURLRequestJobTest;
friend class ServiceWorkerVersionBrowserTest; friend class ServiceWorkerVersionBrowserTest;
friend class ServiceWorkerVersionTest; friend class ServiceWorkerVersionTest;
......
...@@ -1476,11 +1476,14 @@ void ServiceWorkerVersion::StartWorkerInternal() { ...@@ -1476,11 +1476,14 @@ void ServiceWorkerVersion::StartWorkerInternal() {
params->pause_after_download = pause_after_download_; params->pause_after_download = pause_after_download_;
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info; mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info;
if (ServiceWorkerUtils::IsScriptStreamingEnabled()) { if (ServiceWorkerUtils::IsScriptStreamingEnabled() &&
!pause_after_download_) {
DCHECK(!installed_scripts_sender_); DCHECK(!installed_scripts_sender_);
installed_scripts_sender_ = installed_scripts_sender_ =
base::MakeUnique<ServiceWorkerInstalledScriptsSender>(); base::MakeUnique<ServiceWorkerInstalledScriptsSender>(
this, script_url(), context());
installed_scripts_info = installed_scripts_sender_->CreateInfoAndBind(); installed_scripts_info = installed_scripts_sender_->CreateInfoAndBind();
installed_scripts_sender_->Start();
} }
embedded_worker_->Start( embedded_worker_->Start(
......
...@@ -22,8 +22,9 @@ struct ServiceWorkerScriptInfo { ...@@ -22,8 +22,9 @@ struct ServiceWorkerScriptInfo {
map<string, string> headers; map<string, string> headers;
// A handle for receiving the script body. // A handle for receiving the script body.
handle<data_pipe_consumer> body; handle<data_pipe_consumer> body;
// A handle for receiving the V8 code cached metadata. // A handle for receiving the V8 code cached metadata. This is null when no
handle<data_pipe_consumer> meta_data; // meta data is available.
handle<data_pipe_consumer>? meta_data;
}; };
// Renderer-side interface. The browser uses this interface to send // Renderer-side interface. The browser uses this interface to send
......
...@@ -120,8 +120,11 @@ EmbeddedWorkerInstanceClientImpl::StartWorkerContext( ...@@ -120,8 +120,11 @@ EmbeddedWorkerInstanceClientImpl::StartWorkerContext(
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info, mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
std::unique_ptr<ServiceWorkerContextClient> context_client) { std::unique_ptr<ServiceWorkerContextClient> context_client) {
std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager> manager; std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager> manager;
if (ServiceWorkerUtils::IsScriptStreamingEnabled()) { // |installed_scripts_info| is null if scripts should be served by net layer,
DCHECK(installed_scripts_info); // when the worker is not installed, or the worker is launched for checking
// the update.
if (ServiceWorkerUtils::IsScriptStreamingEnabled() &&
installed_scripts_info) {
manager = WebServiceWorkerInstalledScriptsManagerImpl::Create( manager = WebServiceWorkerInstalledScriptsManagerImpl::Create(
std::move(installed_scripts_info), io_thread_runner_); std::move(installed_scripts_info), io_thread_runner_);
} }
......
...@@ -27,6 +27,10 @@ class Receiver { ...@@ -27,6 +27,10 @@ class Receiver {
watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL) {} watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL) {}
void Start(base::OnceClosure callback) { void Start(base::OnceClosure callback) {
if (!handle_.is_valid()) {
std::move(callback).Run();
return;
}
callback_ = std::move(callback); callback_ = std::move(callback);
// base::Unretained is safe because |watcher_| is owned by |this|. // base::Unretained is safe because |watcher_| is owned by |this|.
watcher_.Watch(handle_.get(), MOJO_HANDLE_SIGNAL_READABLE, watcher_.Watch(handle_.get(), MOJO_HANDLE_SIGNAL_READABLE,
......
...@@ -1315,6 +1315,7 @@ test("content_unittests") { ...@@ -1315,6 +1315,7 @@ test("content_unittests") {
"../browser/service_worker/service_worker_database_unittest.cc", "../browser/service_worker/service_worker_database_unittest.cc",
"../browser/service_worker/service_worker_dispatcher_host_unittest.cc", "../browser/service_worker/service_worker_dispatcher_host_unittest.cc",
"../browser/service_worker/service_worker_handle_unittest.cc", "../browser/service_worker/service_worker_handle_unittest.cc",
"../browser/service_worker/service_worker_installed_scripts_sender_unittest.cc",
"../browser/service_worker/service_worker_job_unittest.cc", "../browser/service_worker/service_worker_job_unittest.cc",
"../browser/service_worker/service_worker_lifetime_tracker_unittest.cc", "../browser/service_worker/service_worker_lifetime_tracker_unittest.cc",
"../browser/service_worker/service_worker_metrics_unittest.cc", "../browser/service_worker/service_worker_metrics_unittest.cc",
......
...@@ -114,8 +114,8 @@ WebEmbeddedWorkerImpl::WebEmbeddedWorkerImpl( ...@@ -114,8 +114,8 @@ WebEmbeddedWorkerImpl::WebEmbeddedWorkerImpl(
waiting_for_debugger_state_(kNotWaitingForDebugger) { waiting_for_debugger_state_(kNotWaitingForDebugger) {
RunningWorkerInstances().insert(this); RunningWorkerInstances().insert(this);
if (RuntimeEnabledFeatures::ServiceWorkerScriptStreamingEnabled()) { if (RuntimeEnabledFeatures::ServiceWorkerScriptStreamingEnabled() &&
DCHECK(installed_scripts_manager); installed_scripts_manager) {
installed_scripts_manager_ = installed_scripts_manager_ =
WTF::MakeUnique<ServiceWorkerInstalledScriptsManager>( WTF::MakeUnique<ServiceWorkerInstalledScriptsManager>(
std::move(installed_scripts_manager)); std::move(installed_scripts_manager));
......
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