Chromium Code Reviews| Index: net/reporting/reporting_service.h |
| diff --git a/net/reporting/reporting_service.h b/net/reporting/reporting_service.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0b1991e7334833bc186100a12be489233161070f |
| --- /dev/null |
| +++ b/net/reporting/reporting_service.h |
| @@ -0,0 +1,173 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef NET_REPORTING_REPORTING_SERVICE_H_ |
| +#define NET_REPORTING_REPORTING_SERVICE_H_ |
| + |
| +#include <map> |
| +#include <unordered_set> |
| + |
| +#include "base/callback.h" |
| +#include "base/macros.h" |
| +#include "base/time/tick_clock.h" |
| +#include "base/time/time.h" |
| +#include "base/values.h" |
| +#include "net/base/backoff_entry.h" |
| +#include "net/base/net_export.h" |
| +#include "net/reporting/reporting_metrics.h" |
| +#include "net/reporting/reporting_report.h" |
| +#include "net/reporting/reporting_uploader.h" |
| +#include "net/url_request/url_request_context_getter.h" |
| +#include "url/gurl.h" |
| + |
| +namespace net { |
| + |
| +class NET_EXPORT ReportingService { |
|
Ryan Sleevi
2017/01/03 21:28:13
High level Design remarks:
1) This feels like a lo
Julia Tuttle
2017/01/25 20:27:46
My original design had a separate "ReportingCache"
|
| + public: |
| + struct NET_EXPORT Policy { |
| + // Time to keep an unused endpoint around, or zero for no limit. |
| + base::TimeDelta endpoint_lifetime; |
| + // Exponential backoff policy for uploading to endpoints. |
| + BackoffEntry::Policy endpoint_backoff; |
| + // Maximum number of failures before discarding an endpoint (once the |
| + // BackoffEntry is okay with it), or -1 for no limit. |
| + int max_endpoint_failures; |
| + // Maximum number of endpoints to keep around, or 0u for no limit. |
| + size_t max_endpoint_count; |
| + |
| + // Time to keep a queued report around, or zero for no limit. |
| + base::TimeDelta report_lifetime; |
| + // Maximum number of failed delivery attempts before discarding a report, or |
| + // -1 for no limit. |
| + int max_report_failures; |
| + // Maximum number of queued reports to keep around, or 0u for no limit. |
| + size_t max_report_count; |
| + |
| + // Whether to persist the report queue across network changes or not. |
| + bool persist_reports_across_network_changes; |
| + |
| + static Policy GetDefault(); |
|
Ryan Sleevi
2017/01/03 21:28:13
DESIGN: Why is an explicit GetDefault required? Wh
Julia Tuttle
2017/01/25 20:27:46
Done.
|
| + }; |
| + |
| + ReportingService(const Policy& policy); |
| + ~ReportingService(); |
| + |
| + void set_uploader(std::unique_ptr<ReportingUploader> uploader); |
|
Ryan Sleevi
2017/01/03 21:28:13
This seems to have more subtlety than just "set_up
Julia Tuttle
2017/01/25 20:27:46
Not really; it's just a separate setter instead of
|
| + void QueueReport(std::unique_ptr<base::Value> body, |
| + const GURL& url, |
| + const GURL& origin, |
| + const std::string& group, |
| + const std::string& type); |
| + void ProcessHeader(const GURL& origin, const std::string& header_value); |
| + void SendReports(); |
| + |
| + void set_clock_for_testing(std::unique_ptr<base::TickClock> clock); |
|
Ryan Sleevi
2017/01/03 21:28:13
SetClockForTesting
Julia Tuttle
2017/01/25 20:27:46
Why? It is actually just a plain setter under the
|
| + bool HasEndpointForTesting(const GURL& endpoint_url); |
| + bool HasClientForTesting(const GURL& endpoint_url, const GURL& origin_url); |
| + int GetEndpointFailuresForTesting(const GURL& endpoint_url); |
| + void CollectGarbageForTesting(); |
| + |
| + private: |
| + // Per-origin configuration and state for an endpoint. |
| + struct Client { |
|
Ryan Sleevi
2017/01/03 21:28:13
Why can't you forward declare this?
Julia Tuttle
2017/01/25 20:27:46
Done.
|
| + public: |
| + Client(const GURL& origin, |
| + bool subdomains, |
| + const std::string& group, |
| + base::TimeDelta ttl, |
| + base::TimeTicks creation); |
| + |
| + GURL origin; |
| + bool subdomains; |
| + std::string group; |
| + base::TimeDelta ttl; |
| + base::TimeTicks creation; |
| + |
| + bool is_expired(base::TimeTicks now) const { return creation + ttl < now; } |
| + }; |
| + |
| + // An endpoint to which one or more origins (represented by clients) want to |
| + // upload reports. |
| + struct Endpoint { |
|
Ryan Sleevi
2017/01/03 21:28:13
Why can't you forward declare this?
Julia Tuttle
2017/01/25 20:27:46
Done.
|
| + public: |
| + Endpoint(const GURL& url, |
| + const BackoffEntry::Policy& backoff_policy, |
| + base::TickClock* clock); |
| + ~Endpoint(); |
| + |
| + const GURL url; |
| + |
| + BackoffEntry backoff; |
| + // For LRU eviction of endpoints. |
| + base::TimeTicks last_used; |
| + // Whether we currently have an upload in progress to this endpoint. |
| + bool pending; |
| + |
| + // Map from client.origin to client. |
| + std::map<GURL, Client> clients; |
| + |
| + bool is_expired(base::TimeTicks now) const; |
| + }; |
| + |
| + // The parsed data from a header representing a single endpoint configuration. |
| + struct EndpointTuple { |
|
Ryan Sleevi
2017/01/03 21:28:13
Why can't you forward declare this?
Julia Tuttle
2017/01/25 20:27:46
Done.
|
| + GURL url; |
| + bool subdomains; |
| + base::TimeDelta ttl; |
| + std::string group; |
| + |
| + static bool FromDictionary(const base::DictionaryValue& dictionary, |
| + EndpointTuple* tuple_out, |
| + std::string* error_out); |
| + static bool FromHeader(const std::string& header, |
| + std::vector<EndpointTuple>* tuples_out, |
| + std::vector<std::string>* errors_out); |
| + |
| + std::string ToString() const; |
| + }; |
| + |
| + struct Delivery { |
|
Ryan Sleevi
2017/01/03 21:28:13
Why can't you forward declare this?
Julia Tuttle
2017/01/25 20:27:46
Done.
|
| + Delivery(const GURL& endpoint_url, |
| + const std::vector<ReportingReport*>& reports); |
| + ~Delivery(); |
| + |
| + const GURL& endpoint_url; |
| + const std::vector<ReportingReport*> reports; |
| + }; |
| + |
| + using EndpointMap = std::map<GURL, std::unique_ptr<Endpoint>>; |
| + using ReportVector = std::vector<std::unique_ptr<ReportingReport>>; |
| + |
| + void ProcessEndpointTuple(const GURL& origin, const EndpointTuple& tuple); |
| + |
| + void OnDeliveryAttemptComplete(const std::unique_ptr<Delivery>& delivery, |
| + ReportingUploader::Outcome outcome); |
| + |
| + void CollectGarbage(); |
| + |
| + Endpoint* FindEndpointForReport(const ReportingReport& report); |
| + bool DoesEndpointMatchReport(const Endpoint& endpoint, |
| + const ReportingReport& report); |
| + std::string SerializeReports(const std::vector<ReportingReport*>& reports); |
| + |
| + Endpoint* GetEndpointByURL(const GURL& url); |
| + void DequeueReport(ReportingReport* report); |
| + |
| + void HistogramHeaderEndpointInternal(bool endpoint_exists, |
| + bool client_exists, |
| + base::TimeDelta ttl) const; |
| + void HistogramReportInternal(ReportFate fate, |
| + const ReportingReport& report) const; |
| + |
| + Policy policy_; |
| + std::unique_ptr<base::TickClock> clock_; |
| + std::unique_ptr<ReportingUploader> uploader_; |
| + |
| + ReportVector reports_; |
| + EndpointMap endpoints_; |
| +}; |
| + |
| +} // namespace net |
| + |
| +#endif // COMPONENTS_REPORTING_REPORTING_SERVICE_H_ |