Skip to content

Commit

Permalink
refactor: add abstraction over grpc-core request models and target cl…
Browse files Browse the repository at this point in the history
…ient
  • Loading branch information
rdavisau committed Apr 13, 2022
1 parent 5a35013 commit bfec146
Show file tree
Hide file tree
Showing 21 changed files with 384 additions and 70 deletions.
64 changes: 64 additions & 0 deletions src/components/tbc.core/Models/OperationModels.cs
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;

namespace Tbc.Core.Models;

public record ConnectRequest
{
public HostInfo HostInfo { get; set; }
}

public record ConnectResponse
{
public string AssemblyName { get; set; }
}

public record LoadDynamicAssemblyRequest
{
public byte[] PeBytes { get; set; }
public byte[] PdbBytes { get; set; }
public string AssemblyName { get; set; }
public string PrimaryTypeName { get; set; }
}

public record Outcome
{
public bool Success { get; set; }
public List<OutcomeMessage> Messages { get; set; } = new();
}

public record OutcomeMessage
{
public string Message { get; set; }
}

public record HostInfo
{
public string Address { get; set; }
public int Port { get; set; }
}

public record ExecuteCommandRequest
{
public string Command { get; set; }
public List<string> Args { get; set; } = new();
}

public record CachedAssemblyState
{
public List<CachedAssembly> CachedAssemblies { get; set; } = new();
}

public record CachedAssembly
{
public string AssemblyName { get; set; } = default!;
public DateTimeOffset ModificationTime { get; set; }
}

public record AssemblyReference
{
public string AssemblyName { get; set; } = default!;
public string AssemblyLocation { get; set; } = default!;
public DateTimeOffset ModificationTime { get; set; } = default!;
public byte[] PeBytes { get; set; } = default!;
}
1 change: 1 addition & 0 deletions src/components/tbc.core/tbc.core.csproj
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RootNamespace>Tbc.Core</RootNamespace>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
Expand Up @@ -4,12 +4,9 @@
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Google.Protobuf;
using Grpc.Core;
using Grpc.Core.Utils;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Tbc.Core.Models;
using Tbc.Host.Components.Abstractions;
using Tbc.Host.Components.CommandProcessor;
using Tbc.Host.Components.CommandProcessor.Models;
Expand All @@ -18,24 +15,24 @@
using Tbc.Host.Components.FileWatcher.Models;
using Tbc.Host.Components.IncrementalCompiler;
using Tbc.Host.Components.IncrementalCompiler.Models;
using Tbc.Host.Components.TargetClient;
using Tbc.Host.Extensions;
using Tbc.Protocol;

