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

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: Fix test class memory leak Created 3 years, 5 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
8 #include <list>
9 #include <memory>
10
11 #include "base/memory/weak_ptr.h"
12 #include "net/base/completion_callback.h"
13 #include "net/http/http_cache.h"
14
15 // If multiple HttpCache::Transactions are accessing the same cache entry
16 // simultaneously, their access to the data read from network is synchronized
17 // by HttpCache::Writers. This enables each of those transactions to drive
18 // reading the response body from the network ensuring a slow consumer does not
19 // starve other consumers of the same resource.
jkarlin 2017/06/28 15:50:10 This should be a part of the HttpCache::Writers co
shivanisha 2017/06/28 19:38:20 moved
20
21 namespace net {
22
23 // Writer represents the set of all HttpCache::Transactions that are
jkarlin 2017/06/28 15:50:10 s/Writer/Writers/
shivanisha 2017/06/28 19:38:20 done
24 // reading from the network using the same network transaction and writing to
25 // the same cache entry. It is owned by the ActiveEntry.
26 class NET_EXPORT_PRIVATE HttpCache::Writers {
27 public:
28 friend class WritersTest;
Randy Smith (Not in Mondays) 2017/06/27 18:49:37 nit, suggestion: I'm used to seeing friend declara
jkarlin 2017/06/28 15:50:10 newline after the friend declaration
shivanisha 2017/06/28 18:02:33 moved to private section
29 // |*disk_entry| must outlive this object.
30 Writers(disk_cache::Entry* entry);
31 ~Writers();
32
33 // Retrieves data from the network transaction associated with the Writers
34 // object. This may be done directly (via a network read into |*buf->data()|)
35 // or indirectly (by copying from another transactions buffer into
36 // |*buf->data()| on network read completion) depending on whether or not a
37 // read is currently in progress. May return the result synchronously or
38 // return ERR_IO_PENDING: if ERR_IO_PENDING is returned, |callback| will be
39 // run to inform the consumer of the result of the Read().
jkarlin 2017/06/28 15:50:09 Comment doesn't make it clear what happens if Writ
shivanisha 2017/06/28 19:38:20 It will not be invoked. Added in the comment
40 int Read(scoped_refptr<IOBuffer> buf,
41 int buf_len,
42 const CompletionCallback& callback,
43 Transaction* transaction);
44
45 // Invoked when StopCaching is called on a member transaction.
46 // It stops caching only if there are no other transactions. Returns true if
jkarlin 2017/06/28 15:50:10 If there are two simultaneous downloads of the sam
shivanisha 2017/06/28 19:38:20 That's right
jkarlin 2017/06/30 18:20:39 This needs to be clearly documented in HttpTransac
shivanisha 2017/07/05 18:55:42 Yes, will document it in the integration CL. Added
47 // caching can be stopped.
48 bool StopCaching(Transaction* transaction);
49
50 // Membership functions.
jkarlin 2017/06/28 15:50:09 Where does the scope of this comment end? I doubt
shivanisha 2017/06/28 19:38:20 Removed
51
52 // Adds an HttpCache::Transaction to Writers and if it's the first transaction
53 // added, transfers the ownership of the network transaction to Writers.
54 // Should only be invoked if CanAddTransaction() returns true.
jkarlin 2017/06/28 15:50:09 Do you mean CanAddWriters?
shivanisha 2017/06/28 19:38:20 yes, updated
55 // |network_transaction| should be non-null only for the first transaction
56 // and it will be assigned to |network_transaction_|. If |is_exclusive| is
57 // true, it makes writing an exclusive operation implying that Writers can
58 // contain at most one transaction till the completion of the response body.
59 // |transaction| can be destroyed at any point and it should invoke
jkarlin 2017/06/28 15:50:09 Should the last line read: Call RemoveTransaction
shivanisha 2017/06/28 19:38:20 The existing statement is conveying the same meani
60 // RemoveTransaction() during its destruction.
61 void AddTransaction(Transaction* transaction,
62 std::unique_ptr<HttpTransaction> network_transaction,
63 bool is_exclusive);
64
65 // Removes a transaction.
66 void RemoveTransaction(Transaction* transaction);
jkarlin 2017/06/28 15:50:09 When can this be called?
shivanisha 2017/06/28 19:38:20 Anytime a transaction is destroyed.Added
67
68 // Invoked when there is a change in a member transaction's priority or a
69 // member transaction is removed.
70 void UpdatePriority();
71
72 // Returns true if this object is empty.
73 bool IsEmpty() const { return all_writers_.empty(); }
74
75 // Returns true is |transaction| is part of writers.
76 bool IsPresent(Transaction* transaction) const {
jkarlin 2017/06/28 15:50:09 suggest s/IsPresent/HasTransaction/
shivanisha 2017/06/28 19:38:20 done
77 return all_writers_.count(transaction) > 0;
78 }
79
80 // Remove and return any idle writers. Should only be invoked when a
81 // response is completely written and when ContainesOnlyIdleWriters()
82 // returns true.
83 TransactionSet RemoveAllIdleWriters();
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(); }
jkarlin 2017/06/28 15:50:09 Interesting, who would need to call this function?
shivanisha 2017/06/28 19:38:20 HC::T might. If not, I will remove it from the int
89
90 // Invoked to mark an entry as truncated.
91 void TruncateEntry();
jkarlin 2017/06/28 15:50:09 When can this be called? Even if a Read() is ongoi
shivanisha 2017/06/28 19:38:20 No, it has a dcheck to assert that
jkarlin 2017/06/30 18:20:39 Please update the comment to reflect when it can b
shivanisha 2017/07/05 18:55:42 done
92
93 // Should be invoked only when writers has transactions attached to it and
94 // thus has a valid network transaction.
95 LoadState GetWriterLoadState();
96
97 // For testing.
98
jkarlin 2017/06/28 15:50:09 Remove newline.
shivanisha 2017/06/28 19:38:20 done
99 int CountTransactionsForTesting() const { return all_writers_.size(); }
jkarlin 2017/06/28 15:50:09 Are the ForTesting functions necessary? This class
shivanisha 2017/06/28 19:38:20 The compiler still gives an error if private membe
100 bool IsTruncatedForTesting() const { return truncated_; }
101
102 private:
103 enum class State {
104 NONE,
105 NETWORK_READ,
106 NETWORK_READ_COMPLETE,
107 CACHE_WRITE_DATA,
108 CACHE_WRITE_DATA_COMPLETE,
109 CACHE_WRITE_TRUNCATED_RESPONSE,
110 CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE,
111 };
112
113 // These transactions are waiting on Read. After the active transaction
114 // completes writing the data to the cache, their buffer would be filled with
115 // the data and their callback will be invoked.
116 struct WaitingForRead {
117 Transaction* transaction;
118 scoped_refptr<IOBuffer> read_buf;
119 int read_buf_len;
120 int write_len;
121 const CompletionCallback callback;
122 WaitingForRead(Transaction* transaction,
123 scoped_refptr<IOBuffer> read_buf,
124 int len,
125 const CompletionCallback& consumer_callback);
126 ~WaitingForRead();
127 WaitingForRead(const WaitingForRead&);
128 };
129 using WaitingForReadList = std::list<WaitingForRead>;
130
131 // Runs the state transition loop. Resets and calls |callback_| on exit,
132 // unless the return value is ERR_IO_PENDING.
133 int DoLoop(int result);
134
135 // State machine functions.
136 int DoNetworkRead();
137 int DoNetworkReadComplete(int result);
138 int DoCacheWriteData(int num_bytes);
139 int DoCacheWriteDataComplete(int result);
140 int DoCacheWriteTruncatedResponse();
141 int DoCacheWriteTruncatedResponseComplete(int result);
142
143 // Helper functions for callback.
144
145 void OnNetworkReadFailure(int result);
146 void OnCacheWriteFailure();
147 void OnDataReceived(int result);
148
149 // Notifies the transactions waiting on Read of the result, by posting a task
150 // for each of them.
151 void ProcessWaitingForReadTransactions(int result);
152
153 // Sets the state to FAIL_READ so that any subsequent Read on an idle
154 // transaction fails.
155 void SetIdleWritersFailState(int result);
156
157 // Called to reset state when all transaction references are removed from
158 // |this|.
159 void ResetStateForEmptyWriters();
160
161 // Invoked when |active_transaction_| fails to read from network or write to
162 // cache. |error| indicates network read error code or cache write error.
163 void ProcessFailure(Transaction* transaction, int error);
164
165 // Returns true if |this| only contains idle writers.
166 bool ContainsOnlyIdleWriters() const;
167
168 // IO Completion callback function.
169 void OnIOComplete(int result);
170
171 State next_state_ = State::NONE;
172
173 // True if only reading from network and not writing to cache.
174 bool network_read_only_ = false;
175
176 // TODO(shivanisha) Add HttpCache* cache_ = nullptr; on integration.
177
178 disk_cache::Entry* disk_entry_ = nullptr;
179
180 std::unique_ptr<HttpTransaction> network_transaction_ = nullptr;
181
182 scoped_refptr<IOBuffer> read_buf_ = nullptr;
183
184 int io_buf_len_ = 0;
185 int write_len_ = 0;
186
187 // The cache transaction that is the current consumer of network_transaction_
188 // ::Read or writing to the entry and is waiting for the operation to be
189 // completed. This is used to ensure there is at most one consumer of
190 // network_transaction_ at a time.
191 Transaction* active_transaction_ = nullptr;
192
193 // Transactions whose consumers have invoked Read, but another transaction is
194 // currently the |active_transaction_|. After the network read and cache write
195 // is complete, the waiting transactions will be notified.
196 WaitingForReadList waiting_for_read_;
197
198 // Includes all transactions. ResetStateForEmptyWriters should be invoked
199 // whenever all_writers_ becomes empty.
200 TransactionSet all_writers_;
201
202 // True if multiple transactions are not allowed e.g. for partial requests.
203 bool is_exclusive_ = false;
204
205 // Current priority of the request. It is always the maximum of all the writer
206 // transactions.
207 RequestPriority priority_ = MINIMUM_PRIORITY;
208
209 bool truncated_ = false; // used for testing.
210
211 CompletionCallback callback_; // Callback for active_transaction_.
212
213 base::WeakPtrFactory<Writers> weak_factory_;
214 DISALLOW_COPY_AND_ASSIGN(Writers);
215 };
216
217 } // namespace net
218
219 #endif // NET_HTTP_HTTP_CACHE_WRITERS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698