Skip to content

Commit dbf1cb0

Browse files
committed
Use a stronger session ID for editors than the process ID
In Visual Studio in particular, the build process can be performed by multiple processes simultaneously, yet they all share the same session identifier. Rider has a similar mechanism. Use that to signal the product-wide analyzer status, so that we reduce the chances of getting duplicate reports.
1 parent 330f826 commit dbf1cb0

2 files changed

Lines changed: 18 additions & 13 deletions

File tree

samples/dotnet/SponsorLink/DiagnosticsManager.cs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ public void ReportOnce(Action<Diagnostic> report, string product = Funding.Produ
5656
{
5757
// Ensure only one such diagnostic is reported per product for the entire process,
5858
// so that we can avoid polluting the error list with duplicates across multiple projects.
59-
var id = string.Concat(Process.GetCurrentProcess().Id, product, diagnostic.Id);
59+
var id = string.Concat(SessionId, product, diagnostic.Id);
6060
using var mutex = new Mutex(false, "mutex" + id);
6161
mutex.WaitOne();
62-
using var mmf = CreateOrOpenMemoryMappedFile(id, 1);
62+
using var mmf = CreateOrOpenMemoryMappedFile(product, 1);
6363
using var accessor = mmf.CreateViewAccessor();
6464
if (accessor.ReadByte(0) == 0)
6565
{
@@ -177,7 +177,7 @@ Diagnostic Push(Diagnostic diagnostic, string product = Funding.Product)
177177
if (Diagnostics.TryAdd(product, diagnostic))
178178
{
179179
// Reset the process-wide flag for this diagnostic.
180-
var id = string.Concat(Process.GetCurrentProcess().Id, product, diagnostic.Id);
180+
var id = string.Concat(SessionId, product, diagnostic.Id);
181181
using var mutex = new Mutex(false, "mutex" + id);
182182
mutex.WaitOne();
183183
using var mmf = CreateOrOpenMemoryMappedFile(id, 1);
@@ -204,18 +204,14 @@ Diagnostic Push(Diagnostic diagnostic, string product = Funding.Product)
204204
static MemoryMappedFile CreateOrOpenMemoryMappedFile(string mapName, int capacity)
205205
{
206206
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
207-
{
208207
return MemoryMappedFile.CreateOrOpen(mapName, capacity);
209-
}
210-
else
211-
{
212-
// On Linux, use a file-based memory-mapped file
213-
string filePath = $"/tmp/{mapName}";
214-
using (var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
215-
fs.Write(new byte[capacity], 0, capacity);
216208

217-
return MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate);
218-
}
209+
// On *nix, use a file-based memory-mapped file
210+
var filePath = $"/tmp/{mapName}";
211+
using (var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
212+
fs.Write(new byte[capacity], 0, capacity);
213+
214+
return MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate);
219215
}
220216

221217
internal static DiagnosticDescriptor CreateSponsor(string[] sponsorable, string prefix) => new(

samples/dotnet/SponsorLink/SponsorLink.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Collections.Generic;
55
using System.Collections.Immutable;
6+
using System.Diagnostics;
67
using System.Diagnostics.CodeAnalysis;
78
using System.IO;
89
using System.Linq;
@@ -43,6 +44,14 @@ static partial class SponsorLink
4344
Environment.GetEnvironmentVariable("RESHARPER_FUS_SESSION") != null ||
4445
Environment.GetEnvironmentVariable("IDEA_INITIAL_DIRECTORY") != null;
4546

47+
/// <summary>
48+
/// A unique session ID associated with the current IDE or process running the analyzer.
49+
/// </summary>
50+
public static string SessionId =>
51+
IsVisualStudio ? Environment.GetEnvironmentVariable("ServiceHubLogSessionKey") :
52+
IsRider ? Environment.GetEnvironmentVariable("RESHARPER_FUS_SESSION") :
53+
Process.GetCurrentProcess().Id.ToString();
54+
4655
/// <summary>
4756
/// Manages the sharing and reporting of diagnostics across the source generator
4857
/// and the diagnostic analyzer, to avoid doing the online check more than once.

0 commit comments

Comments
 (0)