namespace Tbc.Host.Components.FileEnvironment
{
public partial class FileEnvironment : TransientComponentBase<FileEnvironment>, IFileEnvironment, IExposeCommands, IHaveComponentsThatExposeCommands
{
private bool _running;

public TargetClient.TargetClient Client { get; }
public ITargetClient Client { get; }
public ICommandProcessor CommandProcessor { get; }
public IFileWatcher FileWatcher { get; }
public IIncrementalCompiler IncrementalCompiler { get; }

public FileEnvironment(IClient client,
public FileEnvironment(IRemoteClientDefinition client,
IFileWatcher fileWatcher, ICommandProcessor commandProcessor,
Func<IClient, TargetClient.TargetClient> targetClientFactory,
Func<IClient, IIncrementalCompiler> incrementalCompilerFactory,
Func<IRemoteClientDefinition, ITargetClient> targetClientFactory,
Func<IRemoteClientDefinition, IIncrementalCompiler> incrementalCompilerFactory,
ILogger<FileEnvironment> logger) : base(logger)
{
Client = targetClientFactory(client);
Expand Down Expand Up @@ -128,7 +125,7 @@ public async Task SetupReferenceTracking()
Logger.LogInformation(
"Adding reference to {AssemblyName} from {AssemblyLocation} for client {Client}",
asm.AssemblyName, asm.AssemblyLocation, Client.Client);
asm.AssemblyName, asm.AssemblyLocation, Client.ClientDefinition);
IncrementalCompiler.AddMetadataReference(asm);
});
Expand All @@ -147,13 +144,15 @@ public async Task SetupCommandListening()
var iterator = await Client.CommandRequests();
try
{
while (await iterator.MoveNext(default) && !Terminated)
var enumerator = iterator.GetAsyncEnumerator();

while (await enumerator.MoveNextAsync() && !Terminated)
{
var request = iterator.Current;
var request = enumerator.Current;

Logger.LogInformation(
"Received command request {@Request} from target {Client}",
request, Client.Client);
request, Client.ClientDefinition);

// doh
await CommandProcessor.HandleCommand($"{request.Command} {String.Join(" ", request.Args)}");
Expand All @@ -177,15 +176,15 @@ public async Task<Outcome> SendAssemblyForReload(EmittedAssembly asm)
var req = new LoadDynamicAssemblyRequest
{
AssemblyName = asm.AssemblyName,
PeBytes = ByteString.CopyFrom(asm.Pe),
PdbBytes = asm.Pd == null ? ByteString.Empty : ByteString.CopyFrom(asm.Pd),
PeBytes = asm.Pe,
PdbBytes = asm.Pd,
PrimaryTypeName =
String.IsNullOrWhiteSpace(_primaryTypeHint)
? ""
: TryResolvePrimaryType(_primaryTypeHint)
};

return await Client.Loader.LoadAssemblyAsync(req);
return await Client.LoadAssemblyAsync(req);
}

public string TryResolvePrimaryType(string typeHint)
Expand All @@ -207,7 +206,7 @@ public async Task SetPrimaryTypeHint(string typeHint)
}

string IExposeCommands.Identifier
=> $"env-{Client.Client.Address}-{Client.Client.Port}";
=> $"env-{Client.ClientDefinition.Address}-{Client.ClientDefinition.Port}";

IEnumerable<TbcCommand> IExposeCommands.Commands => new List<TbcCommand>
{
Expand Down Expand Up @@ -235,7 +234,7 @@ string IExposeCommands.Identifier
foreach (var arg in args)
req.Args.Add(arg);
var outcome = await Client.Loader.ExecAsync(req);
var outcome = await Client.ExecAsync(req);
Logger.LogInformation("{@Outcome}", outcome);
}
Expand Down Expand Up @@ -300,4 +299,4 @@ public class PersistedContext
public string? PrimaryTypeHint { get; set; }
public List<string> WatchedFiles { get; set; }
}
}
}
@@ -1,8 +1,8 @@
namespace Tbc.Host.Components.FileEnvironment.Models
{
public interface IClient
public interface IRemoteClientDefinition
{
public string Address { get; set; }
public int Port { get; set; }
}
}
}
@@ -1,6 +1,6 @@
namespace Tbc.Host.Components.FileEnvironment.Models
{
public class RemoteClient : IClient
public class RemoteClient : IRemoteClientDefinition
{
public string Address { get; set; }
public int Port { get; set; }
Expand Down
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using Tbc.Core.Models;
using Tbc.Host.Components.FileWatcher.Models;
using Tbc.Host.Components.IncrementalCompiler.Models;
using Tbc.Protocol;

namespace Tbc.Host.Components.IncrementalCompiler
{
Expand All @@ -18,4 +18,4 @@ public interface IIncrementalCompiler
void PrintTrees(bool withDetail);
string TryResolvePrimaryType(string typeHint);
}
}
}
Expand Up @@ -11,14 +11,15 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.Extensions.Logging;
using Tbc.Core.Models;
using Tbc.Host.Components.Abstractions;
using Tbc.Host.Components.CommandProcessor.Models;
using Tbc.Host.Components.FileEnvironment.Models;
using Tbc.Host.Components.FileWatcher.Models;
using Tbc.Host.Components.IncrementalCompiler.Models;
using Tbc.Host.Components.TargetClient.GrpcCore;
using Tbc.Host.Config;
using Tbc.Host.Extensions;
using Tbc.Protocol;

