Skip to content

Commit a90175f

Browse files
committed
Add telemetry
1 parent 2b7fdcb commit a90175f

3 files changed

Lines changed: 65 additions & 30 deletions

File tree

GVFS/GVFS.Common/MissingTreeTracker.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using GVFS.Common.Tracing;
45

56
namespace GVFS.Common
67
{
@@ -11,7 +12,10 @@ namespace GVFS.Common
1112
/// </summary>
1213
public class MissingTreeTracker
1314
{
15+
private const string EtwArea = nameof(MissingTreeTracker);
16+
1417
private readonly int treeCapacity;
18+
private readonly ITracer tracer;
1519
private readonly object syncLock = new object();
1620

1721
// Primary storage: commit -> set of missing trees
@@ -24,8 +28,9 @@ public class MissingTreeTracker
2428
private readonly LinkedList<string> commitOrder;
2529
private readonly Dictionary<string, LinkedListNode<string>> commitNodes;
2630

27-
public MissingTreeTracker(int treeCapacity)
31+
public MissingTreeTracker(ITracer tracer, int treeCapacity)
2832
{
33+
this.tracer = tracer;
2934
this.treeCapacity = treeCapacity;
3035
this.missingTreesByCommit = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
3136
this.commitsByTree = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
@@ -137,6 +142,13 @@ public void MarkCommitComplete(string commitSha)
137142
lock (this.syncLock)
138143
{
139144
this.RemoveCommitWithCascade(commitSha);
145+
146+
EventMetadata metadata = new EventMetadata();
147+
metadata.Add("Area", EtwArea);
148+
metadata.Add("CompletedCommit", commitSha);
149+
metadata.Add("RemainingCommits", this.commitNodes.Count);
150+
metadata.Add("RemainingTrees", this.commitsByTree.Count);
151+
this.tracer.RelatedEvent(EventLevel.Informational, nameof(this.MarkCommitComplete), metadata, Keywords.Telemetry);
140152
}
141153
}
142154

@@ -190,10 +202,26 @@ private bool EvictLruCommit()
190202
var last = this.commitOrder.Last;
191203
if (last != null && last.Value != this.commitOrder.First.Value)
192204
{
193-
string lruCommit = this.commitOrder.Last.Value;
205+
string lruCommit = last.Value;
206+
var treeCountBefore = this.commitsByTree.Count;
194207
this.RemoveCommitNoCache(lruCommit);
208+
209+
EventMetadata metadata = new EventMetadata();
210+
metadata.Add("Area", EtwArea);
211+
metadata.Add("EvictedCommit", lruCommit);
212+
metadata.Add("TreeCountBefore", treeCountBefore);
213+
metadata.Add("TreeCountAfter", this.commitsByTree.Count);
214+
this.tracer.RelatedEvent(EventLevel.Informational, nameof(this.EvictLruCommit), metadata, Keywords.Telemetry);
215+
195216
return true;
196217
}
218+
219+
EventMetadata warnMetadata = new EventMetadata();
220+
warnMetadata.Add("Area", EtwArea);
221+
warnMetadata.Add("TreeCount", this.commitsByTree.Count);
222+
warnMetadata.Add("CommitCount", this.commitNodes.Count);
223+
this.tracer.RelatedEvent(EventLevel.Warning, $"{nameof(this.EvictLruCommit)}CouldNotEvict", warnMetadata, Keywords.Telemetry);
224+
197225
return false;
198226
}
199227

GVFS/GVFS.Mount/InProcessMount.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public class InProcessMount
5858
private HeartbeatThread heartbeat;
5959
private ManualResetEvent unmountEvent;
6060

61-
private readonly MissingTreeTracker missingTreeTracker = new MissingTreeTracker(TrackedTreeCapacity);
61+
private readonly MissingTreeTracker missingTreeTracker;
6262

6363
// True if InProcessMount is calling git reset as part of processing
6464
// a folder dehydrate request
@@ -73,6 +73,7 @@ public InProcessMount(ITracer tracer, GVFSEnlistment enlistment, CacheServerInfo
7373
this.enlistment = enlistment;
7474
this.showDebugWindow = showDebugWindow;
7575
this.unmountEvent = new ManualResetEvent(false);
76+
this.missingTreeTracker = new MissingTreeTracker(tracer, TrackedTreeCapacity);
7677
}
7778

7879
private enum MountState

GVFS/GVFS.UnitTests/Common/MissingTreeTrackerTests.cs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
using GVFS.Common;
22
using GVFS.Tests.Should;
3+
using GVFS.UnitTests.Mock.Common;
34
using NUnit.Framework;
45

56
namespace GVFS.UnitTests.Common
67
{
78
[TestFixture]
89
public class MissingTreeTrackerTests
910
{
11+
private static MissingTreeTracker CreateTracker(int treeCapacity)
12+
{
13+
return new MissingTreeTracker(new MockTracer(), treeCapacity);
14+
}
15+
1016
// -------------------------------------------------------------------------
1117
// AddMissingRootTree
1218
// -------------------------------------------------------------------------
1319

1420
[TestCase]
1521
public void AddMissingRootTree_SingleTreeAndCommit()
1622
{
17-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
23+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
1824

1925
tracker.AddMissingRootTree("tree1", "commit1");
2026

@@ -27,7 +33,7 @@ public void AddMissingRootTree_SingleTreeAndCommit()
2733
[TestCase]
2834
public void AddMissingRootTree_MultipleTreesForSameCommit()
2935
{
30-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
36+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
3137

3238
tracker.AddMissingRootTree("tree1", "commit1");
3339
tracker.AddMissingRootTree("tree2", "commit1");
@@ -48,7 +54,7 @@ public void AddMissingRootTree_MultipleTreesForSameCommit()
4854
[TestCase]
4955
public void AddMissingRootTree_SameTreeAddedTwiceToSameCommit()
5056
{
51-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
57+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
5258

5359
tracker.AddMissingRootTree("tree1", "commit1");
5460
tracker.AddMissingRootTree("tree1", "commit1");
@@ -59,7 +65,7 @@ public void AddMissingRootTree_SameTreeAddedTwiceToSameCommit()
5965
[TestCase]
6066
public void AddMissingRootTree_SameTreeAddedToMultipleCommits()
6167
{
62-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
68+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
6369

6470
tracker.AddMissingRootTree("tree1", "commit1");
6571
tracker.AddMissingRootTree("tree1", "commit2");
@@ -76,7 +82,7 @@ public void AddMissingRootTree_SameTreeAddedToMultipleCommits()
7682
[TestCase]
7783
public void AddMissingRootTree_MultipleTrees_ChecksCount()
7884
{
79-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
85+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
8086

8187
tracker.AddMissingRootTree("tree1", "commit1");
8288
tracker.GetHighestMissingTreeCount(new[] { "commit1" }, out _).ShouldEqual(1);
@@ -99,7 +105,7 @@ public void AddMissingRootTree_MultipleTrees_ChecksCount()
99105
[TestCase]
100106
public void AddMissingSubTrees_AddsSubTreesUnderParentsCommits()
101107
{
102-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
108+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
103109

104110
tracker.AddMissingRootTree("rootTree", "commit1");
105111
tracker.AddMissingSubTrees("rootTree", new[] { "sub1", "sub2" });
@@ -116,7 +122,7 @@ public void AddMissingSubTrees_AddsSubTreesUnderParentsCommits()
116122
[TestCase]
117123
public void AddMissingSubTrees_PropagatesAcrossAllSharingCommits()
118124
{
119-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
125+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
120126

121127
// Two commits share the same root tree
122128
tracker.AddMissingRootTree("rootTree", "commit1");
@@ -135,7 +141,7 @@ public void AddMissingSubTrees_PropagatesAcrossAllSharingCommits()
135141
[TestCase]
136142
public void AddMissingSubTrees_NoOp_WhenParentNotTracked()
137143
{
138-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
144+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
139145

140146
// Should not throw; parent is not tracked
141147
tracker.AddMissingSubTrees("unknownParent", new[] { "sub1" });
@@ -154,7 +160,7 @@ public void AddMissingSubTrees_SkipsCommitEvictedDuringLoop()
154160
// commit2 is LRU (added to the tracker last among commit1/commit2 and then not used
155161
// again, while commit1 just got used), so it is evicted before we process commit2.
156162
// The loop must skip commit2 rather than crashing.
157-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 2);
163+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 2);
158164

159165
tracker.AddMissingRootTree("rootTree", "commit1");
160166
tracker.AddMissingRootTree("rootTree", "commit2");
@@ -175,7 +181,7 @@ public void AddMissingSubTrees_DoesNotEvictIfOnlyOneCommit()
175181
{
176182
/* This shouldn't be possible if user has a proper threshold and is marking commits
177183
* as completed, but test to be safe. */
178-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 2);
184+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 2);
179185
tracker.AddMissingRootTree("rootTree", "commit1");
180186
tracker.AddMissingSubTrees("rootTree", new[] { "sub1" });
181187
tracker.AddMissingSubTrees("rootTree", new[] { "sub2" });
@@ -189,7 +195,7 @@ public void AddMissingSubTrees_DoesNotEvictIfOnlyOneCommit()
189195
[TestCase]
190196
public void TryGetCommits_NonExistentTree()
191197
{
192-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
198+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
193199

194200
tracker.TryGetCommits("nonexistent", out string[] commits).ShouldEqual(false);
195201
commits.ShouldBeNull();
@@ -198,7 +204,7 @@ public void TryGetCommits_NonExistentTree()
198204
[TestCase]
199205
public void TryGetCommits_MarksAllCommitsAsRecentlyUsed()
200206
{
201-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 3);
207+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 3);
202208

203209
tracker.AddMissingRootTree("sharedTree", "commit1");
204210
tracker.AddMissingRootTree("sharedTree", "commit2");
@@ -225,7 +231,7 @@ public void TryGetCommits_MarksAllCommitsAsRecentlyUsed()
225231
[TestCase]
226232
public void GetHighestMissingTreeCount_NonExistentCommit()
227233
{
228-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
234+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
229235

230236
tracker.GetHighestMissingTreeCount(new[] { "nonexistent" }, out string highest).ShouldEqual(0);
231237
highest.ShouldBeNull();
@@ -234,7 +240,7 @@ public void GetHighestMissingTreeCount_NonExistentCommit()
234240
[TestCase]
235241
public void GetHighestMissingTreeCount_ReturnsCommitWithMostTrees()
236242
{
237-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
243+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
238244

239245
tracker.AddMissingRootTree("tree1", "commit1");
240246
tracker.AddMissingRootTree("tree2", "commit1");
@@ -248,7 +254,7 @@ public void GetHighestMissingTreeCount_ReturnsCommitWithMostTrees()
248254
[TestCase]
249255
public void GetHighestMissingTreeCount_DoesNotUpdateLru()
250256
{
251-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 3);
257+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 3);
252258

253259
tracker.AddMissingRootTree("tree1", "commit1");
254260
tracker.AddMissingRootTree("tree2", "commit2");
@@ -273,7 +279,7 @@ public void GetHighestMissingTreeCount_DoesNotUpdateLru()
273279
[TestCase]
274280
public void MarkCommitComplete_RemovesAllTreesForCommit()
275281
{
276-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
282+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
277283

278284
tracker.AddMissingRootTree("tree1", "commit1");
279285
tracker.AddMissingRootTree("tree2", "commit1");
@@ -292,7 +298,7 @@ public void MarkCommitComplete_RemovesAllTreesForCommit()
292298
[TestCase]
293299
public void MarkCommitComplete_NonExistentCommit()
294300
{
295-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
301+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
296302

297303
// Should not throw
298304
tracker.MarkCommitComplete("nonexistent");
@@ -301,7 +307,7 @@ public void MarkCommitComplete_NonExistentCommit()
301307
[TestCase]
302308
public void MarkCommitComplete_CascadesSharedTreesToOtherCommits()
303309
{
304-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
310+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
305311

306312
// commit1 and commit2 share tree1; commit2 also has tree2
307313
tracker.AddMissingRootTree("tree1", "commit1");
@@ -322,7 +328,7 @@ public void MarkCommitComplete_CascadesSharedTreesToOtherCommits()
322328
[TestCase]
323329
public void MarkCommitComplete_RemovesOtherCommitWhenItBecomesEmpty()
324330
{
325-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
331+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
326332

327333
// commit2's only tree is shared with commit1
328334
tracker.AddMissingRootTree("tree1", "commit1");
@@ -338,7 +344,7 @@ public void MarkCommitComplete_RemovesOtherCommitWhenItBecomesEmpty()
338344
[TestCase]
339345
public void MarkCommitComplete_DoesNotAffectUnrelatedCommits()
340346
{
341-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 10);
347+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 10);
342348

343349
tracker.AddMissingRootTree("tree1", "commit1");
344350
tracker.AddMissingRootTree("tree2", "commit2");
@@ -359,7 +365,7 @@ public void MarkCommitComplete_DoesNotAffectUnrelatedCommits()
359365
public void LruEviction_EvictsOldestCommit()
360366
{
361367
// treeCapacity = 3 trees; one tree per commit
362-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 3);
368+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 3);
363369

364370
tracker.AddMissingRootTree("tree1", "commit1");
365371
tracker.AddMissingRootTree("tree2", "commit2");
@@ -380,7 +386,7 @@ public void LruEviction_EvictsOldestCommit()
380386
public void LruEviction_DoesNotCascadeSharedTreesToOtherCommits()
381387
{
382388
// treeCapacity = 3 trees; tree1 is shared so only 2 unique trees + tree3 = 3 total
383-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 3);
389+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 3);
384390

385391
// tree1 is shared between commit1 and commit2 (counts as 1 unique tree)
386392
tracker.AddMissingRootTree("tree1", "commit1");
@@ -405,7 +411,7 @@ public void LruEviction_DoesNotCascadeSharedTreesToOtherCommits()
405411
public void LruEviction_AddingTreeToExistingCommitUpdatesLru()
406412
{
407413
// treeCapacity = 4 trees; tree1, tree2, tree3 fill it, then tree1b re-uses commit1
408-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 4);
414+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 4);
409415

410416
tracker.AddMissingRootTree("tree1", "commit1");
411417
tracker.AddMissingRootTree("tree2", "commit2");
@@ -427,7 +433,7 @@ public void LruEviction_AddingTreeToExistingCommitUpdatesLru()
427433
public void LruEviction_MultipleTreesPerCommit_EvictsEntireCommit()
428434
{
429435
// treeCapacity = 4 trees; commit1 holds 3, commit2 holds 1
430-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 4);
436+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 4);
431437

432438
tracker.AddMissingRootTree("tree1", "commit1");
433439
tracker.AddMissingRootTree("tree2", "commit1");
@@ -452,7 +458,7 @@ public void LruEviction_MultipleTreesPerCommit_EvictsEntireCommit()
452458
[TestCase]
453459
public void LruEviction_CapacityOne()
454460
{
455-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 1);
461+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 1);
456462

457463
tracker.AddMissingRootTree("tree1", "commit1");
458464
tracker.GetHighestMissingTreeCount(new[] { "commit1" }, out _).ShouldEqual(1);
@@ -468,7 +474,7 @@ public void LruEviction_ManyTreesOneCommit_ExceedsCapacity()
468474
{
469475
// treeCapacity = 3 trees; all trees belong to commit1
470476
// Adding a 4th tree must evict commit1 (the only commit) to make room
471-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 3);
477+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 3);
472478

473479
tracker.AddMissingRootTree("tree1", "commit1");
474480
tracker.AddMissingRootTree("tree2", "commit1");
@@ -490,7 +496,7 @@ public void LruEviction_ManyTreesOneCommit_ExceedsCapacity()
490496
public void LruEviction_TryGetCommitsUpdatesLru()
491497
{
492498
// treeCapacity = 3 trees, one per commit
493-
MissingTreeTracker tracker = new MissingTreeTracker(treeCapacity: 3);
499+
MissingTreeTracker tracker = CreateTracker(treeCapacity: 3);
494500

495501
tracker.AddMissingRootTree("tree1", "commit1");
496502
tracker.AddMissingRootTree("tree2", "commit2");

0 commit comments

Comments
 (0)