• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2012 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
5var EventsTracker = (function() {
6  'use strict';
7
8  /**
9   * This class keeps track of all NetLog events.
10   * It receives events from the browser and when loading a log file, and passes
11   * them on to all its observers.
12   *
13   * @constructor
14   */
15  function EventsTracker() {
16    assertFirstConstructorCall(EventsTracker);
17
18    this.capturedEvents_ = [];
19    this.observers_ = [];
20
21    // Controls how large |capturedEvents_| can grow.
22    this.softLimit_ = Infinity;
23    this.hardLimit_ = Infinity;
24  }
25
26  cr.addSingletonGetter(EventsTracker);
27
28  EventsTracker.prototype = {
29    /**
30     * Returns a list of all captured events.
31     */
32    getAllCapturedEvents: function() {
33      return this.capturedEvents_;
34    },
35
36    /**
37     * Returns the number of events that were captured.
38     */
39    getNumCapturedEvents: function() {
40      return this.capturedEvents_.length;
41    },
42
43    /**
44     * Deletes all the tracked events, and notifies any observers.
45     */
46    deleteAllLogEntries: function() {
47      timeutil.clearBaseTime();
48      this.capturedEvents_ = [];
49      for (var i = 0; i < this.observers_.length; ++i)
50        this.observers_[i].onAllLogEntriesDeleted();
51    },
52
53    /**
54     * Adds captured events, and broadcasts them to any observers.
55     */
56    addLogEntries: function(logEntries) {
57      // When reloading a page, it's possible to receive events before
58      // Constants.  Discard those events, as they can cause the fake
59      // "REQUEST_ALIVE" events for pre-existing requests not be the first
60      // events for those requests.
61      if (Constants == null)
62        return;
63      // This can happen when loading logs with no events.
64      if (!logEntries.length)
65        return;
66
67      if (!timeutil.isBaseTimeSet()) {
68        timeutil.setBaseTime(
69            timeutil.convertTimeTicksToTime(logEntries[0].time));
70      }
71
72      this.capturedEvents_ = this.capturedEvents_.concat(logEntries);
73      for (var i = 0; i < this.observers_.length; ++i) {
74        this.observers_[i].onReceivedLogEntries(logEntries);
75      }
76
77      // Check that we haven't grown too big. If so, toss out older events.
78      if (this.getNumCapturedEvents() > this.hardLimit_) {
79        var originalEvents = this.capturedEvents_;
80        this.deleteAllLogEntries();
81        // Delete the oldest events until we reach the soft limit.
82        originalEvents.splice(0, originalEvents.length - this.softLimit_);
83        this.addLogEntries(originalEvents);
84      }
85    },
86
87    /**
88     * Adds a listener of log entries. |observer| will be called back when new
89     * log data arrives or all entries are deleted:
90     *
91     *   observer.onReceivedLogEntries(entries)
92     *   observer.onAllLogEntriesDeleted()
93     */
94    addLogEntryObserver: function(observer) {
95      this.observers_.push(observer);
96    },
97
98    /**
99     * Set bounds on the maximum number of events that will be tracked. This
100     * helps to bound the total amount of memory usage, since otherwise
101     * long-running capture sessions can exhaust the renderer's memory and
102     * crash.
103     *
104     * Once |hardLimit| number of events have been captured we do a garbage
105     * collection and toss out old events, bringing our count down to
106     * |softLimit|.
107     *
108     * To log observers this will look like all the events got deleted, and
109     * then subsequently a bunch of new events were received. In other words, it
110     * behaves the same as if the user had simply started logging a bit later
111     * in time!
112     */
113    setLimits: function(softLimit, hardLimit) {
114      if (hardLimit != Infinity && softLimit >= hardLimit)
115        throw 'hardLimit must be greater than softLimit';
116
117      this.softLimit_ = softLimit;
118      this.hardLimit_ = hardLimit;
119    }
120  };
121
122  return EventsTracker;
123})();
124