namespace Tbc.Host.Components.IncrementalCompiler
{
Expand All @@ -27,7 +28,7 @@ public class IncrementalCompiler : ComponentBase<IncrementalCompiler>, IIncremen
private bool _disposing;

private readonly AssemblyCompilationOptions _options;
private readonly TargetClient.TargetClient _client;
private readonly GrpcCoreTargetClient _client;

private readonly IFileSystem _fileSystem;

Expand All @@ -48,7 +49,7 @@ public List<string> StagedFiles

public IncrementalCompiler(
AssemblyCompilationOptions options,
IClient client, Func<IClient, TargetClient.TargetClient> targetClientFactory,
IRemoteClientDefinition client, Func<IRemoteClientDefinition, GrpcCoreTargetClient> targetClientFactory,
IFileSystem fileSystem, ILogger<IncrementalCompiler> logger) : base(logger)
{
_options = options;
Expand Down Expand Up @@ -278,7 +279,7 @@ public void Dispose()
}

string IExposeCommands.Identifier
=> $"inc-{_client.Client.Address}-{_client.Client.Port}";
=> $"inc-{_client.ClientDefinition.Address}-{_client.ClientDefinition.Port}";

IEnumerable<TbcCommand> IExposeCommands.Commands => new List<TbcCommand>
{
Expand Down
@@ -0,0 +1,27 @@
public enum CanonicalChannelState
{
/// <summary>
/// Channel is idle
/// </summary>
Idle,

/// <summary>
/// Channel is connecting
/// </summary>
Connecting,

/// <summary>
/// Channel is ready for work
/// </summary>
Ready,

/// <summary>
/// Channel has seen a failure but expects to recover
/// </summary>
TransientFailure,

/// <summary>
/// Channel has seen a failure that it cannot recover from
/// </summary>
Shutdown
}
@@ -0,0 +1,47 @@
using System;
using System.Linq;
using Google.Protobuf;
using Tbc.Core.Models;
using AssemblyReference = Tbc.Protocol.AssemblyReference;
using ExecuteCommandRequest = Tbc.Protocol.ExecuteCommandRequest;
using LoadDynamicAssemblyRequest = Tbc.Protocol.LoadDynamicAssemblyRequest;
using Outcome = Tbc.Protocol.Outcome;

namespace Tbc.Host.Components.TargetClient.GrpcCore;

public static class GrpcCoreMappingExtensions
{
public static Tbc.Core.Models.Outcome ToCanonical(this Outcome o)
=> new() {
Success = o.Success,
Messages = o.Messages.Select(x => new OutcomeMessage { Message = x.Message_ }).ToList()
};

public static Tbc.Core.Models.ExecuteCommandRequest ToCanonical(this ExecuteCommandRequest x)
=> new() { Command = x.Command, Args = x.Args.ToList() };

public static Tbc.Core.Models.AssemblyReference ToCanonical(this AssemblyReference x)
=> new()
{
AssemblyName = x.AssemblyName,
ModificationTime = DateTimeOffset.FromUnixTimeSeconds((long)x.ModificationTime),
AssemblyLocation = x.AssemblyLocation,
PeBytes = x.PeBytes.ToByteArray()
};

public static LoadDynamicAssemblyRequest ToCore(this Tbc.Core.Models.LoadDynamicAssemblyRequest req)
=> new()
{
AssemblyName = req.AssemblyName,
PeBytes = ByteString.CopyFrom(req.PeBytes),
PdbBytes = ByteString.CopyFrom(req.PdbBytes),
PrimaryTypeName = req.PrimaryTypeName
};

public static ExecuteCommandRequest ToCore(this Tbc.Core.Models.ExecuteCommandRequest req)
=> new()
{
Command = req.Command,
Args = { req.Args }
};
}

0 comments on commit bfec146

Please sign in to comment.