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

Side by Side Diff: net/http/http_cache_writers.h

Issue 2886483002: Adds a new class HttpCache::Writers for multiple cache transactions reading from the network. (Closed)
Patch Set: Feedback addressed Created 3 years, 6 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 (c) 2017 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 NET_HTTP_HTTP_CACHE_WRITERS_H_
6 #define NET_HTTP_HTTP_CACHE_WRITERS_H_
7 #include <list>
jkarlin 2017/06/12 18:30:32 newline above
shivanisha 2017/06/14 02:33:17 Added
8 #include <memory>
9 #include "base/memory/weak_ptr.h"
jkarlin 2017/06/12 18:30:32 newline above
shivanisha 2017/06/14 02:33:17 added
10 #include "net/base/completion_callback.h"
11 #include "net/http/http_cache.h"
12
13 // If multiple HttpCache::Transactions are accessing the same cache entry
14 // simultaneously, their access to the data read from network is synchronized
15 // by HttpCache::Writers. This enables each of those transactions to drive
16 // reading the response body from the network ensuring a slow consumer does not
17 // starve other consumers of the same resource.
18
19 namespace net {
20
21 // Writer represents the set of all HttpCache::Transactions that are
22 // reading from the network using the same network transaction and writing to
23 // the same cache entry. It is owned by the ActiveEntry.
24 class NET_EXPORT_PRIVATE HttpCache::Writers {
25 public:
26 // |*entry| and |*cache| must outlive this object.
27 Writers(HttpCache* cache, ActiveEntry* entry);
28 ~Writers();
29
30 // Retrieves data from the network transaction associated with the Writers
31 // object. This may be done directly (via a network read into |*buf->data()|)
32 // or indirectly (by copying from another transactions buffer into
33 // |*buf->data()| on network read completion) depending on whether or not a
34 // read is currently in progress. May return the result synchronously or
35 // return ERR_IO_PENDING: if ERR_IO_PENDING is returned, |callback| will be
36 // run to inform the consumer of the result of the Read().
37 int Read(scoped_refptr<IOBuffer> buf,
38 int buf_len,
39 const CompletionCallback& callback,
40 Transaction* transaction);
41
42 // Invoked when StopCaching is called on a member transaction.
43 // It stops caching only if there are no other transactions. Returns true if
44 // caching can be stopped.
45 bool StopCaching(Transaction* transaction);
46
47 // Membership functions.
48
49 // Adds an HttpCache::Transaction to Writers and if its the first transaction
jkarlin 2017/06/12 18:30:32 s/its/it's/
shivanisha 2017/06/14 02:33:17 done
50 // added, transfers the ownership of the network transaction to Writers.
51 // Should only be invoked if CanAddTransaction() returns true.
52 // |network_transaction| should be non-null only for the first transaction
53 // and it will be assigned to |network_transaction_|. If |is_exclusive| is
54 // true, it makes writing an exclusine operation implying that Writers can
Randy Smith (Not in Mondays) 2017/06/08 17:10:01 nit: exclusive
shivanisha 2017/06/12 18:51:14 done
55 // contain at most one transaction till the completion of the response body.
56 // |transaction| can be destroyed at any point and it should invoke
57 // RemoveTransaction() during its destruction.
58 void AddTransaction(Transaction* transaction,
59 std::unique_ptr<HttpTransaction> network_transaction,
60 bool is_exclusive);
Randy Smith (Not in Mondays) 2017/06/08 17:10:01 The current implementation requires the consumer t
shivanisha 2017/06/12 18:51:14 ok, let's come back to this in the integration CL
61
62 // Removes a transaction.
63 void RemoveTransaction(Transaction* transaction);
64
65 // Invoked when there is a change in a member transaction's priority or a
66 // member transaction is removed.
67 void PriorityChanged();
68
69 // Returns true if this object is empty.
70 bool IsEmpty() const { return all_writers_.empty(); }
71
72 // Returns true is |transaction| is part of writers.
73 bool IsPresent(Transaction* transaction) const {
74 return all_writers_.count(transaction) > 0;
75 }
76
77 // Returns true if |this| only contains idle writers.
78 bool ContainsOnlyIdleWriters() const;
79
80 // Move any idle writers to entry_->readers. Should only be invoked when a
81 // response is completely written and when ContainesOnlyIdleWriters()
82 // returns true.
83 void MoveIdleWritersToReaders();
84
85 // Returns true if more writers can be added for shared writing.
86 bool CanAddWriters();
87
88 HttpTransaction* network_transaction() { return network_transaction_.get(); }
89
90 // Invoked from HttpCache when it is notified of a transaction failing to
91 // write. |error| indicates network read error code or cache write error.
92 void ProcessFailure(Transaction* transaction, int error);
93
94 // Invoked to mark an entry as truncated.
95 void TruncateEntry();
96
97 // Should be invoked only when writers has transactions attached to it and
98 // thus has a valid network transaction.
99 LoadState GetWriterLoadState();
100
101 // For testing.
102
103 int CountTransactionsForTesting() const { return all_writers_.size(); }
104 bool IsTruncatedForTesting() const { return truncated_; }
105
106 private:
107 enum class State {
108 NONE,
109 NETWORK_READ,
110 NETWORK_READ_COMPLETE,
111 CACHE_WRITE_DATA,
112 CACHE_WRITE_DATA_COMPLETE,
113 CACHE_WRITE_TRUNCATED_RESPONSE,
114 CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE,
115 FAIL_READ
Randy Smith (Not in Mondays) 2017/06/08 17:10:01 My personal preference would be to keep the invari
jkarlin 2017/06/12 18:30:32 +1
shivanisha 2017/06/12 18:51:14 Deferring this comment since the follow up CL anyw
116 };
117
118 // These transactions are waiting on Read. After the active transaction
119 // completes writing the data to the cache, their buffer would be filled with
120 // the data and their callback will be invoked.
121 struct WaitingForRead {
122 Transaction* transaction;
123 scoped_refptr<IOBuffer> read_buf;
124 int read_buf_len;
125 int write_len;
126 const CompletionCallback callback;
127 WaitingForRead(Transaction* transaction,
128 scoped_refptr<IOBuffer> read_buf,
129 int len,
130 const CompletionCallback& consumer_callback);
131 ~WaitingForRead();
132 WaitingForRead(const WaitingForRead&);
133 };
134 using WaitingForReadList = std::list<WaitingForRead>;
135
136 // Runs the state transition loop. Resets and calls |callback_| on exit,
137 // unless the return value is ERR_IO_PENDING.
138 int DoLoop(int result);
139
140 // State machine functions.
141 int DoNetworkRead();
142 int DoNetworkReadComplete(int result);
143 int DoCacheWriteData(int num_bytes);
144 int DoCacheWriteDataComplete(int result);
145 int DoCacheWriteTruncatedResponse();
146 int DoCacheWriteTruncatedResponseComplete(int result);
147
148 // Helper functions for callback.
149
jkarlin 2017/06/12 18:30:32 Remove newline?
shivanisha 2017/06/14 02:33:17 Comment applies to all 3 following functions.
jkarlin 2017/06/14 20:03:14 Right, for group comments I typically see the comm
150 void OnNetworkReadFailure(int result);
151 void OnCacheWriteFailure();
152 void OnDataReceived(int result);
153
154 // Helper function for writing to cache.
155 int WriteToEntry(int offset,
156 IOBuffer* data,
157 int data_len,
158 const CompletionCallback& callback);
159
160 // Notifies the transactions waiting on Read of the result, by posting a task
161 // for each of them.
162 void ProcessWaitingForReadTransactions(int result);
163
164 // Sets the state to FAIL_READ so that any subsequent Read on an idle
165 // transaction fails.
166 void SetIdleWritersFailState(int result);
167
168 // Called to reset state when all transaction references are removed from
169 // |this|.
170 void ResetStateForEmptyWriters();
171
172 // IO Completion callback function.
173 void OnIOComplete(int result);
174
175 State next_state_ = State::NONE;
176
177 // True if only reading from network and not writing to cache.
178 bool network_read_only_ = false;
179
180 // Http Cache.
181 HttpCache* cache_ = nullptr;
182
183 // Owner of this object.
184 ActiveEntry* entry_ = nullptr;
185
186 std::unique_ptr<HttpTransaction> network_transaction_ = nullptr;
187
188 scoped_refptr<IOBuffer> read_buf_ = nullptr;
189
190 int io_buf_len_ = 0;
191 int write_len_ = 0;
192
193 // The cache transaction that is the current consumer of network_transaction_
194 // ::Read or writing to the entry and is waiting for the operation to be
195 // completed. This is used to ensure there is at most one consumer of
196 // network_transaction_ at a time.
197 Transaction* active_transaction_ = nullptr;
198
199 // Transactions whose consumers have invoked Read, but another transaction is
200 // currently the |active_transaction_|. After the network read and cache write
201 // is complete, the waiting transactions will be notified.
202 WaitingForReadList waiting_for_read_;
203
204 // Includes all transactions.
205 TransactionSet all_writers_;
206
207 // True if multiple transactions are not allowed e.g. for partial requests.
208 bool is_exclusive_ = false;
209
210 // Current priority of the request. It is always the maximum of all the writer
211 // transactions.
212 RequestPriority priority_ = MINIMUM_PRIORITY;
213
214 // Error to be returned on a future Read when state is FAIL_READ.
215 int error_code_ = 0;
216
217 bool truncated_ = false; // used for testing.
218
219 CompletionCallback callback_; // Callback for active_transaction_.
220
221 base::WeakPtrFactory<Writers> weak_factory_;
222 DISALLOW_COPY_AND_ASSIGN(Writers);
223 };
224
225 } // namespace net
226 #endif // NET_HTTP_HTTP_CACHE_WRITERS_H_
jkarlin 2017/06/12 18:30:32 newline above
shivanisha 2017/06/14 02:33:17 Added
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698