Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1510)

Unified Diff: content/browser/service_worker/service_worker_cache_writer.h

Issue 1315443003: ServiceWorkerWriteToCacheJob: refactor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: first draft Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/service_worker/service_worker_cache_writer.h
diff --git a/content/browser/service_worker/service_worker_cache_writer.h b/content/browser/service_worker/service_worker_cache_writer.h
new file mode 100644
index 0000000000000000000000000000000000000000..70010c36f57f6312f8f7fa94a87e9e01a2547cb9
--- /dev/null
+++ b/content/browser/service_worker/service_worker_cache_writer.h
@@ -0,0 +1,210 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_
+
+#include <map>
+#include <set>
+
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+
+namespace content {
+
+struct HttpResponseInfoIOBuffer;
+class ServiceWorkerCacheWriterCore;
+class ServiceWorkerResponseReader;
+class ServiceWorkerResponseWriter;
+class ServiceWorkerStorage;
+
+// This class is responsible for possibly updating the ServiceWorker cache for
+// an installed ServiceWorker main script. If there is no existing cache entry,
+// this class always writes supplied data back to the cache; if there is an
+// existing cache entry, this class only writes supplied data back if there is a
+// cache mismatch.
+//
+// Note that writes done by this class cannot be "short" - ie, if they succeed,
+// they always write all the supplied data back. Therefore completions are
+// signalled with net::Error without a count of bytes written.
+//
+// This class's behavior is modelled as a state machine; see the StateMachine
+// inner class below for the mechanics of this.
+class ServiceWorkerCacheWriter {
+ public:
+ using OnWriteCompleteCallback = base::Callback<void(net::Error)>;
+
+ // The types for the factory functions passed into the constructor. These are
+ // responsible for creating readers from the existing cache entry and writers
+ // to the new cache entry when called. These are passed in as factories
+ // instead of passing readers and writers in directly to avoid creating
+ // writers to entries that won't be updated, and because this class may need
+ // multiple readers internally.
+ using ResponseReaderCreator =
+ base::Callback<scoped_ptr<ServiceWorkerResponseReader>(void)>;
+ using ResponseWriterCreator =
+ base::Callback<scoped_ptr<ServiceWorkerResponseWriter>(void)>;
+
+ // The existing reader may be null, in which case this instance will
+ // unconditionally write back data supplied to |WriteHeaders| and |WriteData|.
+ ServiceWorkerCacheWriter(const ResponseReaderCreator& reader_creator,
+ const ResponseWriterCreator& writer_creator);
+
+ virtual ~ServiceWorkerCacheWriter();
+
+ // Writes the supplied |headers| back to the cache. Returns ERR_IO_PENDING if
+ // the write will complete asynchronously, in which case |callback| will be
+ // called when it completes. Otherwise, returns a code other than
+ // ERR_IO_PENDING and does not invoke |callback|.
+ net::Error WriteHeaders(HttpResponseInfoIOBuffer* headers,
+ const OnWriteCompleteCallback& callback);
+
+ // Writes the supplied body data |data| back to the cache. Returns
+ // ERR_IO_PENDING if the write will complete asynchronously, in which case
+ // |callback| will be called when it completes. Otherwise, returns a code
+ // other than ERR_IO_PENDING and does not invoke |callback|.
+ net::Error WriteData(net::IOBuffer* buf,
+ size_t buf_size,
+ const OnWriteCompleteCallback& callback);
+
+ // Returns a count of bytes written back to the cache.
+ size_t BytesWritten() const;
+
+ private:
+ // This class provides an abstract state machine with states named by numeric
+ // IDs and human-readable string names. Each state has a handler, which is run
+ // whenever the state machine is in that state; handlers are responsible for
+ // producing the next state for the machine (via the |next_state| argument),
+ // deciding whether to pause the state machine (via the |pause| argument), and
+ // also generating the next status field, which is passed untouched into the
+ // next state's handler.
+ class StateMachine {
+ public:
+ enum {
+ // Builtin states. All states are allowed to transition to STATE_DONE and
+ // the machine starts in STATE_DONE, but these are otherwise not special.
+ STATE_START = -1,
+ STATE_DONE = -2,
+ };
+
+ // The state handler type. The arguments are:
+ // int* next_state - state the machine should move to next
+ // bool* pause - whether the machine should pause (return from Run) or not
+ // int status - status from the previous state's Handler
+ using Handler = base::Callback<int(int*, bool*, int)>;
+
+ StateMachine();
+ ~StateMachine();
+
+ // Add a new state to the machine. All states must be registered with this
+ // function before transitions are added referencing them. The |name| is an
+ // arbitrary string, used only for debugging.
+ void AddState(int id, const std::string& name, const Handler& handler);
+
+ // Add an allowed transition from state |from_id| to state |to_id|. In debug
+ // builds, allowed transitions are enforced by the state machine.
+ void AddTransition(int from_id, int to_id);
+
+ // In debug builds, DCHECK() that |from_id| and |to_id| are both valid
+ // states, and that a transition from |from_id| to |to_id| is allowed.
+ void CheckValidTransition(int from_id, int to_id);
+
+ // Runs the state machine. This function executes the handlers for
+ // successive states of the machine until:
+ // a) The machine enters STATE_DONE
+ // b) A handler returns a negative value, indicating an error
+ // c) A handler pauses the machine
+ // This function returns the return value of the last handler that was run.
+ int Run(int status);
+
+ private:
+ // Internal representation of individual states. The |allowed_to| set is a
+ // set of states that a machine in this state may transition to.
+ struct State {
+ State();
+ State(int id, const std::string& name, const Handler& handler);
+ ~State();
+ int id;
+ std::string name;
+ Handler handler;
+ std::set<int> allowed_to;
+ };
+ std::map<int, State> states_;
+ int state_;
+ };
+
+ // State handlers. See function comments in the corresponding source file for
+ // details on these.
+ int Start(int* next_state, bool* pause, int result);
+ int ReadHeadersForCompare(int* next_state, bool* pause, int result);
+ int ReadHeadersForCompareDone(int* next_state, bool* pause, int result);
+ int ReadDataForCompare(int* next_state, bool* pause, int result);
+ int ReadDataForCompareDone(int* next_state, bool* pause, int result);
+ int ReadHeadersForCopy(int* next_state, bool* pause, int result);
+ int ReadHeadersForCopyDone(int* next_state, bool* pause, int result);
+ int WriteHeadersForCopy(int* next_state, bool* pause, int result);
+ int WriteHeadersForCopyDone(int* next_state, bool* pause, int result);
+ int ReadDataForCopy(int* next_state, bool* pause, int result);
+ int ReadDataForCopyDone(int* next_state, bool* pause, int result);
+ int WriteDataForCopy(int* next_state, bool* pause, int result);
+ int WriteDataForCopyDone(int* next_state, bool* pause, int result);
+ int WriteHeadersForPassthrough(int* next_state, bool* pause, int result);
+ int WriteHeadersForPassthroughDone(int* next_state, bool* pause, int result);
+ int WriteDataForPassthrough(int* next_state, bool* pause, int result);
+ int WriteDataForPassthroughDone(int* next_state, bool* pause, int result);
+ int Done(int* next_state, bool* pause, int result);
+
+ // Wrappers for asynchronous calls. These are responsible for scheduling a
+ // callback to drive the state machine if needed. These either:
+ // a) Return ERR_IO_PENDING, and schedule a callback to run the state
+ // machine's Run() later, or
+ // b) Return some other value and do not schedule a callback.
+ int ReadInfoHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader,
+ HttpResponseInfoIOBuffer* buf);
+ int ReadDataHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader,
+ net::IOBuffer* buf,
+ int buf_len);
+ int WriteInfoHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer,
+ HttpResponseInfoIOBuffer* buf);
+ int WriteDataHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer,
+ net::IOBuffer* buf,
+ int buf_len);
+
+ // Callback used by the above helpers.
+ void AsyncRunStateMachine(int result);
+
+ StateMachine state_machine_;
+
+ scoped_refptr<HttpResponseInfoIOBuffer> headers_to_read_;
+ scoped_refptr<HttpResponseInfoIOBuffer> headers_to_write_;
+ scoped_refptr<net::IOBuffer> data_to_read_;
+ int len_to_read_;
+ scoped_refptr<net::IOBuffer> data_to_copy_;
+ scoped_refptr<net::IOBuffer> data_to_write_;
+ int len_to_write_;
+ OnWriteCompleteCallback pending_callback_;
+
+ size_t cached_length_;
+ size_t net_length_;
+
+ size_t bytes_compared_;
+ size_t bytes_copied_;
+ size_t bytes_written_;
+
+ size_t compare_offset_;
+
+ ResponseReaderCreator reader_creator_;
+ ResponseWriterCreator writer_creator_;
+ scoped_ptr<ServiceWorkerResponseReader> compare_reader_;
+ scoped_ptr<ServiceWorkerResponseReader> copy_reader_;
+ scoped_ptr<ServiceWorkerResponseWriter> writer_;
+ base::WeakPtrFactory<ServiceWorkerCacheWriter> weak_factory_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_

Powered by Google App Engine
This is Rietveld 408576698