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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_
6 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_
7
8 #include <map>
9 #include <set>
10
11 #include "base/callback.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h"
16
17 namespace content {
18
19 struct HttpResponseInfoIOBuffer;
20 class ServiceWorkerCacheWriterCore;
21 class ServiceWorkerResponseReader;
22 class ServiceWorkerResponseWriter;
23 class ServiceWorkerStorage;
24
25 // This class is responsible for possibly updating the ServiceWorker cache for
26 // an installed ServiceWorker main script. If there is no existing cache entry,
27 // this class always writes supplied data back to the cache; if there is an
28 // existing cache entry, this class only writes supplied data back if there is a
29 // cache mismatch.
30 //
31 // Note that writes done by this class cannot be "short" - ie, if they succeed,
32 // they always write all the supplied data back. Therefore completions are
33 // signalled with net::Error without a count of bytes written.
34 //
35 // This class's behavior is modelled as a state machine; see the StateMachine
36 // inner class below for the mechanics of this.
37 class ServiceWorkerCacheWriter {
38 public:
39 using OnWriteCompleteCallback = base::Callback<void(net::Error)>;
40
41 // The types for the factory functions passed into the constructor. These are
42 // responsible for creating readers from the existing cache entry and writers
43 // to the new cache entry when called. These are passed in as factories
44 // instead of passing readers and writers in directly to avoid creating
45 // writers to entries that won't be updated, and because this class may need
46 // multiple readers internally.
47 using ResponseReaderCreator =
48 base::Callback<scoped_ptr<ServiceWorkerResponseReader>(void)>;
49 using ResponseWriterCreator =
50 base::Callback<scoped_ptr<ServiceWorkerResponseWriter>(void)>;
51
52 // The existing reader may be null, in which case this instance will
53 // unconditionally write back data supplied to |WriteHeaders| and |WriteData|.
54 ServiceWorkerCacheWriter(const ResponseReaderCreator& reader_creator,
55 const ResponseWriterCreator& writer_creator);
56
57 virtual ~ServiceWorkerCacheWriter();
58
59 // Writes the supplied |headers| back to the cache. Returns ERR_IO_PENDING if
60 // the write will complete asynchronously, in which case |callback| will be
61 // called when it completes. Otherwise, returns a code other than
62 // ERR_IO_PENDING and does not invoke |callback|.
63 net::Error WriteHeaders(HttpResponseInfoIOBuffer* headers,
64 const OnWriteCompleteCallback& callback);
65
66 // Writes the supplied body data |data| back to the cache. Returns
67 // ERR_IO_PENDING if the write will complete asynchronously, in which case
68 // |callback| will be called when it completes. Otherwise, returns a code
69 // other than ERR_IO_PENDING and does not invoke |callback|.
70 net::Error WriteData(net::IOBuffer* buf,
71 size_t buf_size,
72 const OnWriteCompleteCallback& callback);
73
74 // Returns a count of bytes written back to the cache.
75 size_t BytesWritten() const;
76
77 private:
78 // This class provides an abstract state machine with states named by numeric
79 // IDs and human-readable string names. Each state has a handler, which is run
80 // whenever the state machine is in that state; handlers are responsible for
81 // producing the next state for the machine (via the |next_state| argument),
82 // deciding whether to pause the state machine (via the |pause| argument), and
83 // also generating the next status field, which is passed untouched into the
84 // next state's handler.
85 class StateMachine {
86 public:
87 enum {
88 // Builtin states. All states are allowed to transition to STATE_DONE and
89 // the machine starts in STATE_DONE, but these are otherwise not special.
90 STATE_START = -1,
91 STATE_DONE = -2,
92 };
93
94 // The state handler type. The arguments are:
95 // int* next_state - state the machine should move to next
96 // bool* pause - whether the machine should pause (return from Run) or not
97 // int status - status from the previous state's Handler
98 using Handler = base::Callback<int(int*, bool*, int)>;
99
100 StateMachine();
101 ~StateMachine();
102
103 // Add a new state to the machine. All states must be registered with this
104 // function before transitions are added referencing them. The |name| is an
105 // arbitrary string, used only for debugging.
106 void AddState(int id, const std::string& name, const Handler& handler);
107
108 // Add an allowed transition from state |from_id| to state |to_id|. In debug
109 // builds, allowed transitions are enforced by the state machine.
110 void AddTransition(int from_id, int to_id);
111
112 // In debug builds, DCHECK() that |from_id| and |to_id| are both valid
113 // states, and that a transition from |from_id| to |to_id| is allowed.
114 void CheckValidTransition(int from_id, int to_id);
115
116 // Runs the state machine. This function executes the handlers for
117 // successive states of the machine until:
118 // a) The machine enters STATE_DONE
119 // b) A handler returns a negative value, indicating an error
120 // c) A handler pauses the machine
121 // This function returns the return value of the last handler that was run.
122 int Run(int status);
123
124 private:
125 // Internal representation of individual states. The |allowed_to| set is a
126 // set of states that a machine in this state may transition to.
127 struct State {
128 State();
129 State(int id, const std::string& name, const Handler& handler);
130 ~State();
131 int id;
132 std::string name;
133 Handler handler;
134 std::set<int> allowed_to;
135 };
136 std::map<int, State> states_;
137 int state_;
138 };
139
140 // State handlers. See function comments in the corresponding source file for
141 // details on these.
142 int Start(int* next_state, bool* pause, int result);
143 int ReadHeadersForCompare(int* next_state, bool* pause, int result);
144 int ReadHeadersForCompareDone(int* next_state, bool* pause, int result);
145 int ReadDataForCompare(int* next_state, bool* pause, int result);
146 int ReadDataForCompareDone(int* next_state, bool* pause, int result);
147 int ReadHeadersForCopy(int* next_state, bool* pause, int result);
148 int ReadHeadersForCopyDone(int* next_state, bool* pause, int result);
149 int WriteHeadersForCopy(int* next_state, bool* pause, int result);
150 int WriteHeadersForCopyDone(int* next_state, bool* pause, int result);
151 int ReadDataForCopy(int* next_state, bool* pause, int result);
152 int ReadDataForCopyDone(int* next_state, bool* pause, int result);
153 int WriteDataForCopy(int* next_state, bool* pause, int result);
154 int WriteDataForCopyDone(int* next_state, bool* pause, int result);
155 int WriteHeadersForPassthrough(int* next_state, bool* pause, int result);
156 int WriteHeadersForPassthroughDone(int* next_state, bool* pause, int result);
157 int WriteDataForPassthrough(int* next_state, bool* pause, int result);
158 int WriteDataForPassthroughDone(int* next_state, bool* pause, int result);
159 int Done(int* next_state, bool* pause, int result);
160
161 // Wrappers for asynchronous calls. These are responsible for scheduling a
162 // callback to drive the state machine if needed. These either:
163 // a) Return ERR_IO_PENDING, and schedule a callback to run the state
164 // machine's Run() later, or
165 // b) Return some other value and do not schedule a callback.
166 int ReadInfoHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader,
167 HttpResponseInfoIOBuffer* buf);
168 int ReadDataHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader,
169 net::IOBuffer* buf,
170 int buf_len);
171 int WriteInfoHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer,
172 HttpResponseInfoIOBuffer* buf);
173 int WriteDataHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer,
174 net::IOBuffer* buf,
175 int buf_len);
176
177 // Callback used by the above helpers.
178 void AsyncRunStateMachine(int result);
179
180 StateMachine state_machine_;
181
182 scoped_refptr<HttpResponseInfoIOBuffer> headers_to_read_;
183 scoped_refptr<HttpResponseInfoIOBuffer> headers_to_write_;
184 scoped_refptr<net::IOBuffer> data_to_read_;
185 int len_to_read_;
186 scoped_refptr<net::IOBuffer> data_to_copy_;
187 scoped_refptr<net::IOBuffer> data_to_write_;
188 int len_to_write_;
189 OnWriteCompleteCallback pending_callback_;
190
191 size_t cached_length_;
192 size_t net_length_;
193
194 size_t bytes_compared_;
195 size_t bytes_copied_;
196 size_t bytes_written_;
197
198 size_t compare_offset_;
199
200 ResponseReaderCreator reader_creator_;
201 ResponseWriterCreator writer_creator_;
202 scoped_ptr<ServiceWorkerResponseReader> compare_reader_;
203 scoped_ptr<ServiceWorkerResponseReader> copy_reader_;
204 scoped_ptr<ServiceWorkerResponseWriter> writer_;
205 base::WeakPtrFactory<ServiceWorkerCacheWriter> weak_factory_;
206 };
207
208 } // namespace content
209
210 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698