Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wait for solution to be loaded before initializing remote telemetry #74944

Merged
merged 15 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -209,21 +209,18 @@ public async Task InitializeUIAffinitizedServicesAsync(IAsyncServiceProvider asy
_memoryListener = memoryListener;
}

await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(_threadingContext.DisposalToken);

// This must be called after the _openFileTracker was assigned; this way we know that a file added from the project system either got checked
// in CheckForAddedFileBeingOpenMaybeAsync, or we catch it here.
openFileTracker.CheckForOpenFilesThatWeMissed();

// Switch to a background thread to avoid loading option providers on UI thread (telemetry is reading options).
await TaskScheduler.Default;

var logDelta = _globalOptions.GetOption(DiagnosticOptionsStorage.LogTelemetryForBackgroundAnalyzerExecution);
var telemetryService = (VisualStudioWorkspaceTelemetryService)Services.GetRequiredService<IWorkspaceTelemetryService>();
telemetryService.InitializeTelemetrySession(telemetrySession, logDelta);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was already running in the BG before. i'm just moving it earlier (where we're already on the BG) instead of having to jump back to bg to run this


Logger.Log(FunctionId.Run_Environment,
KeyValueLogMessage.Create(m => m["Version"] = FileVersionInfo.GetVersionInfo(typeof(VisualStudioWorkspace).Assembly.Location).FileVersion));

await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(_threadingContext.DisposalToken);

// This must be called after the _openFileTracker was assigned; this way we know that a file added from the project system either got checked
// in CheckForAddedFileBeingOpenMaybeAsync, or we catch it here.
openFileTracker.CheckForOpenFilesThatWeMissed();
}

public Task CheckForAddedFileBeingOpenMaybeAsync(bool useAsync, ImmutableArray<string> newFileNames)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Telemetry;
Expand All @@ -18,7 +20,8 @@ internal abstract class AbstractWorkspaceTelemetryService : IWorkspaceTelemetryS

protected abstract ILogger CreateLogger(TelemetrySession telemetrySession, bool logDelta);

public void InitializeTelemetrySession(TelemetrySession telemetrySession, bool logDelta)
public void InitializeTelemetrySession(
TelemetrySession telemetrySession, bool logDelta)
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved
{
Contract.ThrowIfFalse(CurrentSession is null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
using System;
using System.Composition;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Options;
Expand All @@ -19,20 +20,16 @@
namespace Microsoft.VisualStudio.LanguageServices.Telemetry;

[ExportWorkspaceService(typeof(IWorkspaceTelemetryService)), Shared]
internal sealed class VisualStudioWorkspaceTelemetryService : AbstractWorkspaceTelemetryService
[method: ImportingConstructor]
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
internal sealed class VisualStudioWorkspaceTelemetryService(
IThreadingContext threadingContext,
VisualStudioWorkspace workspace,
IGlobalOptionService globalOptions) : AbstractWorkspaceTelemetryService
{
private readonly VisualStudioWorkspace _workspace;
private readonly IGlobalOptionService _globalOptions;

[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public VisualStudioWorkspaceTelemetryService(
VisualStudioWorkspace workspace,
IGlobalOptionService globalOptions)
{
_workspace = workspace;
_globalOptions = globalOptions;
}
private readonly IThreadingContext _threadingContext = threadingContext;
private readonly VisualStudioWorkspace _workspace = workspace;
private readonly IGlobalOptionService _globalOptions = globalOptions;

protected override ILogger CreateLogger(TelemetrySession telemetrySession, bool logDelta)
=> AggregateLogger.Create(
Expand All @@ -44,24 +41,26 @@ protected override ILogger CreateLogger(TelemetrySession telemetrySession, bool

protected override void TelemetrySessionInitialized()
{
var cancellationToken = _threadingContext.DisposalToken;
_ = Task.Run(async () =>
{
var client = await RemoteHostClient.TryGetClientAsync(_workspace, CancellationToken.None).ConfigureAwait(false);
var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false);
if (client == null)
{
return;
}

var settings = SerializeCurrentSessionSettings();
Contract.ThrowIfNull(settings);

// Only log "delta" property for block end events if feature flag is enabled.
var logDelta = _globalOptions.GetOption(DiagnosticOptionsStorage.LogTelemetryForBackgroundAnalyzerExecution);

var statusService = _workspace.Services.GetRequiredService<IWorkspaceStatusService>();
await statusService.WaitUntilFullyLoadedAsync(cancellationToken).ConfigureAwait(false);
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved

// initialize session in the remote service
_ = await client.TryInvokeAsync<IRemoteProcessTelemetryService>(
(service, cancellationToken) => service.InitializeTelemetrySessionAsync(Process.GetCurrentProcess().Id, settings, logDelta, cancellationToken),
CancellationToken.None).ConfigureAwait(false);
});
cancellationToken).ConfigureAwait(false);
}, cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

namespace Microsoft.CodeAnalysis.Remote;

internal sealed partial class RemoteProcessTelemetryService : BrokeredServiceBase, IRemoteProcessTelemetryService
internal sealed partial class RemoteProcessTelemetryService(
BrokeredServiceBase.ServiceConstructionArguments arguments)
: BrokeredServiceBase(arguments), IRemoteProcessTelemetryService
{
internal sealed class Factory : FactoryBase<IRemoteProcessTelemetryService>
{
Expand All @@ -33,12 +35,6 @@ protected override IRemoteProcessTelemetryService CreateService(in ServiceConstr

#pragma warning disable IDE0052 // Remove unread private members
private PerformanceReporter? _performanceReporter;
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved
#pragma warning restore
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved

public RemoteProcessTelemetryService(ServiceConstructionArguments arguments)
: base(arguments)
{
}

/// <summary>
/// Remote API. Initializes ServiceHub process global state.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,10 @@
namespace Microsoft.VisualStudio.LanguageServices.Telemetry;

[ExportWorkspaceService(typeof(IWorkspaceTelemetryService)), Shared]
internal sealed class RemoteWorkspaceTelemetryService : AbstractWorkspaceTelemetryService
[method: ImportingConstructor]
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
internal sealed class RemoteWorkspaceTelemetryService() : AbstractWorkspaceTelemetryService
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public RemoteWorkspaceTelemetryService()
{
}

protected override ILogger CreateLogger(TelemetrySession telemetrySession, bool logDelta)
=> AggregateLogger.Create(
TelemetryLogger.Create(telemetrySession, logDelta),
Expand Down