Synchronization during initialization and logging updates (#1)

This commit is contained in:
rohit-joy 2016-11-28 18:31:07 -08:00 коммит произвёл GitHub
Родитель cc9a57a599
Коммит 1509dd25aa
10 изменённых файлов: 105 добавлений и 46 удалений

Просмотреть файл

@ -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" />