OLD | NEW |
---|---|
(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> | |
8 #include <memory> | |
9 #include "base/memory/weak_ptr.h" | |
10 #include "net/base/completion_callback.h" | |
11 #include "net/http/http_cache.h" | |
12 | |
13 // Multiple transactions reading from the network and writing to the cache | |
14 // enables each of those transactions to drive reading the response body from | |
15 // the network. This ensures that a slow consumer does not starve other | |
16 // consumers of the same resource. A shared transaction will either read the | |
17 // already written part of the response from the cache or invoke read on the | |
18 // network and write to the cache, depending on its read offset. | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:28
I'm having a hard time understanding this comment
shivanisha
2017/05/17 13:02:30
Sounds good. Updated the comment.
| |
19 | |
20 namespace net { | |
21 | |
22 // Writer represents the set of all HttpCache::Transactions that are | |
23 // reading from the network using the same network transaction and writing to | |
24 // the same cache entry. It is owned by the ActiveEntry. | |
25 class HttpCache::Writers { | |
26 public: | |
27 // Creates a new Writers object and transfers the ownership of network | |
28 // transaction to Writers. Consumer must ensure that |*entry| and | |
29 // |*cache| outlive |this|. | |
30 Writers(base::WeakPtr<HttpCache> cache, ActiveEntry* entry); | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:29
Two questions:
a) How can this transfer a network
shivanisha
2017/05/17 13:02:30
a) Removed that part of the comment. Was a remnant
| |
31 ~Writers(); | |
32 | |
33 // Invokes Read on network transaction if a read is not already in progress. | |
34 // In case a read is already in progress then this transaction is added to | |
35 // a waiting queue and ERR_IO_PENDING is returned. If ERR_IO_PENDING is | |
36 // returned, the result of the read will be later communicated to the consumer | |
37 // via the |callback|. | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:29
Given that the offset in the object was mentioned
shivanisha
2017/05/17 13:02:30
Removed the reference to offset in the above comme
| |
38 int Read(scoped_refptr<IOBuffer> buf, | |
39 int buf_len, | |
40 const CompletionCallback& callback, | |
41 Transaction* transaction); | |
42 | |
43 // Invoked when StopCaching is called on a member transaction. | |
44 // It stops caching only if there are no other transactions. Returns true if | |
45 // caching can be stopped. | |
46 bool StopCaching(Transaction* transaction); | |
47 | |
48 // Membership functions. | |
49 | |
50 // Adds a transaction to Writers. Should only be invoked if | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:28
nit: I believe this only adds HttpCache::Transacti
shivanisha
2017/05/17 13:02:30
Done
| |
51 // CanAddTransaction() returns true. If network_transaction is non-null, it | |
52 // will be assigned to network_transaction_. The first transaction added | |
53 // should definitely pass a non-null network transaction. It is ok for | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:28
This seems contradictory with the constructor comm
shivanisha
2017/05/17 13:02:30
Constructor comment corrected.
| |
54 // |transaction| to die before this object. | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:29
Leaving the object with an invalid raw pointer? T
shivanisha
2017/05/17 13:02:30
Updated the comment to include RemoveTransaction r
| |
55 void AddTransaction(Transaction* transaction, | |
56 HttpTransaction* network_transaction); | |
57 | |
58 // Removes a transaction. | |
59 void RemoveTransaction(Transaction* transaction); | |
60 | |
61 // Removes all transactions. | |
62 void RemoveAllTransactions(); | |
63 | |
64 // Invoked when there is a change in a member transaction's priority or a | |
65 // member transaction is removed. | |
66 void PriorityChanged(); | |
67 | |
68 // Returns true if this object is empty. | |
69 bool IsEmpty() { return all_writers_.empty(); } | |
70 | |
71 // Returns true is |transaction| is part of writers. | |
72 bool IsPresent(Transaction* transaction) { | |
73 return all_writers_.count(transaction) > 0; | |
74 } | |
75 | |
76 // When response is completely written, any idle writers are moved to | |
77 // entry_->readers. | |
78 void MoveIdleWritersToReaders(); | |
79 | |
80 // Set exclusive as true. | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:29
This doesn't actually describe the behavior that t
shivanisha
2017/05/17 13:02:30
Done
| |
81 void SetExclusive() { is_exclusive_ = true; } | |
82 | |
83 // Returns true if more writers can be added for shared writing. | |
84 bool CanAddWriters(); | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:29
Is this a const function?
More generally, for sta
shivanisha
2017/05/17 13:02:31
Made a few functions as const. Thanks
| |
85 | |
86 HttpTransaction* network_transaction() { return network_transaction_.get(); } | |
87 | |
88 // Invoked from HttpCache when it is notified of a transaction failing to | |
89 // write. |error| indicates network read error code or cache write error. | |
90 void ProcessFailure(Transaction* transaction, int error); | |
91 | |
92 // Invoked to mark an entry as truncated. | |
93 void TruncateEntry(); | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:29
The fact that the implementation of this involves
shivanisha
2017/05/17 13:02:30
Documented and also added a DCHECK that state shou
Randy Smith (Not in Mondays)
2017/05/18 01:02:54
Can that be done as a conditional inside of Remove
shivanisha
2017/05/19 13:49:57
RemoveTransaction() will be called as soon as the
| |
94 | |
95 LoadState GetWriterLoadState(); | |
96 | |
97 // For testing. | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:29
nit: Test functions usually have "ForTesting" suff
shivanisha
2017/05/17 13:02:30
Added the suffix.
| |
98 int CountTransactions() { return all_writers_.size(); } | |
99 bool IsTruncated() { return truncated_; } | |
100 | |
101 private: | |
102 enum class State { | |
103 NONE, | |
104 NETWORK_READ, | |
105 NETWORK_READ_COMPLETE, | |
106 CACHE_WRITE_DATA, | |
107 CACHE_WRITE_DATA_COMPLETE, | |
108 CACHE_WRITE_TRUNCATED_RESPONSE, | |
109 CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE, | |
110 }; | |
111 | |
112 // These transactions are waiting on Read. After the active transaction | |
113 // completes writing the data to the cache, their buffer would be filled with | |
114 // the data and their callback will be invoked. | |
115 struct WaitingForRead { | |
116 Transaction* transaction; | |
117 scoped_refptr<IOBuffer> read_buf; | |
118 int read_buf_len; | |
119 int write_len; | |
120 const CompletionCallback callback; | |
121 WaitingForRead(Transaction* transaction, | |
122 scoped_refptr<IOBuffer> read_buf, | |
123 int len, | |
124 const CompletionCallback& consumer_callback); | |
125 ~WaitingForRead(); | |
126 WaitingForRead(const WaitingForRead&); | |
127 }; | |
128 using WaitingForReadList = std::list<WaitingForRead>; | |
129 | |
130 // Runs the state transition loop. Resets and calls |callback_| on exit, | |
131 // unless the return value is ERR_IO_PENDING. | |
132 int DoLoop(int result); | |
133 | |
134 // State machine functions. | |
135 int DoNetworkRead(); | |
136 int DoNetworkReadComplete(int result); | |
137 int DoCacheWriteData(int num_bytes); | |
138 int DoCacheWriteDataComplete(int result); | |
139 int DoCacheWriteTruncatedResponse(); | |
140 int DoCacheWriteTruncatedResponseComplete(int result); | |
141 | |
142 // Helper functions for callback. | |
143 | |
144 void OnNetworkReadFailure(int result); | |
145 void OnCacheWriteFailure(); | |
146 void OnDataReceived(int result); | |
147 | |
148 // Helper function for writing to cache. | |
149 int WriteToEntry(int index, | |
150 int offset, | |
151 IOBuffer* data, | |
152 int data_len, | |
153 const CompletionCallback& callback); | |
154 | |
155 // Notifies the transactions waiting on Read of the result, by posting a task | |
156 // for each of them. | |
157 void ProcessWaitingForReadTransactions(int result); | |
158 | |
159 // Sets the state of idle writers so that they can fail any subsequent | |
160 // Read. | |
161 void SetIdleWritersFailState(int result); | |
162 | |
163 RequestPriority getCurrentHighestPriority(); | |
Randy Smith (Not in Mondays)
2017/05/16 22:35:28
nit: I don't think this format is allowed by the s
shivanisha
2017/05/17 13:02:30
Done.
| |
164 | |
165 bool IsResponseCompleted(); | |
166 | |
167 int WriteResponseInfo(bool truncated); | |
168 | |
169 // IO Completion callback function. | |
170 void OnIOComplete(int result); | |
171 | |
172 State next_state_ = State::NONE; | |
173 | |
174 // True if only reading from network and not writing to cache. | |
175 bool network_read_only_ = false; | |
176 | |
177 // Http Cache. | |
178 base::WeakPtr<HttpCache> cache_; | |
179 | |
180 // Owner of this object. | |
181 ActiveEntry* entry_ = nullptr; | |
182 | |
183 std::unique_ptr<HttpTransaction> network_transaction_; | |
184 | |
185 scoped_refptr<IOBuffer> read_buf_; | |
186 | |
187 int io_buf_len_ = 0; | |
188 int write_len_ = 0; | |
189 | |
190 // The cache transaction that is the current consumer of network_transaction_ | |
191 // ::Read or writing to the entry and is waiting for the operation to be | |
192 // completed. This is used to ensure there is at most one consumer of | |
193 // network_transaction_ at a time. | |
194 Transaction* active_transaction_ = nullptr; | |
195 | |
196 // Transactions whose consumers have invoked Read, but another transaction is | |
197 // currently the |active_transaction_|. After the network read and cache write | |
198 // is complete, the waiting transactions will be notified. | |
199 WaitingForReadList waiting_for_read_; | |
200 | |
201 // Includes all transactions. | |
202 TransactionSet all_writers_; | |
203 | |
204 // True if multiple transactions are not allowed e.g. for partial requests. | |
205 bool is_exclusive_ = false; | |
206 | |
207 // Current priority of the request. If a higher priority transaction is | |
208 // added, the priority of network transaction will be increased. | |
209 RequestPriority priority_ = MINIMUM_PRIORITY; | |
210 | |
211 bool truncated_ = false; // used for testing. | |
212 | |
213 CompletionCallback callback_; // Consumer's callback. | |
214 CompletionCallback io_callback_; | |
215 base::WeakPtrFactory<Writers> weak_factory_; | |
216 DISALLOW_COPY_AND_ASSIGN(Writers); | |
217 }; | |
218 | |
219 } // namespace net | |
220 #endif // NET_HTTP_HTTP_CACHE_WRITERS_H_ | |
OLD | NEW |