| Index: content/browser/service_worker/service_worker_lifetime_tracker.cc
|
| diff --git a/content/browser/service_worker/service_worker_lifetime_tracker.cc b/content/browser/service_worker/service_worker_lifetime_tracker.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f682a9ae14e7d2516360f634f1ecda89073cd8f6
|
| --- /dev/null
|
| +++ b/content/browser/service_worker/service_worker_lifetime_tracker.cc
|
| @@ -0,0 +1,71 @@
|
| +// Copyright 2017 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.
|
| +
|
| +#include "content/browser/service_worker/service_worker_lifetime_tracker.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/stl_util.h"
|
| +#include "base/time/default_tick_clock.h"
|
| +#include "content/browser/service_worker/service_worker_metrics.h"
|
| +
|
| +namespace content {
|
| +
|
| +// Five minutes is somewhat ad-hoc. We want to capture workers that are
|
| +// running for a long time in UMA even if they never stop. A timer running too
|
| +// frequently would be wasteful and too infrequently could miss long-running
|
| +// workers before browser shutdown. Five minutes seems about right; it's also
|
| +// the default keep-alive time limit for a service worker event so workers
|
| +// running longer than this are a bit special: they must have had multiple
|
| +// events in their lifetime.
|
| +constexpr base::TimeDelta kTimerDuration = base::TimeDelta::FromMinutes(5);
|
| +
|
| +ServiceWorkerLifetimeTracker::ServiceWorkerLifetimeTracker()
|
| + : ServiceWorkerLifetimeTracker(base::MakeUnique<base::DefaultTickClock>()) {
|
| +}
|
| +
|
| +ServiceWorkerLifetimeTracker::ServiceWorkerLifetimeTracker(
|
| + std::unique_ptr<base::TickClock> tick_clock)
|
| + : tick_clock_(std::move(tick_clock)), timer_(tick_clock_.get()) {}
|
| +
|
| +ServiceWorkerLifetimeTracker::~ServiceWorkerLifetimeTracker() = default;
|
| +
|
| +void ServiceWorkerLifetimeTracker::StartTiming(int64_t version_id) {
|
| + DCHECK(!base::ContainsKey(running_workers_, version_id));
|
| +
|
| + running_workers_[version_id] = tick_clock_->NowTicks();
|
| + if (!timer_.IsRunning()) {
|
| + timer_.Start(FROM_HERE, kTimerDuration, this,
|
| + &ServiceWorkerLifetimeTracker::RecordHistograms);
|
| + }
|
| +}
|
| +
|
| +void ServiceWorkerLifetimeTracker::StopTiming(int64_t version_id) {
|
| + auto it = running_workers_.find(version_id);
|
| + if (it == running_workers_.end())
|
| + return;
|
| + ServiceWorkerMetrics::RecordRuntime(tick_clock_->NowTicks() - it->second);
|
| + running_workers_.erase(it);
|
| +}
|
| +
|
| +void ServiceWorkerLifetimeTracker::AbortTiming(int64_t version_id) {
|
| + auto it = running_workers_.find(version_id);
|
| + if (it == running_workers_.end())
|
| + return;
|
| + running_workers_.erase(it);
|
| +}
|
| +
|
| +void ServiceWorkerLifetimeTracker::RecordHistograms() {
|
| + base::TimeTicks now = tick_clock_->NowTicks();
|
| +
|
| + for (auto& item : running_workers_) {
|
| + base::TimeDelta runtime = now - item.second;
|
| + if (runtime > kTimerDuration)
|
| + ServiceWorkerMetrics::RecordStillRunning(runtime);
|
| + }
|
| +
|
| + if (running_workers_.empty())
|
| + timer_.Stop();
|
| +}
|
| +
|
| +} // namespace content
|
|
|