-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
171 lines (126 loc) · 2.82 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
* Ticks Tracer
* Takes snapshots for an object across event loop ticks
*
* @author Mohammad Fares <[email protected]>
*/
var clone = require('clone');
/**
* Ticks Tracer
*
* @param {Object} tracedObject
*/
function TicksTracer(tracedObject) {
/**
* The current tick number
* @type {Number}
*/
this._ticksCounter = 0;
/**
* To store the taken snapshots indexed by ticks numbers
* @type {Array}
*/
this._snapshots = [];
/**
* Is taking snapshots stopped
* @type {Boolean}
*/
this._isStopped = false;
/**
* The object to take snapshots of
* @type {Object}
*/
this._tracedObject = tracedObject;
// Stat tracing
this._tracing();
}
/**
* Take a snapshot for the traced object
*/
TicksTracer.prototype._takeSnapshot = function() {
this._snapshots[this._ticksCounter] = clone(this._tracedObject);
};
/**
* Update the last taken snapshot for the traced object
*/
TicksTracer.prototype._updateLastSnapshot = function() {
this._snapshots[this._snapshots.length - 1] = clone(this._tracedObject);
};
/**
* Start tracing
*
* - Keeps calling itself after each event loop tick.
* - Stops when the `_isStopped` flag is true.
* - On each tick:
* - Call `_takeSnapshot()`
* - Increment the `_ticksCounter`
*/
TicksTracer.prototype._tracing = function() {
if (this._isStopped) {
return;
}
this._takeSnapshot();
this._ticksCounter++;
setImmediate(this._tracing.bind(this));
};
/**
* Get the current tick number
*
* @return {Number}
*/
TicksTracer.prototype.getTicksCount = function() {
return this._ticksCounter;
};
/**
* Get a taken snapshot by a tick number
*
* @param {Number} tick
* @return {Object}
*/
TicksTracer.prototype.getSnapshotAt = function(tick) {
return this._snapshots[tick];
};
/**
* Get all taken snapshots indexed by ticks numbers
*
* @return {Array}
*/
TicksTracer.prototype.getSnapshots = function() {
return this._snapshots;
};
/**
* Get a list of snapshots that represent only the diffs
*
* @return {Array}
*/
TicksTracer.prototype.getSnapshotsDiffs = function() {
var diffs = [];
var self = this;
self._snapshots.forEach(function(snapshot, index) {
var prevSnapshot = null;
var currentSnapshot = self._snapshots[index];
var diff = {};
if (index == 0) {
diffs.push(snapshot);
return;
}
prevSnapshot = self._snapshots[index - 1];
for (var key in currentSnapshot) {
if (!(key in prevSnapshot) || prevSnapshot[key] != currentSnapshot[key]) {
diff[key] = currentSnapshot[key];
}
}
diffs.push(diff);
});
return diffs;
};
/**
* Stop tracing
*
* @return {Object}
*/
TicksTracer.prototype.stop = function() {
this._isStopped = true;
this._updateLastSnapshot();
};
module.exports = TicksTracer;