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

Side by Side Diff: net/url_request/request_tracker.h

Issue 848006: Generalize the net module's LoadLog facility from a passive container, to an event stream (NetLog). (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Split up RequestTracker into ConnectJobTracker+RequestTracker+RequestTrackerBase, address comments Created 10 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_stream.cc ('k') | net/url_request/request_tracker_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2009 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_URL_REQUEST_REQUEST_TRACKER_H_
6 #define NET_URL_REQUEST_REQUEST_TRACKER_H_
7
8 #include <vector>
9
10 #include "base/ref_counted.h"
11 #include "base/linked_list.h"
12 #include "base/logging.h"
13 #include "googleurl/src/gurl.h"
14 #include "net/base/load_log.h"
15
16 // Class to track all of the live instances of Request associated with a
17 // particular URLRequestContext. It keeps a circular queue of the LoadLogs
18 // for recently deceased requests.
19 template<typename Request>
20 class RequestTracker {
21 public:
22 struct RecentRequestInfo {
23 GURL original_url;
24 scoped_refptr<net::LoadLog> load_log;
25 };
26
27 // Helper class to make Request insertable into a base::LinkedList,
28 // without making the public interface expose base::LinkNode.
29 class Node : public base::LinkNode<Node> {
30 public:
31 Node(Request* request) : request_(request) {}
32 ~Node() {}
33
34 Request* request() const { return request_; }
35
36 private:
37 Request* request_;
38 };
39
40 typedef std::vector<RecentRequestInfo> RecentRequestInfoList;
41 typedef bool (*RecentRequestsFilterFunc)(const GURL&);
42
43 // The maximum number of entries for |graveyard_|, when in bounded mode.
44 static const size_t kMaxGraveyardSize;
45
46 // The maximum size of URLs to stuff into RecentRequestInfo, when in bounded
47 // mode.
48 static const size_t kMaxGraveyardURLSize;
49
50 // The maximum number of entries to use for LoadLogs when in bounded mode.
51 static const size_t kBoundedLoadLogMaxEntries;
52
53 RequestTracker()
54 : next_graveyard_index_(0),
55 graveyard_filter_func_(NULL),
56 is_unbounded_(false) {
57 }
58
59 ~RequestTracker() {}
60
61 // Returns a list of Requests that are alive.
62 std::vector<Request*> GetLiveRequests() {
63 std::vector<Request*> list;
64 for (base::LinkNode<Node>* node = live_instances_.head();
65 node != live_instances_.end();
66 node = node->next()) {
67 Request* request = node->value()->request();
68 list.push_back(request);
69 }
70 return list;
71 }
72
73 // Clears the circular buffer of RecentRequestInfos.
74 void ClearRecentlyDeceased() {
75 next_graveyard_index_ = 0;
76 graveyard_.clear();
77 }
78
79 // Returns a list of recently completed Requests.
80 const RecentRequestInfoList GetRecentlyDeceased() {
81 RecentRequestInfoList list;
82
83 // Copy the items from |graveyard_| (our circular queue of recently
84 // deceased request infos) into a vector, ordered from oldest to newest.
85 for (size_t i = 0; i < graveyard_.size(); ++i) {
86 size_t index = (next_graveyard_index_ + i) % graveyard_.size();
87 list.push_back(graveyard_[index]);
88 }
89 return list;
90 }
91
92 void Add(Request* request) {
93 live_instances_.Append(&request->request_tracker_node_);
94 }
95
96 void Remove(Request* request) {
97 // Remove from |live_instances_|.
98 request->request_tracker_node_.RemoveFromList();
99
100 RecentRequestInfo info;
101 request->GetInfoForTracker(&info);
102
103 if (!is_unbounded_) {
104 // Paranoia check: truncate |info.original_url| if it is really big.
105 const std::string& spec = info.original_url.possibly_invalid_spec();
106 if (spec.size() > kMaxGraveyardURLSize)
107 info.original_url = GURL(spec.substr(0, kMaxGraveyardURLSize));
108 }
109
110 if (ShouldInsertIntoGraveyard(info)) {
111 // Add into |graveyard_|.
112 InsertIntoGraveyard(info);
113 }
114 }
115
116 // This function lets you exclude requests from being saved to the graveyard.
117 // The graveyard is a circular buffer of the most recently completed
118 // requests. Pass NULL turn off filtering. Otherwise pass in a function
119 // returns false to exclude requests, true otherwise.
120 void SetGraveyardFilter(RecentRequestsFilterFunc filter_func) {
121 graveyard_filter_func_ = filter_func;
122 }
123
124 bool IsUnbounded() const {
125 return is_unbounded_;
126 }
127
128 void SetUnbounded(bool unbounded) {
129 // No change.
130 if (is_unbounded_ == unbounded)
131 return;
132
133 // If we are going from unbounded to bounded, we need to trim the
134 // graveyard. For simplicity we will simply clear it.
135 if (is_unbounded_ && !unbounded)
136 ClearRecentlyDeceased();
137
138 is_unbounded_ = unbounded;
139 }
140
141 // Creates a LoadLog using the unbounded/bounded constraints that
142 // apply to this tracker.
143 net::LoadLog* CreateLoadLog() {
144 if (IsUnbounded())
145 return new net::LoadLog(net::LoadLog::kUnbounded);
146 return new net::LoadLog(kBoundedLoadLogMaxEntries);
147 }
148
149 private:
150 bool ShouldInsertIntoGraveyard(const RecentRequestInfo& info) {
151 if (!graveyard_filter_func_)
152 return true;
153 return graveyard_filter_func_(info.original_url);
154 }
155
156 void InsertIntoGraveyard(const RecentRequestInfo& info) {
157 if (is_unbounded_) {
158 graveyard_.push_back(info);
159 return;
160 }
161
162 // Otherwise enforce a bound on the graveyard size, by treating it as a
163 // circular buffer.
164 if (graveyard_.size() < kMaxGraveyardSize) {
165 // Still growing to maximum capacity.
166 DCHECK_EQ(next_graveyard_index_, graveyard_.size());
167 graveyard_.push_back(info);
168 } else {
169 // At maximum capacity, overwite the oldest entry.
170 graveyard_[next_graveyard_index_] = info;
171 }
172 next_graveyard_index_ = (next_graveyard_index_ + 1) % kMaxGraveyardSize;
173 }
174
175 base::LinkedList<Node> live_instances_;
176
177 size_t next_graveyard_index_;
178 RecentRequestInfoList graveyard_;
179 RecentRequestsFilterFunc graveyard_filter_func_;
180 bool is_unbounded_;
181 };
182
183 template<typename Request>
184 const size_t RequestTracker<Request>::kMaxGraveyardSize = 25;
185
186 template<typename Request>
187 const size_t RequestTracker<Request>::kMaxGraveyardURLSize = 1000;
188
189 template<typename Request>
190 const size_t RequestTracker<Request>::kBoundedLoadLogMaxEntries = 50;
191
192 #endif // NET_URL_REQUEST_REQUEST_TRACKER_H_
OLDNEW
« no previous file with comments | « net/spdy/spdy_stream.cc ('k') | net/url_request/request_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698