// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.ServiceHub.Framework;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Remote
{
///
/// Base type for Roslyn brokered services hosted in ServiceHub.
///
internal abstract partial class BrokeredServiceBase : IDisposable
{
private readonly TraceSource _logger;
protected readonly RemoteWorkspaceManager WorkspaceManager;
protected readonly SolutionAssetSource SolutionAssetSource;
protected readonly ServiceBrokerClient ServiceBrokerClient;
// test data are only available when running tests:
internal readonly RemoteHostTestData? TestData;
static BrokeredServiceBase()
{
}
protected BrokeredServiceBase(in ServiceConstructionArguments arguments)
{
_logger = (TraceSource)arguments.ServiceProvider.GetService(typeof(TraceSource));
TestData = (RemoteHostTestData?)arguments.ServiceProvider.GetService(typeof(RemoteHostTestData));
WorkspaceManager = TestData?.WorkspaceManager ?? RemoteWorkspaceManager.Default;
#pragma warning disable VSTHRD012 // Provide JoinableTaskFactory where allowed
ServiceBrokerClient = new ServiceBrokerClient(arguments.ServiceBroker);
#pragma warning restore
SolutionAssetSource = new SolutionAssetSource(ServiceBrokerClient);
}
public void Dispose()
=> ServiceBrokerClient.Dispose();
public RemoteWorkspace GetWorkspace()
=> WorkspaceManager.GetWorkspace();
protected void Log(TraceEventType errorType, string message)
=> _logger.TraceEvent(errorType, 0, $"{GetType()}: {message}");
protected Task GetSolutionAsync(PinnedSolutionInfo solutionInfo, CancellationToken cancellationToken)
{
var workspace = GetWorkspace();
var assetProvider = workspace.CreateAssetProvider(solutionInfo, WorkspaceManager.SolutionAssetCache, SolutionAssetSource);
return workspace.GetSolutionAsync(assetProvider, solutionInfo.SolutionChecksum, solutionInfo.FromPrimaryBranch, solutionInfo.WorkspaceVersion, cancellationToken);
}
protected async ValueTask RunServiceAsync(Func> implementation, CancellationToken cancellationToken)
{
WorkspaceManager.SolutionAssetCache.UpdateLastActivityTime();
try
{
return await implementation(cancellationToken).ConfigureAwait(false);
}
catch (Exception ex) when (FatalError.ReportWithoutCrashUnlessCanceledAndPropagate(ex, cancellationToken))
{
throw ExceptionUtilities.Unreachable;
}
}
protected async ValueTask RunServiceAsync(Func implementation, CancellationToken cancellationToken)
{
WorkspaceManager.SolutionAssetCache.UpdateLastActivityTime();
try
{
await implementation(cancellationToken).ConfigureAwait(false);
}
catch (Exception ex) when (FatalError.ReportWithoutCrashUnlessCanceledAndPropagate(ex, cancellationToken))
{
throw ExceptionUtilities.Unreachable;
}
}
}
}