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

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: Fixes Created 5 years, 2 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 "content/common/content_export.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_errors.h"
17
18 namespace content {
19
20 struct HttpResponseInfoIOBuffer;
21 class ServiceWorkerCacheWriterCore;
22 class ServiceWorkerResponseReader;
23 class ServiceWorkerResponseWriter;
24 class ServiceWorkerStorage;
25
26 // This class is responsible for possibly updating the ServiceWorker script
27 // cache for an installed ServiceWorker main script. If there is no existing
28 // cache entry, this class always writes supplied data back to the cache; if
29 // there is an existing cache entry, this class only writes supplied data back
30 // if there is a cache mismatch.
31 //
32 // Note that writes done by this class cannot be "short" - ie, if they succeed,
33 // they always write all the supplied data back. Therefore completions are
34 // signalled with net::Error without a count of bytes written.
35 //
36 // This class's behavior is modelled as a state machine; see the DoLoop function
37 // for comments about this.
38 class CONTENT_EXPORT ServiceWorkerCacheWriter {
39 public:
40 using OnWriteCompleteCallback = base::Callback<void(net::Error)>;
41
42 // The types for the factory functions passed into the constructor. These are
43 // responsible for creating readers from the existing cache entry and writers
44 // to the new cache entry when called. These are passed in as factories
45 // instead of passing readers and writers in directly to avoid creating
46 // writers to entries that won't be updated, and because this class may need
47 // multiple readers internally.
48 using ResponseReaderCreator =
49 base::Callback<scoped_ptr<ServiceWorkerResponseReader>(void)>;
50 using ResponseWriterCreator =
51 base::Callback<scoped_ptr<ServiceWorkerResponseWriter>(void)>;
52
53 // The existing reader may be null, in which case this instance will
54 // unconditionally write back data supplied to |MaybeWriteHeaders| and
55 // |MaybeWriteData|.
56 ServiceWorkerCacheWriter(const ResponseReaderCreator& reader_creator,
57 const ResponseWriterCreator& writer_creator);
58
59 ~ServiceWorkerCacheWriter();
60
61 // Writes the supplied |headers| back to the cache. Returns ERR_IO_PENDING if
62 // the write will complete asynchronously, in which case |callback| will be
63 // called when it completes. Otherwise, returns a code other than
64 // ERR_IO_PENDING and does not invoke |callback|. Note that this method will
65 // not necessarily write data back to the cache if the incoming data is
66 // equivalent to the existing cached data. See the source of this function for
67 // details about how this function drives the state machine.
68 net::Error MaybeWriteHeaders(HttpResponseInfoIOBuffer* headers,
69 const OnWriteCompleteCallback& callback);
70
71 // Writes the supplied body data |data| back to the cache. Returns
72 // ERR_IO_PENDING if the write will complete asynchronously, in which case
73 // |callback| will be called when it completes. Otherwise, returns a code
74 // other than ERR_IO_PENDING and does not invoke |callback|. Note that this
75 // method will not necessarily write data back to the cache if the incoming
76 // data is equivalent to the existing cached data. See the source of this
77 // function for details about how this function drives the state machine.
78 net::Error MaybeWriteData(net::IOBuffer* buf,
79 size_t buf_size,
80 const OnWriteCompleteCallback& callback);
81
82 // Returns a count of bytes written back to the cache.
83 size_t bytes_written() const { return bytes_written_; }
84 bool did_replace() const { return did_replace_; }
85
86 private:
87 // States for the state machine.
88 //
89 // The state machine flows roughly like this: if there is no existing cache
90 // entry, incoming headers and data are written directly back to the cache
91 // ("passthrough mode", the PASSTHROUGH states). If there is an existing cache
92 // entry, incoming headers and data are compared to the existing cache entry
93 // ("compare mode", the COMPARE states); if at any point the incoming
94 // headers/data are not equal to the cached headers/data, this class copies
95 // the cached data up to the point where the incoming data and the cached data
96 // diverged ("copy mode", the COPY states), then switches to "passthrough
97 // mode" to write the remainder of the incoming data. The overall effect is to
98 // avoid rewriting the cache entry if the incoming data is identical to the
99 // cached data.
100 //
101 // Note that after a call to MaybeWriteHeaders or MaybeWriteData completes,
102 // the machine is always in STATE_DONE, indicating that the call is finished;
103 // those methods are responsible for setting a new initial state.
104 enum State {
105 STATE_START,
106 // Control flows linearly through these four states, then loops from
107 // READ_DATA_FOR_COMPARE_DONE to READ_DATA_FOR_COMPARE, or exits to
108 // READ_HEADERS_FOR_COPY.
109 STATE_READ_HEADERS_FOR_COMPARE,
110 STATE_READ_HEADERS_FOR_COMPARE_DONE,
111 STATE_READ_DATA_FOR_COMPARE,
112 STATE_READ_DATA_FOR_COMPARE_DONE,
113
114 // Control flows linearly through these states, with each pass from
115 // READ_DATA_FOR_COPY to WRITE_DATA_FOR_COPY_DONE copying one block of data
116 // at a time. Control loops from WRITE_DATA_FOR_COPY_DONE back to
117 // READ_DATA_FOR_COPY if there is more data to copy, or exits to
118 // WRITE_DATA_FOR_PASSTHROUGH.
119 STATE_READ_HEADERS_FOR_COPY,
120 STATE_READ_HEADERS_FOR_COPY_DONE,
121 STATE_WRITE_HEADERS_FOR_COPY,
122 STATE_WRITE_HEADERS_FOR_COPY_DONE,
123 STATE_READ_DATA_FOR_COPY,
124 STATE_READ_DATA_FOR_COPY_DONE,
125 STATE_WRITE_DATA_FOR_COPY,
126 STATE_WRITE_DATA_FOR_COPY_DONE,
127
128 // Control flows linearly through these states, with a loop between
129 // WRITE_DATA_FOR_PASSTHROUGH and WRITE_DATA_FOR_PASSTHROUGH_DONE.
130 STATE_WRITE_HEADERS_FOR_PASSTHROUGH,
131 STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE,
132 STATE_WRITE_DATA_FOR_PASSTHROUGH,
133 STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE,
134
135 // This state means "done with the current call; ready for another one."
136 STATE_DONE,
137 };
138
139 // Drives this class's state machine. This function steps the state machine
140 // until one of:
141 // a) One of the state functions returns an error
142 // b) The state machine reaches STATE_DONE
143 // A successful value (net::OK or greater) indicates that the requested
144 // operation completed synchronously. A return value of ERR_IO_PENDING
145 // indicates that some step had to submit asynchronous IO for later
146 // completion, and the state machine will resume running (via AsyncDoLoop)
147 // when that asynchronous IO completes. Any other return value indicates that
148 // the requested operation failed synchronously.
149 int DoLoop(int result);
150
151 // State handlers. See function comments in the corresponding source file for
152 // details on these.
153 int DoStart(int result);
154 int DoReadHeadersForCompare(int result);
155 int DoReadHeadersForCompareDone(int result);
156 int DoReadDataForCompare(int result);
157 int DoReadDataForCompareDone(int result);
158 int DoReadHeadersForCopy(int result);
159 int DoReadHeadersForCopyDone(int result);
160 int DoWriteHeadersForCopy(int result);
161 int DoWriteHeadersForCopyDone(int result);
162 int DoReadDataForCopy(int result);
163 int DoReadDataForCopyDone(int result);
164 int DoWriteDataForCopy(int result);
165 int DoWriteDataForCopyDone(int result);
166 int DoWriteHeadersForPassthrough(int result);
167 int DoWriteHeadersForPassthroughDone(int result);
168 int DoWriteDataForPassthrough(int result);
169 int DoWriteDataForPassthroughDone(int result);
170 int DoDone(int result);
171
172 // Wrappers for asynchronous calls. These are responsible for scheduling a
173 // callback to drive the state machine if needed. These either:
174 // a) Return ERR_IO_PENDING, and schedule a callback to run the state
175 // machine's Run() later, or
176 // b) Return some other value and do not schedule a callback.
177 int ReadInfoHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader,
178 HttpResponseInfoIOBuffer* buf);
179 int ReadDataHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader,
180 net::IOBuffer* buf,
181 int buf_len);
182 int WriteInfoHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer,
183 HttpResponseInfoIOBuffer* buf);
184 int WriteDataHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer,
185 net::IOBuffer* buf,
186 int buf_len);
187
188 // Callback used by the above helpers for their IO operations. This is only
189 // run when those IO operations complete asynchronously, in which case it
190 // invokes the synchronous DoLoop function and runs the client callback (the
191 // one passed into MaybeWriteData/MaybeWriteHeaders) if that invocation
192 // of DoLoop completes synchronously.
193 void AsyncDoLoop(int result);
194
195 State state_;
196 // Note that this variable is only used for assertions; it reflects "state !=
197 // DONE && not in synchronous DoLoop".
198 bool io_pending_;
199 bool comparing_;
200
201 scoped_refptr<HttpResponseInfoIOBuffer> headers_to_read_;
202 scoped_refptr<HttpResponseInfoIOBuffer> headers_to_write_;
203 scoped_refptr<net::IOBuffer> data_to_read_;
204 int len_to_read_;
205 scoped_refptr<net::IOBuffer> data_to_copy_;
206 scoped_refptr<net::IOBuffer> data_to_write_;
207 int len_to_write_;
208 OnWriteCompleteCallback pending_callback_;
209
210 size_t cached_length_;
211
212 size_t bytes_compared_;
213 size_t bytes_copied_;
214 size_t bytes_written_;
215
216 bool did_replace_;
217
218 size_t compare_offset_;
219
220 ResponseReaderCreator reader_creator_;
221 ResponseWriterCreator writer_creator_;
222 scoped_ptr<ServiceWorkerResponseReader> compare_reader_;
223 scoped_ptr<ServiceWorkerResponseReader> copy_reader_;
224 scoped_ptr<ServiceWorkerResponseWriter> writer_;
225 base::WeakPtrFactory<ServiceWorkerCacheWriter> weak_factory_;
226 };
227
228 } // namespace content
229
230 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_
OLDNEW
« no previous file with comments | « content/browser/appcache/appcache_response.h ('k') | content/browser/service_worker/service_worker_cache_writer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698