зеркало из https://github.com/microsoft/mwt-ds.git
fixed warnings
This commit is contained in:
Родитель
0f51caf506
Коммит
e25a055fbf
|
@ -25,6 +25,7 @@
|
||||||
<NuGetPackageImportStamp>
|
<NuGetPackageImportStamp>
|
||||||
</NuGetPackageImportStamp>
|
</NuGetPackageImportStamp>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
|
<Use64BitIISExpress />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
@ -82,11 +83,11 @@
|
||||||
<Reference Include="Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>$(SolutionDir)\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
|
<HintPath>$(SolutionDir)\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.13.9.1126, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.16.1.24801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>$(SolutionDir)\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.13.9\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
|
<HintPath>$(SolutionDir)\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.16.1\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.13.9.1126, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.16.1.24801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>$(SolutionDir)\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.13.9\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
|
<HintPath>$(SolutionDir)\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.16.1\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>$(SolutionDir)\packages\Microsoft.Rest.ClientRuntime.2.3.7\lib\net452\Microsoft.Rest.ClientRuntime.dll</HintPath>
|
<HintPath>$(SolutionDir)\packages\Microsoft.Rest.ClientRuntime.2.3.7\lib\net452\Microsoft.Rest.ClientRuntime.dll</HintPath>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<package id="Microsoft.Data.Edm" version="5.8.2" targetFramework="net452" />
|
<package id="Microsoft.Data.Edm" version="5.8.2" targetFramework="net452" />
|
||||||
<package id="Microsoft.Data.OData" version="5.8.2" targetFramework="net452" />
|
<package id="Microsoft.Data.OData" version="5.8.2" targetFramework="net452" />
|
||||||
<package id="Microsoft.Data.Services.Client" version="5.8.2" targetFramework="net452" />
|
<package id="Microsoft.Data.Services.Client" version="5.8.2" targetFramework="net452" />
|
||||||
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.13.9" targetFramework="net462" />
|
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.16.1" targetFramework="net462" />
|
||||||
<package id="Microsoft.Net.Compilers" version="2.1.0" targetFramework="net462" developmentDependency="true" />
|
<package id="Microsoft.Net.Compilers" version="2.1.0" targetFramework="net462" developmentDependency="true" />
|
||||||
<package id="Microsoft.Rest.ClientRuntime" version="2.3.7" targetFramework="net462" />
|
<package id="Microsoft.Rest.ClientRuntime" version="2.3.7" targetFramework="net462" />
|
||||||
<package id="Microsoft.Rest.ClientRuntime.Azure" version="3.3.6" targetFramework="net462" />
|
<package id="Microsoft.Rest.ClientRuntime.Azure" version="3.3.6" targetFramework="net462" />
|
||||||
|
|
|
@ -1,52 +1,52 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||||
</startup>
|
</startup>
|
||||||
<runtime>
|
<runtime>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="VowpalWabbit" publicKeyToken="a76afd1645210483" culture="neutral"/>
|
<assemblyIdentity name="VowpalWabbit" publicKeyToken="a76afd1645210483" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="VowpalWabbit.Core" publicKeyToken="a76afd1645210483" culture="neutral"/>
|
<assemblyIdentity name="VowpalWabbit.Core" publicKeyToken="a76afd1645210483" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="VowpalWabbit.Common" publicKeyToken="a76afd1645210483" culture="neutral"/>
|
<assemblyIdentity name="VowpalWabbit.Common" publicKeyToken="a76afd1645210483" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.ApplicationInsights" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.ApplicationInsights" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
<system.diagnostics>
|
<system.diagnostics>
|
||||||
<trace autoflush="true" indentsize="0">
|
<trace autoflush="true" indentsize="0">
|
||||||
<listeners>
|
<listeners>
|
||||||
<add name="myAppInsightsListener" type="Microsoft.ApplicationInsights.TraceListener.ApplicationInsightsTraceListener, Microsoft.ApplicationInsights.TraceListener"/>
|
<add name="myAppInsightsListener" type="Microsoft.ApplicationInsights.TraceListener.ApplicationInsightsTraceListener, Microsoft.ApplicationInsights.TraceListener" />
|
||||||
</listeners>
|
</listeners>
|
||||||
</trace>
|
</trace>
|
||||||
</system.diagnostics>
|
</system.diagnostics>
|
||||||
|
|
|
@ -13,17 +13,31 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Download blobs in background.
|
||||||
|
/// </summary>
|
||||||
public class AzureBlobBackgroundDownloader : IDisposable
|
public class AzureBlobBackgroundDownloader : IDisposable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Download finished event handler.
|
||||||
|
/// </summary>
|
||||||
public delegate void DownloadedEventHandler(object sender, byte[] data);
|
public delegate void DownloadedEventHandler(object sender, byte[] data);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Download failed event handler.
|
||||||
|
/// </summary>
|
||||||
public delegate void FailedEventHandler(object sender, Exception e);
|
public delegate void FailedEventHandler(object sender, Exception e);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Download finished event handler.
|
||||||
|
/// </summary>
|
||||||
public event DownloadedEventHandler Downloaded;
|
public event DownloadedEventHandler Downloaded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Download failed event handler.
|
||||||
|
/// </summary>
|
||||||
public event FailedEventHandler Failed;
|
public event FailedEventHandler Failed;
|
||||||
|
|
||||||
|
|
||||||
private IDisposable disposable;
|
private IDisposable disposable;
|
||||||
|
|
||||||
private readonly Uri blobAddress;
|
private readonly Uri blobAddress;
|
||||||
|
@ -32,6 +46,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
|
|
||||||
private bool downloadImmediately;
|
private bool downloadImmediately;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance.
|
||||||
|
/// </summary>
|
||||||
public AzureBlobBackgroundDownloader(string blobAddress, TimeSpan interval, bool downloadImmediately = false, string storageConnectionString = null)
|
public AzureBlobBackgroundDownloader(string blobAddress, TimeSpan interval, bool downloadImmediately = false, string storageConnectionString = null)
|
||||||
{
|
{
|
||||||
if (blobAddress == null)
|
if (blobAddress == null)
|
||||||
|
@ -120,6 +137,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disposes the object.
|
||||||
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (this.disposable != null)
|
if (this.disposable != null)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(SolutionDir)\packages\GitLink.3.1.0\build\GitLink.props" Condition="Exists('$(SolutionDir)\packages\GitLink.3.1.0\build\GitLink.props')" />
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
@ -55,10 +56,6 @@
|
||||||
<DocumentationFile>$(SolutionDir)bin\x64\Release\Microsoft.Research.MultiWorldTesting.ClientLibrary.XML</DocumentationFile>
|
<DocumentationFile>$(SolutionDir)bin\x64\Release\Microsoft.Research.MultiWorldTesting.ClientLibrary.XML</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="GitLink, Version=2.4.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>$(SolutionDir)\packages\gitlink.2.4.0\lib\net45\GitLink.exe</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Microsoft.AI.PerfCounterCollector, Version=2.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.AI.PerfCounterCollector, Version=2.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>$(SolutionDir)\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.2.0\lib\net45\Microsoft.AI.PerfCounterCollector.dll</HintPath>
|
<HintPath>$(SolutionDir)\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.2.0\lib\net45\Microsoft.AI.PerfCounterCollector.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
|
@ -209,6 +206,8 @@
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Error Condition="!Exists('$(SolutionDir)\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets'))" />
|
<Error Condition="!Exists('$(SolutionDir)\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets'))" />
|
||||||
|
<Error Condition="!Exists('$(SolutionDir)\packages\GitLink.3.1.0\build\GitLink.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\GitLink.3.1.0\build\GitLink.props'))" />
|
||||||
|
<Error Condition="!Exists('$(SolutionDir)\packages\GitLink.3.1.0\build\GitLink.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\GitLink.3.1.0\build\GitLink.targets'))" />
|
||||||
</Target>
|
</Target>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>$(ProjectDir)\..\docgen.bat "$(ProjectDir)\..\"</PostBuildEvent>
|
<PostBuildEvent>$(ProjectDir)\..\docgen.bat "$(ProjectDir)\..\"</PostBuildEvent>
|
||||||
|
@ -217,8 +216,8 @@
|
||||||
<AssemblyInfo CodeLanguage="CS" OutputFile="$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs" AssemblyTitle="Microsoft.Research.MultiWorldTesting.ClientLibrary" AssemblyDescription="" AssemblyConfiguration="" AssemblyCompany="Microsoft Corp" AssemblyProduct="Microsoft.Research.MultiWorldTesting.ClientLibrary" AssemblyCopyright="Copyright (C) Microsoft Corp 2014-2016" AssemblyTrademark="" ComVisible="false" CLSCompliant="false" Guid="a991c863-165c-4fd5-b388-45b13df358a8" AssemblyVersion="$(ClientLibraryAssemblyVersion)" AssemblyFileVersion="$(ClientLibraryAssemblyVersion)" />
|
<AssemblyInfo CodeLanguage="CS" OutputFile="$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs" AssemblyTitle="Microsoft.Research.MultiWorldTesting.ClientLibrary" AssemblyDescription="" AssemblyConfiguration="" AssemblyCompany="Microsoft Corp" AssemblyProduct="Microsoft.Research.MultiWorldTesting.ClientLibrary" AssemblyCopyright="Copyright (C) Microsoft Corp 2014-2016" AssemblyTrademark="" ComVisible="false" CLSCompliant="false" Guid="a991c863-165c-4fd5-b388-45b13df358a8" AssemblyVersion="$(ClientLibraryAssemblyVersion)" AssemblyFileVersion="$(ClientLibraryAssemblyVersion)" />
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
<Exec Command="$(SolutionDir)packages\gitlink.2.4.0\lib\net45\GitLink.exe ..\.. -f $(SolutionDir)\mwt-ds.sln -p $(Platform) -c $(Configuration) -d $(OutDir) -errorsaswarnings -u https://github.com/Microsoft/mwt-ds" Condition="'$(BuildNuget)' == 'true'" />
|
|
||||||
<Exec Command=".nuget\nuget pack $(ProjectDir)\$(ProjectName).nuspec -Version $(ClientLibraryAssemblyVersion) -Prop "Configuration=Release;Platform=x64" -Prop SolutionDir=$(SolutionDir) -OutputDirectory $(OutDir) " WorkingDirectory="$(SolutionDir)" Condition="'$(BuildNuget)' == 'true'" />
|
<Exec Command=".nuget\nuget pack $(ProjectDir)\$(ProjectName).nuspec -Version $(ClientLibraryAssemblyVersion) -Prop "Configuration=Release;Platform=x64" -Prop SolutionDir=$(SolutionDir) -OutputDirectory $(OutDir) " WorkingDirectory="$(SolutionDir)" Condition="'$(BuildNuget)' == 'true'" />
|
||||||
</Target>
|
</Target>
|
||||||
<Import Project="$(SolutionDir)\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets" Condition="Exists('$(SolutionDir)\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets')" />
|
<Import Project="$(SolutionDir)\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets" Condition="Exists('$(SolutionDir)\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets')" />
|
||||||
|
<Import Project="$(SolutionDir)\packages\GitLink.3.1.0\build\GitLink.targets" Condition="Exists('$(SolutionDir)\packages\GitLink.3.1.0\build\GitLink.targets')" />
|
||||||
</Project>
|
</Project>
|
|
@ -2,8 +2,14 @@
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// When a model cannot be found.
|
||||||
|
/// </summary>
|
||||||
public class ModelNotFoundException : Exception
|
public class ModelNotFoundException : Exception
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance.
|
||||||
|
/// </summary>
|
||||||
public ModelNotFoundException(string message) : base(message) { }
|
public ModelNotFoundException(string message) : base(message) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disposes the resources.
|
||||||
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
foreach (var p in typeof(PerformanceCounters).GetProperties())
|
foreach (var p in typeof(PerformanceCounters).GetProperties())
|
||||||
|
@ -115,39 +118,75 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of interactions queued.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.NumberOfItems64)]
|
[PerformanceCounterType(PerformanceCounterType.NumberOfItems64)]
|
||||||
public PerformanceCounter InteractionExamplesQueue { get; private set; }
|
public PerformanceCounter InteractionExamplesQueue { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total number of interactions seen.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.NumberOfItems64)]
|
[PerformanceCounterType(PerformanceCounterType.NumberOfItems64)]
|
||||||
public PerformanceCounter InteractionExamplesTotal { get; private set; }
|
public PerformanceCounter InteractionExamplesTotal { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of interactions processed per second.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond32)]
|
[PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond32)]
|
||||||
public PerformanceCounter InteractionExamplesPerSec { get; private set; }
|
public PerformanceCounter InteractionExamplesPerSec { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of bytes (from interaction) per second.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond64)]
|
[PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond64)]
|
||||||
public PerformanceCounter InteractionExamplesBytesPerSec { get; private set; }
|
public PerformanceCounter InteractionExamplesBytesPerSec { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Average size of interactions (in bytes).
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.AverageCount64)]
|
[PerformanceCounterType(PerformanceCounterType.AverageCount64)]
|
||||||
public PerformanceCounter AverageInteractionExampleSize { get; private set; }
|
public PerformanceCounter AverageInteractionExampleSize { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Average size of interactions (in bytes) - Base.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.AverageBase)]
|
[PerformanceCounterType(PerformanceCounterType.AverageBase)]
|
||||||
public PerformanceCounter AverageInteractionExampleSizeBase { get; private set; }
|
public PerformanceCounter AverageInteractionExampleSizeBase { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of observations queued.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.NumberOfItems64)]
|
[PerformanceCounterType(PerformanceCounterType.NumberOfItems64)]
|
||||||
public PerformanceCounter ObservationExamplesQueue { get; private set; }
|
public PerformanceCounter ObservationExamplesQueue { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total number of observations seen.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.NumberOfItems64)]
|
[PerformanceCounterType(PerformanceCounterType.NumberOfItems64)]
|
||||||
public PerformanceCounter ObservationExamplesTotal { get; private set; }
|
public PerformanceCounter ObservationExamplesTotal { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of observations per second.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond32)]
|
[PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond32)]
|
||||||
public PerformanceCounter ObservationExamplesPerSec { get; private set; }
|
public PerformanceCounter ObservationExamplesPerSec { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of bytes of observations per second.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond64)]
|
[PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond64)]
|
||||||
public PerformanceCounter ObservationExamplesBytesPerSec { get; private set; }
|
public PerformanceCounter ObservationExamplesBytesPerSec { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Average observation size in bytes.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.AverageCount64)]
|
[PerformanceCounterType(PerformanceCounterType.AverageCount64)]
|
||||||
public PerformanceCounter AverageObservationExampleSize { get; private set; }
|
public PerformanceCounter AverageObservationExampleSize { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Average observation size in bytes - Base.
|
||||||
|
/// </summary>
|
||||||
[PerformanceCounterType(PerformanceCounterType.AverageBase)]
|
[PerformanceCounterType(PerformanceCounterType.AverageBase)]
|
||||||
public PerformanceCounter AverageObservationExampleSizeBase { get; private set; }
|
public PerformanceCounter AverageObservationExampleSizeBase { get; private set; }
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="EnterpriseLibrary.TransientFaultHandling" version="6.0.1304.0" targetFramework="net45" />
|
<package id="EnterpriseLibrary.TransientFaultHandling" version="6.0.1304.0" targetFramework="net45" />
|
||||||
<package id="gitlink" version="2.4.0" targetFramework="net45" developmentDependency="true" />
|
<package id="GitLink" version="3.1.0" targetFramework="net462" developmentDependency="true" />
|
||||||
<package id="Microsoft.ApplicationInsights" version="2.2.0" targetFramework="net45" />
|
<package id="Microsoft.ApplicationInsights" version="2.2.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.2.0" targetFramework="net45" />
|
<package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.2.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.ApplicationInsights.TraceListener" version="2.2.0" targetFramework="net45" />
|
<package id="Microsoft.ApplicationInsights.TraceListener" version="2.2.0" targetFramework="net45" />
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Research.MultiWorldTesting.ClientLibrary;
|
using Microsoft.Research.MultiWorldTesting.ClientLibrary;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ClientDecisionServiceTest
|
namespace ClientDecisionServiceTest
|
||||||
{
|
{
|
||||||
|
@ -14,7 +15,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public void TestADFExplorationResult()
|
public async Task TestADFExplorationResult()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ namespace ClientDecisionServiceTest
|
||||||
for (int i = 1; i <= 100; i++)
|
for (int i = 1; i <= 100; i++)
|
||||||
{
|
{
|
||||||
var adfContext = new TestADFContext(i);
|
var adfContext = new TestADFContext(i);
|
||||||
int[] action = ds.ChooseRanking(uniqueKey, adfContext);
|
int[] action = await ds.ChooseRankingAsync(uniqueKey, adfContext);
|
||||||
|
|
||||||
Assert.AreEqual(i, action.Length);
|
Assert.AreEqual(i, action.Length);
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public void TestADFModelUpdateFromStream()
|
public async Task TestADFModelUpdateFromStream()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ namespace ClientDecisionServiceTest
|
||||||
int numActions = rg.Next(5, 20);
|
int numActions = rg.Next(5, 20);
|
||||||
var context = TestADFContextWithFeatures.CreateRandom(numActions, rg);
|
var context = TestADFContextWithFeatures.CreateRandom(numActions, rg);
|
||||||
|
|
||||||
int[] action = ds.ChooseRanking(uniqueKey, context);
|
int[] action = await ds.ChooseRankingAsync(uniqueKey, context);
|
||||||
|
|
||||||
Assert.AreEqual(numActions, action.Length);
|
Assert.AreEqual(numActions, action.Length);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public void TestSingleActionDSUploadSingleEvent()
|
public async Task TestSingleActionDSUploadSingleEvent()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace ClientDecisionServiceTest
|
||||||
.Create<TestContext>(dsConfig)
|
.Create<TestContext>(dsConfig)
|
||||||
.ExploitUntilModelReady(new ConstantPolicy<TestContext>()))
|
.ExploitUntilModelReady(new ConstantPolicy<TestContext>()))
|
||||||
{
|
{
|
||||||
chosenAction = ds.ChooseAction(uniqueKey, new TestContext());
|
chosenAction = await ds.ChooseActionAsync(uniqueKey, new TestContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.AreEqual(1, joinServer.RequestCount);
|
Assert.AreEqual(1, joinServer.RequestCount);
|
||||||
|
@ -48,7 +48,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public void TestSingleActionDSUploadMultipleEvents()
|
public async Task TestSingleActionDSUploadMultipleEvents()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -64,8 +64,8 @@ namespace ClientDecisionServiceTest
|
||||||
.ExploitUntilModelReady(new ConstantPolicy<TestContext>()))
|
.ExploitUntilModelReady(new ConstantPolicy<TestContext>()))
|
||||||
{
|
{
|
||||||
|
|
||||||
int chosenAction1 = ds.ChooseAction(uniqueKey, new TestContext());
|
int chosenAction1 = await ds.ChooseActionAsync(uniqueKey, new TestContext());
|
||||||
int chosenAction2 = ds.ChooseAction(uniqueKey, new TestContext());
|
int chosenAction2 = await ds.ChooseActionAsync(uniqueKey, new TestContext());
|
||||||
ds.ReportReward(1.0f, uniqueKey);
|
ds.ReportReward(1.0f, uniqueKey);
|
||||||
ds.ReportOutcome(JsonConvert.SerializeObject(new { value = "test outcome" }), uniqueKey);
|
ds.ReportOutcome(JsonConvert.SerializeObject(new { value = "test outcome" }), uniqueKey);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ namespace ClientDecisionServiceTest
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestMultiActionDSUploadSingleEvent()
|
public async Task TestMultiActionDSUploadSingleEvent()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ namespace ClientDecisionServiceTest
|
||||||
//.WithTopSlotEpsilonGreedy(.2f)
|
//.WithTopSlotEpsilonGreedy(.2f)
|
||||||
.ExploitUntilModelReady(new ConstantPolicy<TestContext>()))
|
.ExploitUntilModelReady(new ConstantPolicy<TestContext>()))
|
||||||
{
|
{
|
||||||
chosenActions = ds.ChooseRanking(uniqueKey, new TestContext());
|
chosenActions = await ds.ChooseRankingAsync(uniqueKey, new TestContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.AreEqual(1, joinServer.RequestCount);
|
Assert.AreEqual(1, joinServer.RequestCount);
|
||||||
|
@ -177,7 +177,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public void TestMultiActionDSUploadMultipleEvents()
|
public async Task TestMultiActionDSUploadMultipleEvents()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -191,8 +191,8 @@ namespace ClientDecisionServiceTest
|
||||||
//.WithTopSlotEpsilonGreedy(.2f)
|
//.WithTopSlotEpsilonGreedy(.2f)
|
||||||
.ExploitUntilModelReady(new ConstantPolicy<TestContext>()))
|
.ExploitUntilModelReady(new ConstantPolicy<TestContext>()))
|
||||||
{
|
{
|
||||||
int[] chosenAction1 = ds.ChooseRanking(uniqueKey, new TestContext());
|
int[] chosenAction1 = await ds.ChooseRankingAsync(uniqueKey, new TestContext());
|
||||||
int[] chosenAction2 = ds.ChooseRanking(uniqueKey, new TestContext());
|
int[] chosenAction2 = await ds.ChooseRankingAsync(uniqueKey, new TestContext());
|
||||||
ds.ReportReward(1.0f, uniqueKey);
|
ds.ReportReward(1.0f, uniqueKey);
|
||||||
ds.ReportOutcome(new { value = "test outcome" }, uniqueKey);
|
ds.ReportOutcome(new { value = "test outcome" }, uniqueKey);
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public void TestMultiActionDSUploadSelective()
|
public async Task TestMultiActionDSUploadSelective()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ namespace ClientDecisionServiceTest
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numEvents; i++)
|
for (int i = 0; i < numEvents; i++)
|
||||||
{
|
{
|
||||||
int[] chosenAction1 = ds.ChooseRanking(uniqueKey, new TestContext());
|
int[] chosenAction1 = await ds.ChooseRankingAsync(uniqueKey, new TestContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Some events must have been dropped so the total count cannot be same as original
|
// Some events must have been dropped so the total count cannot be same as original
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public void TestDevModeSettingsAndExampleLog()
|
public async Task TestDevModeSettingsAndExampleLog()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ namespace ClientDecisionServiceTest
|
||||||
Random rg = new Random(i);
|
Random rg = new Random(i);
|
||||||
int numActions = rg.Next(5, 20);
|
int numActions = rg.Next(5, 20);
|
||||||
var context = TestADFContextWithFeatures.CreateRandom(numActions, rg);
|
var context = TestADFContextWithFeatures.CreateRandom(numActions, rg);
|
||||||
int[] action = ds.ChooseRanking(interId, context);
|
int[] action = await ds.ChooseRankingAsync(interId, context);
|
||||||
ds.ReportReward(i / 100f, obserId);
|
ds.ReportReward(i / 100f, obserId);
|
||||||
|
|
||||||
eventIdList.Add(interId);
|
eventIdList.Add(interId);
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(0)]
|
[Priority(0)]
|
||||||
public void InitialFullExplorationTest()
|
public async Task InitialFullExplorationTest()
|
||||||
{
|
{
|
||||||
var recorder = new MyRecorder();
|
var recorder = new MyRecorder();
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ namespace ClientDecisionServiceTest
|
||||||
|
|
||||||
using (var ds = DecisionService.CreateJson(config, metaData:metaData).WithRecorder(recorder))
|
using (var ds = DecisionService.CreateJson(config, metaData:metaData).WithRecorder(recorder))
|
||||||
{
|
{
|
||||||
var decision = ds.ChooseRanking("abc", "{\"a\":1,\"_multi\":[{\"b\":2}]}");
|
var decision = await ds.ChooseRankingAsync("abc", "{\"a\":1,\"_multi\":[{\"b\":2}]}");
|
||||||
|
|
||||||
// since there's not a model loaded why should get 100% exploration
|
// since there's not a model loaded why should get 100% exploration
|
||||||
// Assert.AreEqual(1f, recorder.LastExplorerState.Probability);
|
// Assert.AreEqual(1f, recorder.LastExplorerState.Probability);
|
||||||
|
@ -61,7 +61,7 @@ namespace ClientDecisionServiceTest
|
||||||
model.Position = 0;
|
model.Position = 0;
|
||||||
ds.UpdateModel(model);
|
ds.UpdateModel(model);
|
||||||
|
|
||||||
decision = ds.ChooseRanking("abc", "{\"a\":1,\"_multi\":[{\"b\":2}, {\"b\":3}]}");
|
decision = await ds.ChooseRankingAsync("abc", "{\"a\":1,\"_multi\":[{\"b\":2}, {\"b\":3}]}");
|
||||||
// Assert.AreNotEqual(1f, recorder.LastExplorerState.Probability);
|
// Assert.AreNotEqual(1f, recorder.LastExplorerState.Probability);
|
||||||
|
|
||||||
var vwState = recorder.LastMapperState as VWState;
|
var vwState = recorder.LastMapperState as VWState;
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace ClientDecisionServiceTest
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestDSLocalModelUpdate()
|
public async Task TestDSLocalModelUpdate()
|
||||||
{
|
{
|
||||||
string vwArgs = "--cb_explore_adf --epsilon 0.2 --cb_type dr -q ::";
|
string vwArgs = "--cb_explore_adf --epsilon 0.2 --cb_type dr -q ::";
|
||||||
DecisionServiceLocal<FoodContext> dsLocal = new DecisionServiceLocal<FoodContext>(vwArgs, 1, TimeSpan.MaxValue);
|
DecisionServiceLocal<FoodContext> dsLocal = new DecisionServiceLocal<FoodContext>(vwArgs, 1, TimeSpan.MaxValue);
|
||||||
|
@ -107,17 +107,17 @@ namespace ClientDecisionServiceTest
|
||||||
// Generate interactions and ensure the model updates at the right frequency
|
// Generate interactions and ensure the model updates at the right frequency
|
||||||
// (updates every example initially)
|
// (updates every example initially)
|
||||||
prevModel = dsLocal.Model;
|
prevModel = dsLocal.Model;
|
||||||
dsLocal.ChooseAction(guid1, context, 1);
|
await dsLocal.ChooseActionAsync(guid1, context, 1);
|
||||||
dsLocal.ReportRewardAndComplete((float)1.0, guid1);
|
dsLocal.ReportRewardAndComplete((float)1.0, guid1);
|
||||||
Assert.IsTrue(!dsLocal.Model.SequenceEqual(prevModel));
|
Assert.IsTrue(!dsLocal.Model.SequenceEqual(prevModel));
|
||||||
|
|
||||||
// Set the model to update every two examples
|
// Set the model to update every two examples
|
||||||
prevModel = dsLocal.Model;
|
prevModel = dsLocal.Model;
|
||||||
dsLocal.ModelUpdateInterval = 2;
|
dsLocal.ModelUpdateInterval = 2;
|
||||||
dsLocal.ChooseAction(guid1, context, 1);
|
await dsLocal.ChooseActionAsync(guid1, context, 1);
|
||||||
dsLocal.ReportRewardAndComplete((float)1.0, guid1);
|
dsLocal.ReportRewardAndComplete((float)1.0, guid1);
|
||||||
Assert.IsFalse(!dsLocal.Model.SequenceEqual(prevModel));
|
Assert.IsFalse(!dsLocal.Model.SequenceEqual(prevModel));
|
||||||
dsLocal.ChooseAction(guid2, context, 1);
|
await dsLocal.ChooseActionAsync(guid2, context, 1);
|
||||||
dsLocal.ReportRewardAndComplete((float)2.0, guid1);
|
dsLocal.ReportRewardAndComplete((float)2.0, guid1);
|
||||||
Assert.IsTrue(!dsLocal.Model.SequenceEqual(prevModel));
|
Assert.IsTrue(!dsLocal.Model.SequenceEqual(prevModel));
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public void TestRcv1ModelUpdateFromStream()
|
public async Task TestRcv1ModelUpdateFromStream()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ namespace ClientDecisionServiceTest
|
||||||
|
|
||||||
DateTime timeStamp = DateTime.UtcNow;
|
DateTime timeStamp = DateTime.UtcNow;
|
||||||
|
|
||||||
int action = ds.ChooseAction(uniqueKey, context);
|
int action = await ds.ChooseActionAsync(uniqueKey, context);
|
||||||
|
|
||||||
// verify the actions are in the expected range
|
// verify the actions are in the expected range
|
||||||
Assert.IsTrue(action >= 1 && action <= numActions);
|
Assert.IsTrue(action >= 1 && action <= numActions);
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using VW.Serializer;
|
using VW.Serializer;
|
||||||
using Microsoft.Research.MultiWorldTesting.Contract;
|
using Microsoft.Research.MultiWorldTesting.Contract;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ClientDecisionServiceTest
|
namespace ClientDecisionServiceTest
|
||||||
{
|
{
|
||||||
|
@ -36,7 +37,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(0)]
|
[Priority(0)]
|
||||||
public void TestSingleActionOfflineModeCustomLogger()
|
public async Task TestSingleActionOfflineModeCustomLogger()
|
||||||
{
|
{
|
||||||
var dsConfig = new DecisionServiceConfiguration("") { OfflineMode = true, OfflineApplicationID = "" };
|
var dsConfig = new DecisionServiceConfiguration("") { OfflineMode = true, OfflineApplicationID = "" };
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ namespace ClientDecisionServiceTest
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numChooseAction; i++)
|
for (int i = 0; i < numChooseAction; i++)
|
||||||
{
|
{
|
||||||
ds.ChooseAction(i.ToString(), new TestContext());
|
await ds.ChooseActionAsync(i.ToString(), new TestContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.AreEqual(numChooseAction, recorder.NumRecord);
|
Assert.AreEqual(numChooseAction, recorder.NumRecord);
|
||||||
|
@ -85,7 +86,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
[Ignore]
|
[Ignore]
|
||||||
public void TestSingleActionOnlineModeCustomLogger()
|
public async Task TestSingleActionOnlineModeCustomLogger()
|
||||||
{
|
{
|
||||||
var dsConfig = new DecisionServiceConfiguration(MockCommandCenter.SettingsBlobUri)
|
var dsConfig = new DecisionServiceConfiguration(MockCommandCenter.SettingsBlobUri)
|
||||||
{
|
{
|
||||||
|
@ -103,7 +104,7 @@ namespace ClientDecisionServiceTest
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numChooseAction; i++)
|
for (int i = 0; i < numChooseAction; i++)
|
||||||
{
|
{
|
||||||
ds.ChooseAction(i.ToString(), new TestContext());
|
await ds.ChooseActionAsync(i.ToString(), new TestContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.AreEqual(numChooseAction, recorder.NumRecord);
|
Assert.AreEqual(numChooseAction, recorder.NumRecord);
|
||||||
|
@ -134,7 +135,7 @@ namespace ClientDecisionServiceTest
|
||||||
[ExpectedException(typeof(Exception))]
|
[ExpectedException(typeof(Exception))]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(0)]
|
[Priority(0)]
|
||||||
public void TestMultiActionOfflineModeArgument()
|
public async Task TestMultiActionOfflineModeArgument()
|
||||||
{
|
{
|
||||||
var metaData = new ApplicationClientMetadata
|
var metaData = new ApplicationClientMetadata
|
||||||
{
|
{
|
||||||
|
@ -145,14 +146,14 @@ namespace ClientDecisionServiceTest
|
||||||
new DecisionServiceConfiguration("") { OfflineMode = true, OfflineApplicationID = "" },
|
new DecisionServiceConfiguration("") { OfflineMode = true, OfflineApplicationID = "" },
|
||||||
metaData))
|
metaData))
|
||||||
{
|
{
|
||||||
ds.ChooseAction("", "{}");
|
await ds.ChooseActionAsync("", "{}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(0)]
|
[Priority(0)]
|
||||||
public void TestMultiActionOfflineModeCustomLogger()
|
public async Task TestMultiActionOfflineModeCustomLogger()
|
||||||
{
|
{
|
||||||
var dsConfig = new DecisionServiceConfiguration("") { OfflineMode = true, OfflineApplicationID = "" };
|
var dsConfig = new DecisionServiceConfiguration("") { OfflineMode = true, OfflineApplicationID = "" };
|
||||||
var metaData = new ApplicationClientMetadata
|
var metaData = new ApplicationClientMetadata
|
||||||
|
@ -168,7 +169,7 @@ namespace ClientDecisionServiceTest
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numChooseAction; i++)
|
for (int i = 0; i < numChooseAction; i++)
|
||||||
{
|
{
|
||||||
ds.ChooseAction(i.ToString(), new TestContext());
|
await ds.ChooseActionAsync(i.ToString(), new TestContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.AreEqual(numChooseAction, recorder.NumRecord);
|
Assert.AreEqual(numChooseAction, recorder.NumRecord);
|
||||||
|
@ -197,7 +198,7 @@ namespace ClientDecisionServiceTest
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("Client Library")]
|
[TestCategory("Client Library")]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public void TestMultiActionOnlineModeCustomLogger()
|
public async Task TestMultiActionOnlineModeCustomLogger()
|
||||||
{
|
{
|
||||||
joinServer.Reset();
|
joinServer.Reset();
|
||||||
|
|
||||||
|
@ -216,7 +217,7 @@ namespace ClientDecisionServiceTest
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numChooseAction; i++)
|
for (int i = 0; i < numChooseAction; i++)
|
||||||
{
|
{
|
||||||
ds.ChooseAction(i.ToString(), new TestContext());
|
await ds.ChooseActionAsync(i.ToString(), new TestContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.AreEqual(numChooseAction, recorder.NumRecord);
|
Assert.AreEqual(numChooseAction, recorder.NumRecord);
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<runtime>
|
<runtime>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-5.8.1.0" newVersion="5.8.1.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="VowpalWabbit.Core" publicKeyToken="a76afd1645210483" culture="neutral"/>
|
<assemblyIdentity name="VowpalWabbit.Core" publicKeyToken="a76afd1645210483" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="VowpalWabbit" publicKeyToken="a76afd1645210483" culture="neutral"/>
|
<assemblyIdentity name="VowpalWabbit" publicKeyToken="a76afd1645210483" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="VowpalWabbit.Common" publicKeyToken="a76afd1645210483" culture="neutral"/>
|
<assemblyIdentity name="VowpalWabbit.Common" publicKeyToken="a76afd1645210483" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-8.4.0.0" newVersion="8.4.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.ApplicationInsights" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.ApplicationInsights" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
|
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>
|
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration>
|
||||||
|
|
|
@ -7,18 +7,34 @@ using VW.Serializer;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for all Vowpal Wabbit contenxt mappers.
|
||||||
|
/// </summary>
|
||||||
public abstract class VWBaseContextMapper<TVowpalWabbit, TContext, TAction>
|
public abstract class VWBaseContextMapper<TVowpalWabbit, TContext, TAction>
|
||||||
: IUpdatable<Stream>, IDisposable, IContextMapper<TContext, TAction>
|
: IUpdatable<Stream>, IDisposable, IContextMapper<TContext, TAction>
|
||||||
where TVowpalWabbit : class, IDisposable
|
where TVowpalWabbit : class, IDisposable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Type inspector used to extract schema information.
|
||||||
|
/// </summary>
|
||||||
protected ITypeInspector typeInspector;
|
protected ITypeInspector typeInspector;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The pool of VW objects.
|
||||||
|
/// </summary>
|
||||||
protected VowpalWabbitThreadedPredictionBase<TVowpalWabbit> vwPool;
|
protected VowpalWabbitThreadedPredictionBase<TVowpalWabbit> vwPool;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// True if development mode enabled (additional logging).
|
||||||
|
/// </summary>
|
||||||
protected bool developmentMode;
|
protected bool developmentMode;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor using a memory stream.
|
/// Constructor using a memory stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vwModelStream">The VW model memory stream.</param>
|
/// <param name="vwModelStream">The VW model memory stream.</param>
|
||||||
|
/// <param name="developmentMode">True if development mode enabled (additional logging).</param>
|
||||||
|
/// <param name="typeInspector">Type inspector used to extract schema information.</param>
|
||||||
protected VWBaseContextMapper(
|
protected VWBaseContextMapper(
|
||||||
Stream vwModelStream = null,
|
Stream vwModelStream = null,
|
||||||
ITypeInspector typeInspector = null,
|
ITypeInspector typeInspector = null,
|
||||||
|
@ -86,6 +102,13 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the action to take for a given context.
|
||||||
|
/// This implementation should be thread-safe if multithreading is needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">A user-defined context for the decision.</param>
|
||||||
|
/// <returns>A decision tuple containing the index of the action to take (1-based), and the Id of the model or policy used to make the decision.
|
||||||
|
/// Can be null if the Policy is not ready yet (e.g. model not loaded).</returns>
|
||||||
public Task<PolicyDecision<TAction>> MapContextAsync(TContext context)
|
public Task<PolicyDecision<TAction>> MapContextAsync(TContext context)
|
||||||
{
|
{
|
||||||
if (this.vwPool == null)
|
if (this.vwPool == null)
|
||||||
|
@ -100,8 +123,19 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sub classes must override and create a new VW pool.
|
||||||
|
/// </summary>
|
||||||
protected abstract VowpalWabbitThreadedPredictionBase<TVowpalWabbit> CreatePool(VowpalWabbitSettings settings);
|
protected abstract VowpalWabbitThreadedPredictionBase<TVowpalWabbit> CreatePool(VowpalWabbitSettings settings);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the action to take for a given context.
|
||||||
|
/// This implementation should be thread-safe if multithreading is needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vw">The Vowpal Wabbit instance to use.</param>
|
||||||
|
/// <param name="context">A user-defined context for the decision.</param>
|
||||||
|
/// <returns>A decision tuple containing the index of the action to take (1-based), and the Id of the model or policy used to make the decision.
|
||||||
|
/// Can be null if the Policy is not ready yet (e.g. model not loaded).</returns>
|
||||||
protected abstract PolicyDecision<TAction> MapContext(TVowpalWabbit vw, TContext context);
|
protected abstract PolicyDecision<TAction> MapContext(TVowpalWabbit vw, TContext context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@ using VW.Serializer;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Vowpal Wabbit based explorer using C# based features.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TContext"></typeparam>
|
||||||
public sealed class VWExplorer<TContext> :
|
public sealed class VWExplorer<TContext> :
|
||||||
VWBaseContextMapper<VowpalWabbit<TContext>, TContext, ActionProbability[]>,
|
VWBaseContextMapper<VowpalWabbit<TContext>, TContext, ActionProbability[]>,
|
||||||
IContextMapper<TContext, ActionProbability[]>, INumberOfActionsProvider<TContext>
|
IContextMapper<TContext, ActionProbability[]>, INumberOfActionsProvider<TContext>
|
||||||
|
@ -18,7 +22,6 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor using a memory stream.
|
/// Constructor using a memory stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vwModelStream">The VW model memory stream.</param>
|
|
||||||
public VWExplorer(Stream vwModelStream = null, ITypeInspector typeInspector = null, bool developmentMode = false)
|
public VWExplorer(Stream vwModelStream = null, ITypeInspector typeInspector = null, bool developmentMode = false)
|
||||||
: base(vwModelStream, typeInspector, developmentMode)
|
: base(vwModelStream, typeInspector, developmentMode)
|
||||||
{
|
{
|
||||||
|
@ -32,11 +35,22 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
this.multiSerializer = this.serializer as IVowpalWabbitMultiExampleSerializerCompiler<TContext>;
|
this.multiSerializer = this.serializer as IVowpalWabbitMultiExampleSerializerCompiler<TContext>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sub classes must override and create a new VW pool.
|
||||||
|
/// </summary>
|
||||||
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit<TContext>> CreatePool(VowpalWabbitSettings settings)
|
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit<TContext>> CreatePool(VowpalWabbitSettings settings)
|
||||||
{
|
{
|
||||||
return new VowpalWabbitThreadedPrediction<TContext>(settings);
|
return new VowpalWabbitThreadedPrediction<TContext>(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the action to take for a given context.
|
||||||
|
/// This implementation should be thread-safe if multithreading is needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vw">The Vowpal Wabbit instance to use.</param>
|
||||||
|
/// <param name="context">A user-defined context for the decision.</param>
|
||||||
|
/// <returns>A decision tuple containing the index of the action to take (1-based), and the Id of the model or policy used to make the decision.
|
||||||
|
/// Can be null if the Policy is not ready yet (e.g. model not loaded).</returns>
|
||||||
protected override PolicyDecision<ActionProbability[]> MapContext(VowpalWabbit<TContext> vw, TContext context)
|
protected override PolicyDecision<ActionProbability[]> MapContext(VowpalWabbit<TContext> vw, TContext context)
|
||||||
{
|
{
|
||||||
if (this.developmentMode)
|
if (this.developmentMode)
|
||||||
|
@ -63,6 +77,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
return PolicyDecision.Create(ap, state);
|
return PolicyDecision.Create(ap, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the number of actions defined by this context.
|
||||||
|
/// </summary>
|
||||||
public int GetNumberOfActions(TContext context)
|
public int GetNumberOfActions(TContext context)
|
||||||
{
|
{
|
||||||
if (this.multiSerializer == null)
|
if (this.multiSerializer == null)
|
||||||
|
|
|
@ -7,15 +7,29 @@ using System;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Vowpal Wabbit based policy for string JSON based context.
|
||||||
|
/// </summary>
|
||||||
public class VWJsonPolicy :
|
public class VWJsonPolicy :
|
||||||
VWBaseContextMapper<VowpalWabbit, string, int>,
|
VWBaseContextMapper<VowpalWabbit, string, int>,
|
||||||
IPolicy<string>
|
IPolicy<string>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance.
|
||||||
|
/// </summary>
|
||||||
public VWJsonPolicy(Stream vwModelStream = null)
|
public VWJsonPolicy(Stream vwModelStream = null)
|
||||||
: base(vwModelStream)
|
: base(vwModelStream)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the action to take for a given context.
|
||||||
|
/// This implementation should be thread-safe if multithreading is needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vw">The Vowpal Wabbit instance to use.</param>
|
||||||
|
/// <param name="context">A user-defined context for the decision.</param>
|
||||||
|
/// <returns>A decision tuple containing the index of the action to take (1-based), and the Id of the model or policy used to make the decision.
|
||||||
|
/// Can be null if the Policy is not ready yet (e.g. model not loaded).</returns>
|
||||||
protected override PolicyDecision<int> MapContext(VowpalWabbit vw, string context)
|
protected override PolicyDecision<int> MapContext(VowpalWabbit vw, string context)
|
||||||
{
|
{
|
||||||
using (var vwJson = new VowpalWabbitJsonSerializer(vw))
|
using (var vwJson = new VowpalWabbitJsonSerializer(vw))
|
||||||
|
@ -28,26 +42,46 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sub classes must override and create a new VW pool.
|
||||||
|
/// </summary>
|
||||||
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit> CreatePool(VowpalWabbitSettings settings)
|
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit> CreatePool(VowpalWabbitSettings settings)
|
||||||
{
|
{
|
||||||
return new VowpalWabbitThreadedPrediction(settings);
|
return new VowpalWabbitThreadedPrediction(settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Vowpal Wabbit based ranker for string JSON based context.
|
||||||
|
/// </summary>
|
||||||
public class VWJsonRanker :
|
public class VWJsonRanker :
|
||||||
VWBaseContextMapper<VowpalWabbit, string, int[]>,
|
VWBaseContextMapper<VowpalWabbit, string, int[]>,
|
||||||
IRanker<string>, INumberOfActionsProvider<string>
|
IRanker<string>, INumberOfActionsProvider<string>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance.
|
||||||
|
/// </summary>
|
||||||
public VWJsonRanker(Stream vwModelStream = null)
|
public VWJsonRanker(Stream vwModelStream = null)
|
||||||
: base(vwModelStream)
|
: base(vwModelStream)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sub classes must override and create a new VW pool.
|
||||||
|
/// </summary>
|
||||||
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit> CreatePool(VowpalWabbitSettings settings)
|
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit> CreatePool(VowpalWabbitSettings settings)
|
||||||
{
|
{
|
||||||
return new VowpalWabbitThreadedPrediction(settings);
|
return new VowpalWabbitThreadedPrediction(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the action to take for a given context.
|
||||||
|
/// This implementation should be thread-safe if multithreading is needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vw">The Vowpal Wabbit instance to use.</param>
|
||||||
|
/// <param name="context">A user-defined context for the decision.</param>
|
||||||
|
/// <returns>A decision tuple containing the index of the action to take (1-based), and the Id of the model or policy used to make the decision.
|
||||||
|
/// Can be null if the Policy is not ready yet (e.g. model not loaded).</returns>
|
||||||
protected override PolicyDecision<int[]> MapContext(VowpalWabbit vw, string context)
|
protected override PolicyDecision<int[]> MapContext(VowpalWabbit vw, string context)
|
||||||
{
|
{
|
||||||
using (var vwJson = new VowpalWabbitJsonSerializer(vw))
|
using (var vwJson = new VowpalWabbitJsonSerializer(vw))
|
||||||
|
@ -63,6 +97,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the number of actions defined by this context.
|
||||||
|
/// </summary>
|
||||||
public int GetNumberOfActions(string context)
|
public int GetNumberOfActions(string context)
|
||||||
{
|
{
|
||||||
return VowpalWabbitJsonSerializer.GetNumberOfActionDependentExamples(context);
|
return VowpalWabbitJsonSerializer.GetNumberOfActionDependentExamples(context);
|
||||||
|
|
|
@ -11,20 +11,37 @@ using VW.Serializer;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Vowpal Wabbit based explorer for JSON context.
|
||||||
|
/// </summary>
|
||||||
public sealed class VWJsonExplorer :
|
public sealed class VWJsonExplorer :
|
||||||
VWBaseContextMapper<VowpalWabbit, string, ActionProbability[]>,
|
VWBaseContextMapper<VowpalWabbit, string, ActionProbability[]>,
|
||||||
IContextMapper<string, ActionProbability[]>, INumberOfActionsProvider<string>
|
IContextMapper<string, ActionProbability[]>, INumberOfActionsProvider<string>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance.
|
||||||
|
/// </summary>
|
||||||
public VWJsonExplorer(Stream vwModelStream = null, bool developmentMode = false)
|
public VWJsonExplorer(Stream vwModelStream = null, bool developmentMode = false)
|
||||||
: base(vwModelStream, developmentMode: developmentMode)
|
: base(vwModelStream, developmentMode: developmentMode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sub classes must override and create a new VW pool.
|
||||||
|
/// </summary>
|
||||||
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit> CreatePool(VowpalWabbitSettings settings)
|
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit> CreatePool(VowpalWabbitSettings settings)
|
||||||
{
|
{
|
||||||
return new VowpalWabbitThreadedPrediction(settings);
|
return new VowpalWabbitThreadedPrediction(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the action to take for a given context.
|
||||||
|
/// This implementation should be thread-safe if multithreading is needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vw">The Vowpal Wabbit instance to use.</param>
|
||||||
|
/// <param name="context">A user-defined context for the decision.</param>
|
||||||
|
/// <returns>A decision tuple containing the index of the action to take (1-based), and the Id of the model or policy used to make the decision.
|
||||||
|
/// Can be null if the Policy is not ready yet (e.g. model not loaded).</returns>
|
||||||
protected override PolicyDecision<ActionProbability[]> MapContext(VowpalWabbit vw, string context)
|
protected override PolicyDecision<ActionProbability[]> MapContext(VowpalWabbit vw, string context)
|
||||||
{
|
{
|
||||||
using (var vwJson = new VowpalWabbitJsonSerializer(vw))
|
using (var vwJson = new VowpalWabbitJsonSerializer(vw))
|
||||||
|
@ -50,6 +67,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the number of actions defined by this context.
|
||||||
|
/// </summary>
|
||||||
public int GetNumberOfActions(string context)
|
public int GetNumberOfActions(string context)
|
||||||
{
|
{
|
||||||
return VowpalWabbitJsonSerializer.GetNumberOfActionDependentExamples(context);
|
return VowpalWabbitJsonSerializer.GetNumberOfActionDependentExamples(context);
|
||||||
|
|
|
@ -6,23 +6,37 @@ using VW.Serializer;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Vowpal Wabbit based policy.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TContext"></typeparam>
|
||||||
public class VWPolicy<TContext>
|
public class VWPolicy<TContext>
|
||||||
: VWBaseContextMapper<VowpalWabbit<TContext>, TContext, int>, IPolicy<TContext>
|
: VWBaseContextMapper<VowpalWabbit<TContext>, TContext, int>, IPolicy<TContext>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor using a memory stream.
|
/// Constructor using a memory stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vwModelStream">The VW model memory stream.</param>
|
|
||||||
public VWPolicy(Stream vwModelStream = null, ITypeInspector typeInspector = null, bool developmentMode = false)
|
public VWPolicy(Stream vwModelStream = null, ITypeInspector typeInspector = null, bool developmentMode = false)
|
||||||
: base(vwModelStream, typeInspector, developmentMode)
|
: base(vwModelStream, typeInspector, developmentMode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sub classes must override and create a new VW pool.
|
||||||
|
/// </summary>
|
||||||
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit<TContext>> CreatePool(VowpalWabbitSettings settings)
|
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit<TContext>> CreatePool(VowpalWabbitSettings settings)
|
||||||
{
|
{
|
||||||
return new VowpalWabbitThreadedPrediction<TContext>(settings);
|
return new VowpalWabbitThreadedPrediction<TContext>(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the action to take for a given context.
|
||||||
|
/// This implementation should be thread-safe if multithreading is needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vw">The Vowpal Wabbit instance to use.</param>
|
||||||
|
/// <param name="context">A user-defined context for the decision.</param>
|
||||||
|
/// <returns>A decision tuple containing the index of the action to take (1-based), and the Id of the model or policy used to make the decision.
|
||||||
|
/// Can be null if the Policy is not ready yet (e.g. model not loaded).</returns>
|
||||||
protected override PolicyDecision<int> MapContext(VowpalWabbit<TContext> vw, TContext context)
|
protected override PolicyDecision<int> MapContext(VowpalWabbit<TContext> vw, TContext context)
|
||||||
{
|
{
|
||||||
if (this.developmentMode)
|
if (this.developmentMode)
|
||||||
|
|
|
@ -9,6 +9,10 @@ using VW.Serializer;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Vowpal Wabbit based ranker.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TContext"></typeparam>
|
||||||
public class VWRanker<TContext> :
|
public class VWRanker<TContext> :
|
||||||
VWBaseContextMapper<VowpalWabbit<TContext>, TContext, int[]>,
|
VWBaseContextMapper<VowpalWabbit<TContext>, TContext, int[]>,
|
||||||
IRanker<TContext>, INumberOfActionsProvider<TContext>
|
IRanker<TContext>, INumberOfActionsProvider<TContext>
|
||||||
|
@ -18,7 +22,6 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor using a memory stream.
|
/// Constructor using a memory stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vwModelStream">The VW model memory stream.</param>
|
|
||||||
public VWRanker(Stream vwModelStream = null, ITypeInspector typeInspector = null, bool developmentMode = false)
|
public VWRanker(Stream vwModelStream = null, ITypeInspector typeInspector = null, bool developmentMode = false)
|
||||||
: base(vwModelStream, typeInspector, developmentMode)
|
: base(vwModelStream, typeInspector, developmentMode)
|
||||||
{
|
{
|
||||||
|
@ -30,11 +33,22 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
}) as IVowpalWabbitMultiExampleSerializerCompiler<TContext>;
|
}) as IVowpalWabbitMultiExampleSerializerCompiler<TContext>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sub classes must override and create a new VW pool.
|
||||||
|
/// </summary>
|
||||||
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit<TContext>> CreatePool(VowpalWabbitSettings settings)
|
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit<TContext>> CreatePool(VowpalWabbitSettings settings)
|
||||||
{
|
{
|
||||||
return new VowpalWabbitThreadedPrediction<TContext>(settings);
|
return new VowpalWabbitThreadedPrediction<TContext>(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the action to take for a given context.
|
||||||
|
/// This implementation should be thread-safe if multithreading is needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vw">The Vowpal Wabbit instance to use.</param>
|
||||||
|
/// <param name="context">A user-defined context for the decision.</param>
|
||||||
|
/// <returns>A decision tuple containing the index of the action to take (1-based), and the Id of the model or policy used to make the decision.
|
||||||
|
/// Can be null if the Policy is not ready yet (e.g. model not loaded).</returns>
|
||||||
protected override PolicyDecision<int[]> MapContext(VowpalWabbit<TContext> vw, TContext context)
|
protected override PolicyDecision<int[]> MapContext(VowpalWabbit<TContext> vw, TContext context)
|
||||||
{
|
{
|
||||||
if (this.developmentMode)
|
if (this.developmentMode)
|
||||||
|
@ -54,12 +68,19 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
return PolicyDecision.Create(actions, state);
|
return PolicyDecision.Create(actions, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the number of actions defined by this context.
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
public int GetNumberOfActions(TContext context)
|
public int GetNumberOfActions(TContext context)
|
||||||
{
|
{
|
||||||
return this.serializer.GetNumberOfActionDependentExamples(context);
|
return this.serializer.GetNumberOfActionDependentExamples(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Vowpal Wabbit based ranker using C# defined context and action dependent features.
|
||||||
|
/// </summary>
|
||||||
public class VWRanker<TContext, TActionDependentFeature> :
|
public class VWRanker<TContext, TActionDependentFeature> :
|
||||||
VWBaseContextMapper<VowpalWabbit<TContext, TActionDependentFeature>, TContext, int[]>,
|
VWBaseContextMapper<VowpalWabbit<TContext, TActionDependentFeature>, TContext, int[]>,
|
||||||
IRanker<TContext>, INumberOfActionsProvider<TContext>
|
IRanker<TContext>, INumberOfActionsProvider<TContext>
|
||||||
|
@ -69,7 +90,6 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor using a memory stream.
|
/// Constructor using a memory stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vwModelStream">The VW model memory stream.</param>
|
|
||||||
public VWRanker(
|
public VWRanker(
|
||||||
Func<TContext, IReadOnlyCollection<TActionDependentFeature>> getContextFeaturesFunc,
|
Func<TContext, IReadOnlyCollection<TActionDependentFeature>> getContextFeaturesFunc,
|
||||||
Stream vwModelStream = null,
|
Stream vwModelStream = null,
|
||||||
|
@ -80,11 +100,22 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
this.getContextFeaturesFunc = getContextFeaturesFunc;
|
this.getContextFeaturesFunc = getContextFeaturesFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sub classes must override and create a new VW pool.
|
||||||
|
/// </summary>
|
||||||
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit<TContext, TActionDependentFeature>> CreatePool(VowpalWabbitSettings settings)
|
protected override VowpalWabbitThreadedPredictionBase<VowpalWabbit<TContext, TActionDependentFeature>> CreatePool(VowpalWabbitSettings settings)
|
||||||
{
|
{
|
||||||
return new VowpalWabbitThreadedPrediction<TContext, TActionDependentFeature>(settings);
|
return new VowpalWabbitThreadedPrediction<TContext, TActionDependentFeature>(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the action to take for a given context.
|
||||||
|
/// This implementation should be thread-safe if multithreading is needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vw">The Vowpal Wabbit instance to use.</param>
|
||||||
|
/// <param name="context">A user-defined context for the decision.</param>
|
||||||
|
/// <returns>A decision tuple containing the index of the action to take (1-based), and the Id of the model or policy used to make the decision.
|
||||||
|
/// Can be null if the Policy is not ready yet (e.g. model not loaded).</returns>
|
||||||
protected override PolicyDecision<int[]> MapContext(VowpalWabbit<TContext, TActionDependentFeature> vw, TContext context)
|
protected override PolicyDecision<int[]> MapContext(VowpalWabbit<TContext, TActionDependentFeature> vw, TContext context)
|
||||||
{
|
{
|
||||||
if (this.developmentMode)
|
if (this.developmentMode)
|
||||||
|
@ -104,6 +135,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
return PolicyDecision.Create(actions, state);
|
return PolicyDecision.Create(actions, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the number of actions defined by this context.
|
||||||
|
/// </summary>
|
||||||
public int GetNumberOfActions(TContext context)
|
public int GetNumberOfActions(TContext context)
|
||||||
{
|
{
|
||||||
var adfs = this.getContextFeaturesFunc(context);
|
var adfs = this.getContextFeaturesFunc(context);
|
||||||
|
|
|
@ -7,9 +7,15 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
namespace Microsoft.Research.MultiWorldTesting.ClientLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the policy state for a VowpalWabbit model.
|
||||||
|
/// </summary>
|
||||||
[JsonObject(Id = "stvw")]
|
[JsonObject(Id = "stvw")]
|
||||||
public class VWState
|
public class VWState
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The model id used at scoring time.
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("m")]
|
[JsonProperty("m")]
|
||||||
public string ModelId { get; set; }
|
public string ModelId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,17 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly BatchingConfiguration batchConfig;
|
protected readonly BatchingConfiguration batchConfig;
|
||||||
private readonly CancellationTokenSource cancellationTokenSource;
|
private readonly CancellationTokenSource cancellationTokenSource;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cancellation token used for shutdown
|
||||||
|
/// </summary>
|
||||||
protected CancellationToken cancellationToken;
|
protected CancellationToken cancellationToken;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs an uploader object.
|
/// Constructs an uploader object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="batchConfig">Optional; The batching configuration that controls the buffer size.</param>
|
/// <param name="batchConfig">Optional; The batching configuration that controls the buffer size.</param>
|
||||||
|
/// <param name="developmentMode">If true, enables additional logging and disables batching.</param>
|
||||||
public BaseEventUploader(BatchingConfiguration batchConfig = null, bool developmentMode = false)
|
public BaseEventUploader(BatchingConfiguration batchConfig = null, bool developmentMode = false)
|
||||||
{
|
{
|
||||||
this.cancellationTokenSource = new CancellationTokenSource();
|
this.cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
@ -96,6 +101,9 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventUploaderSuccessEventHandler SuccessHandler;
|
public event EventUploaderSuccessEventHandler SuccessHandler;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke when a batch completed.
|
||||||
|
/// </summary>
|
||||||
public event EventUploaderCompletedEventHandler CompletionHandler;
|
public event EventUploaderCompletedEventHandler CompletionHandler;
|
||||||
|
|
||||||
internal void FireErrorHandler(Exception e)
|
internal void FireErrorHandler(Exception e)
|
||||||
|
|
|
@ -6,10 +6,19 @@ using System.Threading.Tasks.Dataflow;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate definition for success.
|
||||||
|
/// </summary>
|
||||||
public delegate void EventUploaderSuccessEventHandler(object source, int eventCount, int sumSize, int inputQueueSize);
|
public delegate void EventUploaderSuccessEventHandler(object source, int eventCount, int sumSize, int inputQueueSize);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate definition for error.
|
||||||
|
/// </summary>
|
||||||
public delegate void EventUploaderErrorEventHandler(object source, Exception e);
|
public delegate void EventUploaderErrorEventHandler(object source, Exception e);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate definition for completion.
|
||||||
|
/// </summary>
|
||||||
public delegate void EventUploaderCompletedEventHandler(object source, string blockName, Task task);
|
public delegate void EventUploaderCompletedEventHandler(object source, string blockName, Task task);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
||||||
/// <param name="batchConfig">Optional; The batching configuration that controls the buffer size.</param>
|
/// <param name="batchConfig">Optional; The batching configuration that controls the buffer size.</param>
|
||||||
/// <param name="loggingServiceBaseAddress">Optional; The address of a custom HTTP logging service. When null, the join service address is used.</param>
|
/// <param name="loggingServiceBaseAddress">Optional; The address of a custom HTTP logging service. When null, the join service address is used.</param>
|
||||||
/// <param name="httpClient">Optional; The custom <see cref="IHttpClient"/> object to handle HTTP requests.</param>
|
/// <param name="httpClient">Optional; The custom <see cref="IHttpClient"/> object to handle HTTP requests.</param>
|
||||||
|
/// <param name="developmentMode">If true, enables additional logging and disables batching.</param>
|
||||||
public EventUploader(BatchingConfiguration batchConfig = null, string loggingServiceBaseAddress = null, IHttpClient httpClient = null, bool developmentMode = false)
|
public EventUploader(BatchingConfiguration batchConfig = null, string loggingServiceBaseAddress = null, IHttpClient httpClient = null, bool developmentMode = false)
|
||||||
: base(batchConfig, developmentMode)
|
: base(batchConfig, developmentMode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="eventHubConnectionString">The Azure Stream Analytics connection string.</param>
|
/// <param name="eventHubConnectionString">The Azure Stream Analytics connection string.</param>
|
||||||
/// <param name="batchConfig">Optional; The batching configuration to used when uploading data.</param>
|
/// <param name="batchConfig">Optional; The batching configuration to used when uploading data.</param>
|
||||||
|
/// <param name="developmentMode">If true, enables additional logging and disables batching.</param>
|
||||||
public EventUploaderASA
|
public EventUploaderASA
|
||||||
(
|
(
|
||||||
string eventHubConnectionString,
|
string eventHubConnectionString,
|
||||||
|
@ -126,7 +127,7 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Uploads a single event to EventHub asynchronously.
|
/// Uploads a single event to EventHub asynchronously.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="events">The event to upload.</param>
|
/// <param name="evt">The event to upload.</param>
|
||||||
/// <returns>A Task object.</returns>
|
/// <returns>A Task object.</returns>
|
||||||
private Task UploadToEventHubAsync(EventData evt)
|
private Task UploadToEventHubAsync(EventData evt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,17 +30,34 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
// int, int[]
|
/// <summary>
|
||||||
|
/// The action or ranking (int, int[])
|
||||||
|
/// </summary>
|
||||||
public object Value { get; set; }
|
public object Value { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The supplied context.
|
||||||
|
/// </summary>
|
||||||
public object Context { get; set; }
|
public object Context { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The state of the explorer (e.g. model id to be able to correlate back).
|
||||||
|
/// </summary>
|
||||||
public object ExplorerState { get; set; }
|
public object ExplorerState { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The state of the mapper (e.g. model id to be able to correlate back).
|
||||||
|
/// </summary>
|
||||||
public object MapperState { get; set; }
|
public object MapperState { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If pipeline overflows, we drop stochastically.
|
||||||
|
/// </summary>
|
||||||
public float? ProbabilityOfDrop { get; set; }
|
public float? ProbabilityOfDrop { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create epsilon greedy interaction???
|
||||||
|
/// </summary>
|
||||||
public static Interaction CreateEpsilonGreedy<TContext>(string key, TContext context, int action, float probability)
|
public static Interaction CreateEpsilonGreedy<TContext>(string key, TContext context, int action, float probability)
|
||||||
{
|
{
|
||||||
return Interaction.Create(key, context, action, new GenericExplorerState { Probability = probability });
|
return Interaction.Create(key, context, action, new GenericExplorerState { Probability = probability });
|
||||||
|
|
|
@ -58,6 +58,9 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event EventUploaderSuccessEventHandler SuccessHandler;
|
event EventUploaderSuccessEventHandler SuccessHandler;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked on pipeline completion.
|
||||||
|
/// </summary>
|
||||||
event EventUploaderCompletedEventHandler CompletionHandler;
|
event EventUploaderCompletedEventHandler CompletionHandler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,30 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
namespace Microsoft.Research.MultiWorldTesting.JoinUploader
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Custom JSON.NET serializer for interactions.
|
||||||
|
/// </summary>
|
||||||
public class InteractionJsonConverter : JsonConverter
|
public class InteractionJsonConverter : JsonConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// True, if it's an interaction type.
|
||||||
|
/// </summary>
|
||||||
public override bool CanConvert(Type objectType)
|
public override bool CanConvert(Type objectType)
|
||||||
{
|
{
|
||||||
return objectType == typeof(Interaction);
|
return objectType == typeof(Interaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not supported.
|
||||||
|
/// </summary>
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Serializes the interaction.
|
||||||
|
/// </summary>
|
||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
var v = value as Interaction;
|
var v = value as Interaction;
|
||||||
|
|
|
@ -6,18 +6,44 @@
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.Contract
|
namespace Microsoft.Research.MultiWorldTesting.Contract
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Various blob and container blob names
|
||||||
|
/// </summary>
|
||||||
public class ApplicationBlobConstants
|
public class ApplicationBlobConstants
|
||||||
{
|
{
|
||||||
// Model blobs
|
/// <summary>
|
||||||
|
/// Container name for models.
|
||||||
|
/// </summary>
|
||||||
public const string ModelContainerName = "mwt-models";
|
public const string ModelContainerName = "mwt-models";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blob name for latest model.
|
||||||
|
/// </summary>
|
||||||
public const string LatestModelBlobName = "current";
|
public const string LatestModelBlobName = "current";
|
||||||
|
|
||||||
// Settings blobs
|
/// <summary>
|
||||||
|
/// Container name for settings.
|
||||||
|
/// </summary>
|
||||||
public const string SettingsContainerName = "mwt-settings";
|
public const string SettingsContainerName = "mwt-settings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blob name for client settings.
|
||||||
|
/// </summary>
|
||||||
public const string LatestClientSettingsBlobName = "client";
|
public const string LatestClientSettingsBlobName = "client";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blob name for trainer settings.
|
||||||
|
/// </summary>
|
||||||
public const string LatestTrainerSettingsBlobName = "trainer";
|
public const string LatestTrainerSettingsBlobName = "trainer";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blob name for extra settings.
|
||||||
|
/// </summary>
|
||||||
public const string LatestExtraSettingsBlobName = "extra";
|
public const string LatestExtraSettingsBlobName = "extra";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Container name for offline evaluation.
|
||||||
|
/// </summary>
|
||||||
public const string OfflineEvalContainerName = "mwt-offline-eval";
|
public const string OfflineEvalContainerName = "mwt-offline-eval";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,14 @@ using System.Net;
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.Contract
|
namespace Microsoft.Research.MultiWorldTesting.Contract
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Helper class to download meta data.
|
||||||
|
/// </summary>
|
||||||
public static class ApplicationMetadataUtil
|
public static class ApplicationMetadataUtil
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Download and deserialize settings.
|
||||||
|
/// </summary>
|
||||||
public static TMetadata DownloadMetadata<TMetadata>(string blobUri)
|
public static TMetadata DownloadMetadata<TMetadata>(string blobUri)
|
||||||
{
|
{
|
||||||
string jsonMetadata = "";
|
string jsonMetadata = "";
|
||||||
|
|
|
@ -6,8 +6,14 @@
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.Contract
|
namespace Microsoft.Research.MultiWorldTesting.Contract
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unused class.
|
||||||
|
/// </summary>
|
||||||
public class ApplicationSettingConstants
|
public class ApplicationSettingConstants
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unused.
|
||||||
|
/// </summary>
|
||||||
public const string UseLatestModelSetting = "latest";
|
public const string UseLatestModelSetting = "latest";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,20 @@ namespace Microsoft.Research.MultiWorldTesting.Contract
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum TrainFrequency
|
public enum TrainFrequency
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Low frequency.
|
||||||
|
/// </summary>
|
||||||
Low = 0,
|
Low = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// High frequency.
|
||||||
|
/// </summary>
|
||||||
High
|
High
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the content of the client settings file.
|
||||||
|
/// </summary>
|
||||||
public class ApplicationClientMetadata
|
public class ApplicationClientMetadata
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -68,9 +78,15 @@ namespace Microsoft.Research.MultiWorldTesting.Contract
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AppInsightsKey { get; set; }
|
public string AppInsightsKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Amount of exploration to apply if no model is available yet.
|
||||||
|
/// </summary>
|
||||||
public float InitialExplorationEpsilon { get; set; }
|
public float InitialExplorationEpsilon { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the content of the "extra" settings file.
|
||||||
|
/// </summary>
|
||||||
public class ApplicationExtraMetadata
|
public class ApplicationExtraMetadata
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -6,15 +6,39 @@
|
||||||
|
|
||||||
namespace Microsoft.Research.MultiWorldTesting.Contract
|
namespace Microsoft.Research.MultiWorldTesting.Contract
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Service constants used for old join service.
|
||||||
|
/// </summary>
|
||||||
public class ServiceConstants
|
public class ServiceConstants
|
||||||
{
|
{
|
||||||
// Join Server
|
/// <summary>
|
||||||
|
/// public address of join server.
|
||||||
|
/// </summary>
|
||||||
public const string JoinAddress = "http://decisionservice.cloudapp.net";
|
public const string JoinAddress = "http://decisionservice.cloudapp.net";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Path for joining.
|
||||||
|
/// </summary>
|
||||||
public const string JoinPostAddress = "/join";
|
public const string JoinPostAddress = "/join";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Authentication header.
|
||||||
|
/// </summary>
|
||||||
public const string TokenAuthenticationScheme = "Bearer";
|
public const string TokenAuthenticationScheme = "Bearer";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Authentication scheme.
|
||||||
|
/// </summary>
|
||||||
public const string ConnectionStringAuthenticationScheme = "AzureStorage";
|
public const string ConnectionStringAuthenticationScheme = "AzureStorage";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Azure container name.
|
||||||
|
/// </summary>
|
||||||
public const string IncompleteContainerPrefix = "incomplete";
|
public const string IncompleteContainerPrefix = "incomplete";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Azure container name.
|
||||||
|
/// </summary>
|
||||||
public const string JoinedBlobContainerPrefix = "joined-examples";
|
public const string JoinedBlobContainerPrefix = "joined-examples";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче