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

Unified Diff: net/reporting/reporting_delivery_agent.cc

Issue 2785293003: Reporting: Make DeliveryAgent self-scheduling. (Closed)
Patch Set: rebase Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/reporting/reporting_delivery_agent.h ('k') | net/reporting/reporting_delivery_agent_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/reporting/reporting_delivery_agent.cc
diff --git a/net/reporting/reporting_delivery_agent.cc b/net/reporting/reporting_delivery_agent.cc
index f39dde936ea46b4e940c8fc9e2a9aaf8c23624f6..e614aa1b166fde4abfb35c3b85317d1831517538 100644
--- a/net/reporting/reporting_delivery_agent.cc
+++ b/net/reporting/reporting_delivery_agent.cc
@@ -13,9 +13,11 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/time/tick_clock.h"
+#include "base/timer/timer.h"
#include "base/values.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_endpoint_manager.h"
+#include "net/reporting/reporting_observer.h"
#include "net/reporting/reporting_report.h"
#include "net/reporting/reporting_uploader.h"
#include "url/gurl.h"
@@ -46,97 +48,174 @@ void SerializeReports(const std::vector<const ReportingReport*>& reports,
DCHECK(json_written);
}
-} // namespace
+class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
+ public ReportingObserver {
+ public:
+ ReportingDeliveryAgentImpl(ReportingContext* context)
+ : context_(context),
+ timer_(base::MakeUnique<base::OneShotTimer>()),
+ weak_factory_(this) {
+ context_->AddObserver(this);
+ }
-ReportingDeliveryAgent::ReportingDeliveryAgent(ReportingContext* context)
- : context_(context), weak_factory_(this) {}
-ReportingDeliveryAgent::~ReportingDeliveryAgent() {}
+ // ReportingDeliveryAgent implementation:
-class ReportingDeliveryAgent::Delivery {
- public:
- Delivery(const GURL& endpoint,
- const std::vector<const ReportingReport*>& reports)
- : endpoint(endpoint), reports(reports) {}
+ ~ReportingDeliveryAgentImpl() override { context_->RemoveObserver(this); }
- ~Delivery() {}
+ void Initialize() override {
+ if (CacheHasReports())
+ StartTimer();
+ }
- const GURL endpoint;
- const std::vector<const ReportingReport*> reports;
-};
+ void SetTimerForTesting(std::unique_ptr<base::Timer> timer) override {
+ DCHECK(!timer_->IsRunning());
+ timer_ = std::move(timer);
+ }
+
+ // ReportingObserver implementation:
+ void OnCacheUpdated() override {
+ if (CacheHasReports())
+ StartTimer();
+ }
-void ReportingDeliveryAgent::SendReports() {
- std::vector<const ReportingReport*> reports;
- cache()->GetReports(&reports);
+ private:
+ class Delivery {
+ public:
+ Delivery(const GURL& endpoint,
+ const std::vector<const ReportingReport*>& reports)
+ : endpoint(endpoint), reports(reports) {}
- // Sort reports into (origin, group) buckets.
- std::map<OriginGroup, std::vector<const ReportingReport*>>
- origin_group_reports;
- for (const ReportingReport* report : reports) {
- OriginGroup origin_group(url::Origin(report->url), report->group);
- origin_group_reports[origin_group].push_back(report);
+ ~Delivery() {}
+
+ const GURL endpoint;
+ const std::vector<const ReportingReport*> reports;
+ };
+
+ using OriginGroup = std::pair<url::Origin, std::string>;
+
+ bool CacheHasReports() {
+ std::vector<const ReportingReport*> reports;
+ context_->cache()->GetReports(&reports);
+ return !reports.empty();
+ }
+
+ void StartTimer() {
+ timer_->Start(FROM_HERE, policy().delivery_interval,
+ base::Bind(&ReportingDeliveryAgentImpl::OnTimerFired,
+ base::Unretained(this)));
+ }
+
+ void OnTimerFired() {
+ if (CacheHasReports()) {
+ SendReports();
+ StartTimer();
+ }
}
- // Find endpoint for each (origin, group) bucket and sort reports into
- // endpoint buckets. Don't allow concurrent deliveries to the same (origin,
- // group) bucket.
- std::map<GURL, std::vector<const ReportingReport*>> endpoint_reports;
- for (auto& it : origin_group_reports) {
- const OriginGroup& origin_group = it.first;
+ void SendReports() {
+ std::vector<const ReportingReport*> reports;
+ cache()->GetReports(&reports);
- if (base::ContainsKey(pending_origin_groups_, origin_group))
- continue;
+ // Sort reports into (origin, group) buckets.
+ std::map<OriginGroup, std::vector<const ReportingReport*>>
+ origin_group_reports;
+ for (const ReportingReport* report : reports) {
+ OriginGroup origin_group(url::Origin(report->url), report->group);
+ origin_group_reports[origin_group].push_back(report);
+ }
- GURL endpoint_url;
- if (!endpoint_manager()->FindEndpointForOriginAndGroup(
- origin_group.first, origin_group.second, &endpoint_url)) {
- continue;
+ // Find endpoint for each (origin, group) bucket and sort reports into
+ // endpoint buckets. Don't allow concurrent deliveries to the same (origin,
+ // group) bucket.
+ std::map<GURL, std::vector<const ReportingReport*>> endpoint_reports;
+ for (auto& it : origin_group_reports) {
+ const OriginGroup& origin_group = it.first;
+
+ if (base::ContainsKey(pending_origin_groups_, origin_group))
+ continue;
+
+ GURL endpoint_url;
+ if (!endpoint_manager()->FindEndpointForOriginAndGroup(
+ origin_group.first, origin_group.second, &endpoint_url)) {
+ continue;
+ }
+
+ endpoint_reports[endpoint_url].insert(
+ endpoint_reports[endpoint_url].end(), it.second.begin(),
+ it.second.end());
+ pending_origin_groups_.insert(origin_group);
}
- endpoint_reports[endpoint_url].insert(endpoint_reports[endpoint_url].end(),
- it.second.begin(), it.second.end());
- pending_origin_groups_.insert(origin_group);
+ // Start a delivery to each endpoint.
+ for (auto& it : endpoint_reports) {
+ const GURL& endpoint = it.first;
+ const std::vector<const ReportingReport*>& reports = it.second;
+
+ endpoint_manager()->SetEndpointPending(endpoint);
+ cache()->SetReportsPending(reports);
+
+ std::string json;
+ SerializeReports(reports, tick_clock()->NowTicks(), &json);
+
+ uploader()->StartUpload(
+ endpoint, json,
+ base::Bind(&ReportingDeliveryAgentImpl::OnUploadComplete,
+ weak_factory_.GetWeakPtr(),
+ base::MakeUnique<Delivery>(endpoint, reports)));
+ }
}
- // Start a delivery to each endpoint.
- for (auto& it : endpoint_reports) {
- const GURL& endpoint = it.first;
- const std::vector<const ReportingReport*>& reports = it.second;
+ void OnUploadComplete(const std::unique_ptr<Delivery>& delivery,
+ ReportingUploader::Outcome outcome) {
+ if (outcome == ReportingUploader::Outcome::SUCCESS) {
+ cache()->RemoveReports(delivery->reports);
+ endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, true);
+ } else {
+ cache()->IncrementReportsAttempts(delivery->reports);
+ endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, false);
+ }
- endpoint_manager()->SetEndpointPending(endpoint);
- cache()->SetReportsPending(reports);
+ if (outcome == ReportingUploader::Outcome::REMOVE_ENDPOINT)
+ cache()->RemoveClientsForEndpoint(delivery->endpoint);
- std::string json;
- SerializeReports(reports, tick_clock()->NowTicks(), &json);
+ for (const ReportingReport* report : delivery->reports) {
+ pending_origin_groups_.erase(
+ OriginGroup(url::Origin(report->url), report->group));
+ }
- uploader()->StartUpload(
- endpoint, json,
- base::Bind(&ReportingDeliveryAgent::OnUploadComplete,
- weak_factory_.GetWeakPtr(),
- base::MakeUnique<Delivery>(endpoint, reports)));
+ endpoint_manager()->ClearEndpointPending(delivery->endpoint);
+ cache()->ClearReportsPending(delivery->reports);
}
-}
-void ReportingDeliveryAgent::OnUploadComplete(
- const std::unique_ptr<Delivery>& delivery,
- ReportingUploader::Outcome outcome) {
- if (outcome == ReportingUploader::Outcome::SUCCESS) {
- cache()->RemoveReports(delivery->reports);
- endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, true);
- } else {
- cache()->IncrementReportsAttempts(delivery->reports);
- endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, false);
+ const ReportingPolicy& policy() { return context_->policy(); }
+ base::TickClock* tick_clock() { return context_->tick_clock(); }
+ ReportingCache* cache() { return context_->cache(); }
+ ReportingUploader* uploader() { return context_->uploader(); }
+ ReportingEndpointManager* endpoint_manager() {
+ return context_->endpoint_manager();
}
- if (outcome == ReportingUploader::Outcome::REMOVE_ENDPOINT)
- cache()->RemoveClientsForEndpoint(delivery->endpoint);
+ ReportingContext* context_;
- for (const ReportingReport* report : delivery->reports) {
- pending_origin_groups_.erase(
- OriginGroup(url::Origin(report->url), report->group));
- }
+ std::unique_ptr<base::Timer> timer_;
+
+ // Tracks OriginGroup tuples for which there is a pending delivery running.
+ // (Would be an unordered_set, but there's no hash on pair.)
+ std::set<OriginGroup> pending_origin_groups_;
+
+ base::WeakPtrFactory<ReportingDeliveryAgentImpl> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ReportingDeliveryAgentImpl);
+};
- endpoint_manager()->ClearEndpointPending(delivery->endpoint);
- cache()->ClearReportsPending(delivery->reports);
+} // namespace
+
+// static
+std::unique_ptr<ReportingDeliveryAgent> ReportingDeliveryAgent::Create(
+ ReportingContext* context) {
+ return base::MakeUnique<ReportingDeliveryAgentImpl>(context);
}
+ReportingDeliveryAgent::~ReportingDeliveryAgent() {}
+
} // namespace net
« no previous file with comments | « net/reporting/reporting_delivery_agent.h ('k') | net/reporting/reporting_delivery_agent_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698