Skip to content

Commit

Permalink
Use a stronger session ID for editors than the process ID
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kzu committed Jul 9, 2024
1 parent 330f826 commit dbf1cb0
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
22 changes: 9 additions & 13 deletions samples/dotnet/SponsorLink/DiagnosticsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ public void ReportOnce(Action<Diagnostic> report, string product = Funding.Produ
{
// Ensure only one such diagnostic is reported per product for the entire process,
// so that we can avoid polluting the error list with duplicates across multiple projects.
var id = string.Concat(Process.GetCurrentProcess().Id, product, diagnostic.Id);
var id = string.Concat(SessionId, product, diagnostic.Id);
using var mutex = new Mutex(false, "mutex" + id);
mutex.WaitOne();
using var mmf = CreateOrOpenMemoryMappedFile(id, 1);
using var mmf = CreateOrOpenMemoryMappedFile(product, 1);
using var accessor = mmf.CreateViewAccessor();
if (accessor.ReadByte(0) == 0)
{
Expand Down Expand Up @@ -177,7 +177,7 @@ Diagnostic Push(Diagnostic diagnostic, string product = Funding.Product)
if (Diagnostics.TryAdd(product, diagnostic))
{
// Reset the process-wide flag for this diagnostic.
var id = string.Concat(Process.GetCurrentProcess().Id, product, diagnostic.Id);
var id = string.Concat(SessionId, product, diagnostic.Id);
using var mutex = new Mutex(false, "mutex" + id);
mutex.WaitOne();
using var mmf = CreateOrOpenMemoryMappedFile(id, 1);
Expand All @@ -204,18 +204,14 @@ Diagnostic Push(Diagnostic diagnostic, string product = Funding.Product)
static MemoryMappedFile CreateOrOpenMemoryMappedFile(string mapName, int capacity)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return MemoryMappedFile.CreateOrOpen(mapName, capacity);
}
else
{
// On Linux, use a file-based memory-mapped file
string filePath = $"/tmp/{mapName}";
using (var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
fs.Write(new byte[capacity], 0, capacity);

return MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate);
}
// On *nix, use a file-based memory-mapped file
var filePath = $"/tmp/{mapName}";
using (var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
fs.Write(new byte[capacity], 0, capacity);

return MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate);
}

internal static DiagnosticDescriptor CreateSponsor(string[] sponsorable, string prefix) => new(
Expand Down
9 changes: 9 additions & 0 deletions samples/dotnet/SponsorLink/SponsorLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -43,6 +44,14 @@ static partial class SponsorLink
Environment.GetEnvironmentVariable("RESHARPER_FUS_SESSION") != null ||
Environment.GetEnvironmentVariable("IDEA_INITIAL_DIRECTORY") != null;

/// <summary>
/// A unique session ID associated with the current IDE or process running the analyzer.
/// </summary>
public static string SessionId =>
IsVisualStudio ? Environment.GetEnvironmentVariable("ServiceHubLogSessionKey") :
IsRider ? Environment.GetEnvironmentVariable("RESHARPER_FUS_SESSION") :
Process.GetCurrentProcess().Id.ToString();

/// <summary>
/// Manages the sharing and reporting of diagnostics across the source generator
/// and the diagnostic analyzer, to avoid doing the online check more than once.
Expand Down

0 comments on commit dbf1cb0

Please sign in to comment.