Synchronization during initialization and logging updates (#1)
This commit is contained in:
Родитель
cc9a57a599
Коммит
1509dd25aa
|
@ -1,15 +1,16 @@
|
|||
using CommandLine;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace RInterop
|
||||
{
|
||||
public class CommandLineOptions
|
||||
{
|
||||
[Option('s', "schema", Required = false,
|
||||
[Option('s', "schema", Required = true,
|
||||
HelpText = "Path to schema binary file containing types to serialize and deserialize input data and output data sent to and received from the R package, respectively")]
|
||||
public string SchemaBinaryPath { get; set; }
|
||||
|
||||
[Option('r', "rpackage", Required = false,
|
||||
[Option('r', "rpackage", Required = true,
|
||||
HelpText = "Path to R package file containing statistical functions (optional if packages are already installed)")]
|
||||
public string RPackagePath { get; set; }
|
||||
|
||||
|
@ -19,20 +20,21 @@ namespace RInterop
|
|||
|
||||
public static bool ParseArguments(string[] args, CommandLineOptions options)
|
||||
{
|
||||
var logger = DependencyFactory.Resolve<ILogger>();
|
||||
if (!Parser.Default.ParseArguments(args, options))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(options.RPackagePath) && !File.Exists(options.RPackagePath))
|
||||
|
||||
if (!File.Exists(options.RPackagePath))
|
||||
{
|
||||
DependencyFactory.Resolve<ILogger>().LogInformation("RPackagePath {0} not found", options.RPackagePath);
|
||||
logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "RPackage {0} not found", options.RPackagePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(options.SchemaBinaryPath) && !File.Exists(options.SchemaBinaryPath))
|
||||
if (!File.Exists(options.SchemaBinaryPath))
|
||||
{
|
||||
DependencyFactory.Resolve<ILogger>().LogInformation("SchemaBinaryPath {0} not found", options.SchemaBinaryPath);
|
||||
logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "Schema binary {0} not found", options.SchemaBinaryPath));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
public static string SchemaBinaryPath { get; set; }
|
||||
|
||||
public static string RPackageName { get; set; }
|
||||
|
||||
public static string RPackagePath { get; set; }
|
||||
|
||||
public static SerializationTypeMaps SerializationTypeMaps { get; set; }
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace RInterop
|
|||
.Resolve<ILoggerFactory>("TraceLoggerFactory")
|
||||
.Create("RInterop"));
|
||||
|
||||
Resolve<ILogger>().LogInformation("Type registrations completed");
|
||||
Resolve<ILogger>().LogInformation("Completed registering dependencies");
|
||||
}
|
||||
|
||||
public static T Resolve<T>()
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
[assembly: System.Reflection.AssemblyCopyright("Copyright (c) Microsoft Corporation 2016")]
|
||||
[assembly: System.CLSCompliant(false)]
|
||||
[assembly: System.Reflection.AssemblyVersion("1.1.41577.4")]
|
||||
[assembly: System.Reflection.AssemblyFileVersion("1.1.41577.4")]
|
||||
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Description;
|
||||
|
@ -12,15 +13,16 @@ namespace RInterop
|
|||
{
|
||||
ILogger logger = DependencyFactory.Resolve<ILogger>();
|
||||
|
||||
logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "Working directory: {0}", Environment.CurrentDirectory));
|
||||
logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "Arguments: {0}", string.Join(" ", args)));
|
||||
|
||||
var options = new CommandLineOptions();
|
||||
if (!CommandLineOptions.ParseArguments(args, options))
|
||||
{
|
||||
DependencyFactory.Resolve<ILogger>().LogInformation("Invalid arguments", args);
|
||||
DependencyFactory.Resolve<ILogger>().LogInformation(string.Format(CultureInfo.InvariantCulture, "Invalid arguments {0}", string.Join(" ", args)));
|
||||
|
||||
logger.LogInformation(@"Usage");
|
||||
logger.LogInformation(@"RInterop.exe --s ""<path to schema.dll>"" --r ""<path to R package file>""");
|
||||
logger.LogInformation(@"Example:");
|
||||
logger.LogInformation(@"RInterop.exe --s ""C:\Temp\Schemas.dll"" --r ""C:\Temp\RPackage.zip""");
|
||||
logger.LogInformation(@"Usage: RInterop.exe --s ""<path to schema.dll>"" --r ""<path to R package file>""");
|
||||
logger.LogInformation(@"Example: RInterop.exe --s ""C:\Temp\Schemas.dll"" --r ""C:\Temp\RPackage.zip""");
|
||||
logger.LogInformation("Press any key to continue...");
|
||||
Console.ReadLine();
|
||||
return;
|
||||
|
@ -36,13 +38,13 @@ namespace RInterop
|
|||
logger.LogInformation("Exception while extracting R package name: {0}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
Config.RPackagePath = options.RPackagePath;
|
||||
|
||||
Config.SchemaBinaryPath = options.SchemaBinaryPath;
|
||||
REngineWrapper.InstallPackages(options.RPackagePath, options.SchemaBinaryPath);
|
||||
|
||||
StartService();
|
||||
}
|
||||
|
||||
|
||||
private static void StartService()
|
||||
{
|
||||
EventWaitHandle startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, @"Global\RInteropStarted");
|
||||
|
@ -81,7 +83,7 @@ namespace RInterop
|
|||
host.AddServiceEndpoint(typeof(IR), new NetNamedPipeBinding(), "");
|
||||
|
||||
host.Open();
|
||||
|
||||
|
||||
startedEvent.Set();
|
||||
|
||||
DependencyFactory.Resolve<ILogger>().LogInformation("Service is available. Press <ENTER> to exit.");
|
||||
|
|
|
@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
|
|||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("RInterop")]
|
||||
[assembly: AssemblyDescription("Abstraction layer for communicating with R")]
|
||||
[assembly: AssemblyDescription("Statistical A/B testing library")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("RInterop")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
//[assembly: AssemblyCopyright("Copyright © 2016")] // Added in generated GlobalAssemblyInfo.cs file
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.4.7.0")]
|
||||
[assembly: AssemblyFileVersion("0.4.7.0")]
|
||||
//[assembly: AssemblyVersion("0.4.7.0")] // Added in generated GlobalAssemblyInfo.cs file
|
||||
//[assembly: AssemblyFileVersion("0.4.7.0")] // Added in generated GlobalAssemblyInfo.cs file
|
||||
|
|
|
@ -62,12 +62,12 @@ namespace RInterop
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogInformation("Exception during evaluation {0}", e);
|
||||
_logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "Exception during evaluation {0}", e));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Initialize(Dictionary<string, string> inputTypeMap, Dictionary<string, string> outputTypeMap)
|
||||
{
|
||||
Assembly assembly = Assembly.LoadFrom(Config.SchemaBinaryPath);
|
||||
|
@ -77,6 +77,7 @@ namespace RInterop
|
|||
Config.SerializationTypeMaps.InputTypeMap[key] = assembly
|
||||
.GetTypes()
|
||||
.First(a => a.FullName.Equals(inputTypeMap[key]));
|
||||
_logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "Got input type mapping: {0} > {1}", key, inputTypeMap[key]));
|
||||
}
|
||||
|
||||
foreach (string key in outputTypeMap.Keys)
|
||||
|
@ -84,6 +85,7 @@ namespace RInterop
|
|||
Config.SerializationTypeMaps.OutputTypeMap[key] = assembly
|
||||
.GetTypes()
|
||||
.First(a => a.FullName.Equals(outputTypeMap[key]));
|
||||
_logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "Got output type mapping: {0} > {1}", key, outputTypeMap[key]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,28 +21,9 @@ namespace RInterop
|
|||
{
|
||||
if (_engine == null)
|
||||
{
|
||||
var logger = DependencyFactory.Resolve<ILogger>();
|
||||
|
||||
_engine = REngine.GetInstance();
|
||||
|
||||
_engine.Evaluate(string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
@"install.packages(""{0}"", verbose = TRUE, dependencies = TRUE, type = ""win.binary"")",
|
||||
Config.RPackagePath.Replace(@"\", @"\\")));
|
||||
|
||||
List<string> imports = _engine
|
||||
.Evaluate(@"packageDescription(""" + Config.RPackageName + @""")$Imports")
|
||||
.AsCharacter()
|
||||
.First()
|
||||
.Replace(" ", string.Empty)
|
||||
.Split(',')
|
||||
.ToList();
|
||||
|
||||
foreach (string packageName in imports)
|
||||
{
|
||||
_engine.Evaluate(string.Format(CultureInfo.InvariantCulture,
|
||||
@"if (!require(""{0}""))
|
||||
install.packages(""{0}"", repo = ""https://cran.rstudio.com/"", dependencies = TRUE)",
|
||||
packageName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,5 +31,35 @@ install.packages(""{0}"", repo = ""https://cran.rstudio.com/"", dependencies = T
|
|||
return _engine;
|
||||
}
|
||||
}
|
||||
|
||||
public static void InstallPackages(string rPackagePath, string schemaBinaryPath)
|
||||
{
|
||||
var engine = REngineWrapper.REngine;
|
||||
var logger = DependencyFactory.Resolve<ILogger>();
|
||||
engine.Evaluate(string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
@"install.packages(""{0}"", verbose = TRUE, dependencies = TRUE, type = ""win.binary"")",
|
||||
rPackagePath.Replace(@"\", @"\\")));
|
||||
|
||||
logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "Installed R package {0}", rPackagePath));
|
||||
|
||||
List<string> imports = engine
|
||||
.Evaluate(@"packageDescription(""" + Config.RPackageName + @""")$Imports")
|
||||
.AsCharacter()
|
||||
.First()
|
||||
.Replace(" ", string.Empty)
|
||||
.Split(',')
|
||||
.ToList();
|
||||
|
||||
foreach (string packageName in imports)
|
||||
{
|
||||
logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "Installing dependent R package {0}", packageName));
|
||||
engine.Evaluate(string.Format(CultureInfo.InvariantCulture,
|
||||
@"if (!require(""{0}""))
|
||||
install.packages(""{0}"", repo = ""https://cran.rstudio.com/"", dependencies = TRUE)",
|
||||
packageName));
|
||||
logger.LogInformation(string.Format(CultureInfo.InvariantCulture, "Installed R package {0}", packageName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
<Compile Include="CommandLineOptions.cs" />
|
||||
<Compile Include="Config.cs" />
|
||||
<Compile Include="DependencyFactory.cs" />
|
||||
<Compile Include="GlobalAssemblyInfo.cs" />
|
||||
<Compile Include="ILogger.cs" />
|
||||
<Compile Include="ILoggerFactory.cs" />
|
||||
<Compile Include="IR.cs" />
|
||||
|
@ -143,8 +144,34 @@
|
|||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Bond.CSharp.5.0.0\build\Bond.CSharp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Bond.CSharp.5.0.0\build\Bond.CSharp.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Bond.CSharp.5.0.0\build\Bond.CSharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Bond.CSharp.5.0.0\build\Bond.CSharp.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets'))" />
|
||||
</Target>
|
||||
<PropertyGroup>
|
||||
<Major>1</Major>
|
||||
<Minor>1</Minor>
|
||||
</PropertyGroup>
|
||||
<Choose>
|
||||
<When Condition=" '$(BUILD_BUILDNUMBER)'=='' ">
|
||||
<PropertyGroup>
|
||||
<Build>$([MSBuild]::Modulo($([System.DateTime]::UtcNow.ToString("yyyyMMdd")), 65536))</Build>
|
||||
<Revision>4</Revision>
|
||||
<BUILD_BUILDNUMBER>$(Build).$(Revision)</BUILD_BUILDNUMBER>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<When Condition=" '$(BUILD_BUILDNUMBER)'!='' ">
|
||||
<PropertyGroup>
|
||||
<Build>$([MSBuild]::Modulo($([System.Math]::Floor($(BUILD_BUILDNUMBER))), 65536))</Build>
|
||||
<Revision>$(BUILD_BUILDNUMBER.Substring($([MSBuild]::Add($(BUILD_BUILDNUMBER.IndexOf('.')), 1))))</Revision>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
<Target Name="BeforeBuild">
|
||||
<Message Text="AssemblyVersion: $(Major).$(Minor).$(Build).$(Revision)" />
|
||||
<Message Text="AssemblyFileVersion: $(Major).$(Minor).$(BUILD_BUILDNUMBER)" />
|
||||
<AssemblyInfo CodeLanguage="CS" OutputFile="GlobalAssemblyInfo.cs" AssemblyCopyright="Copyright (c) Microsoft Corporation 2016" AssemblyTrademark="" CLSCompliant="false" AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)" AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" />
|
||||
</Target>
|
||||
<Import Project="..\packages\Bond.CSharp.5.0.0\build\Bond.CSharp.targets" Condition="Exists('..\packages\Bond.CSharp.5.0.0\build\Bond.CSharp.targets')" />
|
||||
<Import Project="..\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets" Condition="Exists('..\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<package id="CommandLineParser" version="1.9.71" targetFramework="net452" />
|
||||
<package id="CommonServiceLocator" version="1.3" targetFramework="net452" />
|
||||
<package id="DynamicInterop" version="0.7.4" targetFramework="net452" />
|
||||
<package id="MSBuildTasks" version="1.5.0.214" targetFramework="net452" developmentDependency="true" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
||||
<package id="R.NET.Community" version="1.6.5" targetFramework="net452" />
|
||||
<package id="Unity" version="4.0.1" targetFramework="net452" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче