From e25a055fbf3ca307a832ffba43eb8c05eed7af76 Mon Sep 17 00:00:00 2001 From: Markus Cozowicz Date: Mon, 18 Sep 2017 15:08:41 -0400 Subject: [PATCH] fixed warnings --- Crawl/Crawl.csproj | 9 ++-- Crawl/packages.config | 2 +- client/ClientDecisionService/App.config | 42 +++++++++---------- .../AzureBlobBackgroundDownloader.cs | 22 +++++++++- .../ClientDecisionService.Static.csproj | 11 +++-- .../ModelNotFoundException.cs | 6 +++ .../PerformanceCounters.cs | 39 +++++++++++++++++ client/ClientDecisionService/packages.config | 2 +- .../ActionDependentFeaturesTest.cs | 9 ++-- .../DecisionServiceUploadTests.cs | 24 +++++------ .../DevelopmentModeTest.cs | 4 +- .../InitialFullExploration.cs | 6 +-- .../LocalModeTest.cs | 8 ++-- .../ModelUpdateTests.cs | 4 +- .../ClientDecisionServiceTest/ModularTests.cs | 21 +++++----- client/ClientDecisionServiceTest/app.config | 40 +++++++++--------- .../VWBaseContextMapper.cs | 34 +++++++++++++++ .../VWExplorer.cs | 21 +++++++++- .../VWJson.cs | 37 ++++++++++++++++ .../VWJsonExplorer.cs | 20 +++++++++ .../VWPolicy.cs | 16 ++++++- .../VWRanker.cs | 38 ++++++++++++++++- .../VWState.cs | 6 +++ .../JoinServerUploader/BaseEventUploader.cs | 8 ++++ .../BatchingConfiguration.cs | 9 ++++ client/JoinServerUploader/EventUploader.cs | 3 +- client/JoinServerUploader/EventUploaderAsa.cs | 3 +- client/JoinServerUploader/Events.cs | 19 ++++++++- client/JoinServerUploader/IEventUploader.cs | 3 ++ .../InteractionJsonConverter.cs | 12 ++++++ .../ApplicationBlobConstants.cs | 30 ++++++++++++- .../ApplicationMetadataUtil.cs | 6 +++ .../ApplicationSettingConstants.cs | 6 +++ .../ApplicationTransferMetadata.cs | 16 +++++++ .../ServiceConstants.cs | 26 +++++++++++- 35 files changed, 460 insertions(+), 102 deletions(-) diff --git a/Crawl/Crawl.csproj b/Crawl/Crawl.csproj index b2978f09..fd5c91e8 100644 --- a/Crawl/Crawl.csproj +++ b/Crawl/Crawl.csproj @@ -25,6 +25,7 @@ + true @@ -82,11 +83,11 @@ $(SolutionDir)\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll - - $(SolutionDir)\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.13.9\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + $(SolutionDir)\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.16.1\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll - - $(SolutionDir)\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.13.9\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll + + $(SolutionDir)\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.16.1\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll $(SolutionDir)\packages\Microsoft.Rest.ClientRuntime.2.3.7\lib\net452\Microsoft.Rest.ClientRuntime.dll diff --git a/Crawl/packages.config b/Crawl/packages.config index 661331d2..f9c3eadd 100644 --- a/Crawl/packages.config +++ b/Crawl/packages.config @@ -11,7 +11,7 @@ - + diff --git a/client/ClientDecisionService/App.config b/client/ClientDecisionService/App.config index f93ae947..2c9deed5 100644 --- a/client/ClientDecisionService/App.config +++ b/client/ClientDecisionService/App.config @@ -1,52 +1,52 @@ - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + diff --git a/client/ClientDecisionService/AzureBlobBackgroundDownloader.cs b/client/ClientDecisionService/AzureBlobBackgroundDownloader.cs index fedbbcf1..4cb5dcfd 100644 --- a/client/ClientDecisionService/AzureBlobBackgroundDownloader.cs +++ b/client/ClientDecisionService/AzureBlobBackgroundDownloader.cs @@ -13,17 +13,31 @@ using System.Threading.Tasks; namespace Microsoft.Research.MultiWorldTesting.ClientLibrary { + /// + /// Download blobs in background. + /// public class AzureBlobBackgroundDownloader : IDisposable { + /// + /// Download finished event handler. + /// public delegate void DownloadedEventHandler(object sender, byte[] data); + /// + /// Download failed event handler. + /// public delegate void FailedEventHandler(object sender, Exception e); + /// + /// Download finished event handler. + /// public event DownloadedEventHandler Downloaded; + /// + /// Download failed event handler. + /// public event FailedEventHandler Failed; - private IDisposable disposable; private readonly Uri blobAddress; @@ -32,6 +46,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary private bool downloadImmediately; + /// + /// Creates a new instance. + /// public AzureBlobBackgroundDownloader(string blobAddress, TimeSpan interval, bool downloadImmediately = false, string storageConnectionString = null) { if (blobAddress == null) @@ -120,6 +137,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary } } + /// + /// Disposes the object. + /// public void Dispose() { if (this.disposable != null) diff --git a/client/ClientDecisionService/ClientDecisionService.Static.csproj b/client/ClientDecisionService/ClientDecisionService.Static.csproj index f630a230..b8c39665 100644 --- a/client/ClientDecisionService/ClientDecisionService.Static.csproj +++ b/client/ClientDecisionService/ClientDecisionService.Static.csproj @@ -1,5 +1,6 @@  + Debug @@ -55,10 +56,6 @@ $(SolutionDir)bin\x64\Release\Microsoft.Research.MultiWorldTesting.ClientLibrary.XML - - $(SolutionDir)\packages\gitlink.2.4.0\lib\net45\GitLink.exe - True - $(SolutionDir)\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.2.0\lib\net45\Microsoft.AI.PerfCounterCollector.dll True @@ -209,6 +206,8 @@ 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}. + + $(ProjectDir)\..\docgen.bat "$(ProjectDir)\..\" @@ -217,8 +216,8 @@ - - + + \ No newline at end of file diff --git a/client/ClientDecisionService/ModelNotFoundException.cs b/client/ClientDecisionService/ModelNotFoundException.cs index 7edd1d5e..4a8f7996 100644 --- a/client/ClientDecisionService/ModelNotFoundException.cs +++ b/client/ClientDecisionService/ModelNotFoundException.cs @@ -2,8 +2,14 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary { + /// + /// When a model cannot be found. + /// public class ModelNotFoundException : Exception { + /// + /// Creates a new instance. + /// public ModelNotFoundException(string message) : base(message) { } } } diff --git a/client/ClientDecisionService/PerformanceCounters.cs b/client/ClientDecisionService/PerformanceCounters.cs index 104b6086..4258452e 100644 --- a/client/ClientDecisionService/PerformanceCounters.cs +++ b/client/ClientDecisionService/PerformanceCounters.cs @@ -101,6 +101,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary this.initialized = true; } + /// + /// Disposes the resources. + /// public void Dispose() { foreach (var p in typeof(PerformanceCounters).GetProperties()) @@ -115,39 +118,75 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary } } + /// + /// Number of interactions queued. + /// [PerformanceCounterType(PerformanceCounterType.NumberOfItems64)] public PerformanceCounter InteractionExamplesQueue { get; private set; } + /// + /// Total number of interactions seen. + /// [PerformanceCounterType(PerformanceCounterType.NumberOfItems64)] public PerformanceCounter InteractionExamplesTotal { get; private set; } + /// + /// Number of interactions processed per second. + /// [PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond32)] public PerformanceCounter InteractionExamplesPerSec { get; private set; } + /// + /// Number of bytes (from interaction) per second. + /// [PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond64)] public PerformanceCounter InteractionExamplesBytesPerSec { get; private set; } + /// + /// Average size of interactions (in bytes). + /// [PerformanceCounterType(PerformanceCounterType.AverageCount64)] public PerformanceCounter AverageInteractionExampleSize { get; private set; } + /// + /// Average size of interactions (in bytes) - Base. + /// [PerformanceCounterType(PerformanceCounterType.AverageBase)] public PerformanceCounter AverageInteractionExampleSizeBase { get; private set; } + /// + /// Number of observations queued. + /// [PerformanceCounterType(PerformanceCounterType.NumberOfItems64)] public PerformanceCounter ObservationExamplesQueue { get; private set; } + /// + /// Total number of observations seen. + /// [PerformanceCounterType(PerformanceCounterType.NumberOfItems64)] public PerformanceCounter ObservationExamplesTotal { get; private set; } + /// + /// Number of observations per second. + /// [PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond32)] public PerformanceCounter ObservationExamplesPerSec { get; private set; } + /// + /// Number of bytes of observations per second. + /// [PerformanceCounterType(PerformanceCounterType.RateOfCountsPerSecond64)] public PerformanceCounter ObservationExamplesBytesPerSec { get; private set; } + /// + /// Average observation size in bytes. + /// [PerformanceCounterType(PerformanceCounterType.AverageCount64)] public PerformanceCounter AverageObservationExampleSize { get; private set; } + /// + /// Average observation size in bytes - Base. + /// [PerformanceCounterType(PerformanceCounterType.AverageBase)] public PerformanceCounter AverageObservationExampleSizeBase { get; private set; } diff --git a/client/ClientDecisionService/packages.config b/client/ClientDecisionService/packages.config index e0f1ca35..7f9e7929 100644 --- a/client/ClientDecisionService/packages.config +++ b/client/ClientDecisionService/packages.config @@ -1,7 +1,7 @@  - + diff --git a/client/ClientDecisionServiceTest/ActionDependentFeaturesTest.cs b/client/ClientDecisionServiceTest/ActionDependentFeaturesTest.cs index 3ac87cf8..1dcdf455 100644 --- a/client/ClientDecisionServiceTest/ActionDependentFeaturesTest.cs +++ b/client/ClientDecisionServiceTest/ActionDependentFeaturesTest.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.Research.MultiWorldTesting.ClientLibrary; +using System.Threading.Tasks; namespace ClientDecisionServiceTest { @@ -14,7 +15,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(1)] - public void TestADFExplorationResult() + public async Task TestADFExplorationResult() { joinServer.Reset(); @@ -36,7 +37,7 @@ namespace ClientDecisionServiceTest for (int i = 1; i <= 100; i++) { var adfContext = new TestADFContext(i); - int[] action = ds.ChooseRanking(uniqueKey, adfContext); + int[] action = await ds.ChooseRankingAsync(uniqueKey, adfContext); Assert.AreEqual(i, action.Length); @@ -55,7 +56,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(1)] - public void TestADFModelUpdateFromStream() + public async Task TestADFModelUpdateFromStream() { joinServer.Reset(); @@ -92,7 +93,7 @@ namespace ClientDecisionServiceTest int numActions = rg.Next(5, 20); var context = TestADFContextWithFeatures.CreateRandom(numActions, rg); - int[] action = ds.ChooseRanking(uniqueKey, context); + int[] action = await ds.ChooseRankingAsync(uniqueKey, context); Assert.AreEqual(numActions, action.Length); diff --git a/client/ClientDecisionServiceTest/DecisionServiceUploadTests.cs b/client/ClientDecisionServiceTest/DecisionServiceUploadTests.cs index b50bb4d0..8f76d0ac 100644 --- a/client/ClientDecisionServiceTest/DecisionServiceUploadTests.cs +++ b/client/ClientDecisionServiceTest/DecisionServiceUploadTests.cs @@ -17,7 +17,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(1)] - public void TestSingleActionDSUploadSingleEvent() + public async Task TestSingleActionDSUploadSingleEvent() { joinServer.Reset(); @@ -35,7 +35,7 @@ namespace ClientDecisionServiceTest .Create(dsConfig) .ExploitUntilModelReady(new ConstantPolicy())) { - chosenAction = ds.ChooseAction(uniqueKey, new TestContext()); + chosenAction = await ds.ChooseActionAsync(uniqueKey, new TestContext()); } Assert.AreEqual(1, joinServer.RequestCount); @@ -48,7 +48,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(1)] - public void TestSingleActionDSUploadMultipleEvents() + public async Task TestSingleActionDSUploadMultipleEvents() { joinServer.Reset(); @@ -64,8 +64,8 @@ namespace ClientDecisionServiceTest .ExploitUntilModelReady(new ConstantPolicy())) { - int chosenAction1 = ds.ChooseAction(uniqueKey, new TestContext()); - int chosenAction2 = ds.ChooseAction(uniqueKey, new TestContext()); + int chosenAction1 = await ds.ChooseActionAsync(uniqueKey, new TestContext()); + int chosenAction2 = await ds.ChooseActionAsync(uniqueKey, new TestContext()); ds.ReportReward(1.0f, uniqueKey); ds.ReportOutcome(JsonConvert.SerializeObject(new { value = "test outcome" }), uniqueKey); } @@ -148,7 +148,7 @@ namespace ClientDecisionServiceTest } [TestMethod] - public void TestMultiActionDSUploadSingleEvent() + public async Task TestMultiActionDSUploadSingleEvent() { joinServer.Reset(); @@ -164,7 +164,7 @@ namespace ClientDecisionServiceTest //.WithTopSlotEpsilonGreedy(.2f) .ExploitUntilModelReady(new ConstantPolicy())) { - chosenActions = ds.ChooseRanking(uniqueKey, new TestContext()); + chosenActions = await ds.ChooseRankingAsync(uniqueKey, new TestContext()); } Assert.AreEqual(1, joinServer.RequestCount); @@ -177,7 +177,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(1)] - public void TestMultiActionDSUploadMultipleEvents() + public async Task TestMultiActionDSUploadMultipleEvents() { joinServer.Reset(); @@ -191,8 +191,8 @@ namespace ClientDecisionServiceTest //.WithTopSlotEpsilonGreedy(.2f) .ExploitUntilModelReady(new ConstantPolicy())) { - int[] chosenAction1 = ds.ChooseRanking(uniqueKey, new TestContext()); - int[] chosenAction2 = ds.ChooseRanking(uniqueKey, new TestContext()); + int[] chosenAction1 = await ds.ChooseRankingAsync(uniqueKey, new TestContext()); + int[] chosenAction2 = await ds.ChooseRankingAsync(uniqueKey, new TestContext()); ds.ReportReward(1.0f, uniqueKey); ds.ReportOutcome(new { value = "test outcome" }, uniqueKey); } @@ -202,7 +202,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(1)] - public void TestMultiActionDSUploadSelective() + public async Task TestMultiActionDSUploadSelective() { joinServer.Reset(); @@ -233,7 +233,7 @@ namespace ClientDecisionServiceTest { 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 diff --git a/client/ClientDecisionServiceTest/DevelopmentModeTest.cs b/client/ClientDecisionServiceTest/DevelopmentModeTest.cs index ca9fe0f4..bffbcda6 100644 --- a/client/ClientDecisionServiceTest/DevelopmentModeTest.cs +++ b/client/ClientDecisionServiceTest/DevelopmentModeTest.cs @@ -16,7 +16,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(1)] - public void TestDevModeSettingsAndExampleLog() + public async Task TestDevModeSettingsAndExampleLog() { joinServer.Reset(); @@ -57,7 +57,7 @@ namespace ClientDecisionServiceTest Random rg = new Random(i); int numActions = rg.Next(5, 20); var context = TestADFContextWithFeatures.CreateRandom(numActions, rg); - int[] action = ds.ChooseRanking(interId, context); + int[] action = await ds.ChooseRankingAsync(interId, context); ds.ReportReward(i / 100f, obserId); eventIdList.Add(interId); diff --git a/client/ClientDecisionServiceTest/InitialFullExploration.cs b/client/ClientDecisionServiceTest/InitialFullExploration.cs index 2b1f5d71..a5c5d09e 100644 --- a/client/ClientDecisionServiceTest/InitialFullExploration.cs +++ b/client/ClientDecisionServiceTest/InitialFullExploration.cs @@ -31,7 +31,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(0)] - public void InitialFullExplorationTest() + public async Task InitialFullExplorationTest() { var recorder = new MyRecorder(); @@ -53,7 +53,7 @@ namespace ClientDecisionServiceTest 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 // Assert.AreEqual(1f, recorder.LastExplorerState.Probability); @@ -61,7 +61,7 @@ namespace ClientDecisionServiceTest model.Position = 0; 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); var vwState = recorder.LastMapperState as VWState; diff --git a/client/ClientDecisionServiceTest/LocalModeTest.cs b/client/ClientDecisionServiceTest/LocalModeTest.cs index dcae81a5..4373c88a 100755 --- a/client/ClientDecisionServiceTest/LocalModeTest.cs +++ b/client/ClientDecisionServiceTest/LocalModeTest.cs @@ -95,7 +95,7 @@ namespace ClientDecisionServiceTest } [TestMethod] - public void TestDSLocalModelUpdate() + public async Task TestDSLocalModelUpdate() { string vwArgs = "--cb_explore_adf --epsilon 0.2 --cb_type dr -q ::"; DecisionServiceLocal dsLocal = new DecisionServiceLocal(vwArgs, 1, TimeSpan.MaxValue); @@ -107,17 +107,17 @@ namespace ClientDecisionServiceTest // Generate interactions and ensure the model updates at the right frequency // (updates every example initially) prevModel = dsLocal.Model; - dsLocal.ChooseAction(guid1, context, 1); + await dsLocal.ChooseActionAsync(guid1, context, 1); dsLocal.ReportRewardAndComplete((float)1.0, guid1); Assert.IsTrue(!dsLocal.Model.SequenceEqual(prevModel)); // Set the model to update every two examples prevModel = dsLocal.Model; dsLocal.ModelUpdateInterval = 2; - dsLocal.ChooseAction(guid1, context, 1); + await dsLocal.ChooseActionAsync(guid1, context, 1); dsLocal.ReportRewardAndComplete((float)1.0, guid1); Assert.IsFalse(!dsLocal.Model.SequenceEqual(prevModel)); - dsLocal.ChooseAction(guid2, context, 1); + await dsLocal.ChooseActionAsync(guid2, context, 1); dsLocal.ReportRewardAndComplete((float)2.0, guid1); Assert.IsTrue(!dsLocal.Model.SequenceEqual(prevModel)); } diff --git a/client/ClientDecisionServiceTest/ModelUpdateTests.cs b/client/ClientDecisionServiceTest/ModelUpdateTests.cs index 76e9fe09..182e1d75 100644 --- a/client/ClientDecisionServiceTest/ModelUpdateTests.cs +++ b/client/ClientDecisionServiceTest/ModelUpdateTests.cs @@ -18,7 +18,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(1)] - public void TestRcv1ModelUpdateFromStream() + public async Task TestRcv1ModelUpdateFromStream() { joinServer.Reset(); @@ -63,7 +63,7 @@ namespace ClientDecisionServiceTest 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 Assert.IsTrue(action >= 1 && action <= numActions); diff --git a/client/ClientDecisionServiceTest/ModularTests.cs b/client/ClientDecisionServiceTest/ModularTests.cs index 9a72e4bd..cdb42a51 100644 --- a/client/ClientDecisionServiceTest/ModularTests.cs +++ b/client/ClientDecisionServiceTest/ModularTests.cs @@ -5,6 +5,7 @@ using System; using System.IO; using VW.Serializer; using Microsoft.Research.MultiWorldTesting.Contract; +using System.Threading.Tasks; namespace ClientDecisionServiceTest { @@ -36,7 +37,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(0)] - public void TestSingleActionOfflineModeCustomLogger() + public async Task TestSingleActionOfflineModeCustomLogger() { var dsConfig = new DecisionServiceConfiguration("") { OfflineMode = true, OfflineApplicationID = "" }; @@ -54,7 +55,7 @@ namespace ClientDecisionServiceTest { 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); @@ -85,7 +86,7 @@ namespace ClientDecisionServiceTest [TestCategory("Client Library")] [Priority(1)] [Ignore] - public void TestSingleActionOnlineModeCustomLogger() + public async Task TestSingleActionOnlineModeCustomLogger() { var dsConfig = new DecisionServiceConfiguration(MockCommandCenter.SettingsBlobUri) { @@ -103,7 +104,7 @@ namespace ClientDecisionServiceTest { 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); @@ -134,7 +135,7 @@ namespace ClientDecisionServiceTest [ExpectedException(typeof(Exception))] [TestCategory("Client Library")] [Priority(0)] - public void TestMultiActionOfflineModeArgument() + public async Task TestMultiActionOfflineModeArgument() { var metaData = new ApplicationClientMetadata { @@ -145,14 +146,14 @@ namespace ClientDecisionServiceTest new DecisionServiceConfiguration("") { OfflineMode = true, OfflineApplicationID = "" }, metaData)) { - ds.ChooseAction("", "{}"); + await ds.ChooseActionAsync("", "{}"); } } [TestMethod] [TestCategory("Client Library")] [Priority(0)] - public void TestMultiActionOfflineModeCustomLogger() + public async Task TestMultiActionOfflineModeCustomLogger() { var dsConfig = new DecisionServiceConfiguration("") { OfflineMode = true, OfflineApplicationID = "" }; var metaData = new ApplicationClientMetadata @@ -168,7 +169,7 @@ namespace ClientDecisionServiceTest { 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); @@ -197,7 +198,7 @@ namespace ClientDecisionServiceTest [TestMethod] [TestCategory("Client Library")] [Priority(1)] - public void TestMultiActionOnlineModeCustomLogger() + public async Task TestMultiActionOnlineModeCustomLogger() { joinServer.Reset(); @@ -216,7 +217,7 @@ namespace ClientDecisionServiceTest { 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); diff --git a/client/ClientDecisionServiceTest/app.config b/client/ClientDecisionServiceTest/app.config index 22bf7405..bd3d792e 100644 --- a/client/ClientDecisionServiceTest/app.config +++ b/client/ClientDecisionServiceTest/app.config @@ -1,43 +1,43 @@ - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + diff --git a/client/ClientDecisionServiceVowpalWabbit/VWBaseContextMapper.cs b/client/ClientDecisionServiceVowpalWabbit/VWBaseContextMapper.cs index a5ef81b5..eb0d63a8 100644 --- a/client/ClientDecisionServiceVowpalWabbit/VWBaseContextMapper.cs +++ b/client/ClientDecisionServiceVowpalWabbit/VWBaseContextMapper.cs @@ -7,18 +7,34 @@ using VW.Serializer; namespace Microsoft.Research.MultiWorldTesting.ClientLibrary { + /// + /// Base class for all Vowpal Wabbit contenxt mappers. + /// public abstract class VWBaseContextMapper : IUpdatable, IDisposable, IContextMapper where TVowpalWabbit : class, IDisposable { + /// + /// Type inspector used to extract schema information. + /// protected ITypeInspector typeInspector; + + /// + /// The pool of VW objects. + /// protected VowpalWabbitThreadedPredictionBase vwPool; + + /// + /// True if development mode enabled (additional logging). + /// protected bool developmentMode; /// /// Constructor using a memory stream. /// /// The VW model memory stream. + /// True if development mode enabled (additional logging). + /// Type inspector used to extract schema information. protected VWBaseContextMapper( Stream vwModelStream = null, ITypeInspector typeInspector = null, @@ -86,6 +102,13 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary } } + /// + /// Determines the action to take for a given context. + /// This implementation should be thread-safe if multithreading is needed. + /// + /// A user-defined context for the decision. + /// 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). public Task> MapContextAsync(TContext context) { if (this.vwPool == null) @@ -100,8 +123,19 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary } } + /// + /// Sub classes must override and create a new VW pool. + /// protected abstract VowpalWabbitThreadedPredictionBase CreatePool(VowpalWabbitSettings settings); + /// + /// Determines the action to take for a given context. + /// This implementation should be thread-safe if multithreading is needed. + /// + /// The Vowpal Wabbit instance to use. + /// A user-defined context for the decision. + /// 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). protected abstract PolicyDecision MapContext(TVowpalWabbit vw, TContext context); } } diff --git a/client/ClientDecisionServiceVowpalWabbit/VWExplorer.cs b/client/ClientDecisionServiceVowpalWabbit/VWExplorer.cs index 0f2e8f64..4c4f7ed2 100644 --- a/client/ClientDecisionServiceVowpalWabbit/VWExplorer.cs +++ b/client/ClientDecisionServiceVowpalWabbit/VWExplorer.cs @@ -8,6 +8,10 @@ using VW.Serializer; namespace Microsoft.Research.MultiWorldTesting.ClientLibrary { + /// + /// Vowpal Wabbit based explorer using C# based features. + /// + /// public sealed class VWExplorer : VWBaseContextMapper, TContext, ActionProbability[]>, IContextMapper, INumberOfActionsProvider @@ -18,7 +22,6 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary /// /// Constructor using a memory stream. /// - /// The VW model memory stream. public VWExplorer(Stream vwModelStream = null, ITypeInspector typeInspector = null, bool developmentMode = false) : base(vwModelStream, typeInspector, developmentMode) { @@ -31,12 +34,23 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary this.multiSerializer = this.serializer as IVowpalWabbitMultiExampleSerializerCompiler; } - + + /// + /// Sub classes must override and create a new VW pool. + /// protected override VowpalWabbitThreadedPredictionBase> CreatePool(VowpalWabbitSettings settings) { return new VowpalWabbitThreadedPrediction(settings); } + /// + /// Determines the action to take for a given context. + /// This implementation should be thread-safe if multithreading is needed. + /// + /// The Vowpal Wabbit instance to use. + /// A user-defined context for the decision. + /// 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). protected override PolicyDecision MapContext(VowpalWabbit vw, TContext context) { if (this.developmentMode) @@ -63,6 +77,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary return PolicyDecision.Create(ap, state); } + /// + /// Returns the number of actions defined by this context. + /// public int GetNumberOfActions(TContext context) { if (this.multiSerializer == null) diff --git a/client/ClientDecisionServiceVowpalWabbit/VWJson.cs b/client/ClientDecisionServiceVowpalWabbit/VWJson.cs index 4b0c6154..a837a688 100644 --- a/client/ClientDecisionServiceVowpalWabbit/VWJson.cs +++ b/client/ClientDecisionServiceVowpalWabbit/VWJson.cs @@ -7,15 +7,29 @@ using System; namespace Microsoft.Research.MultiWorldTesting.ClientLibrary { + /// + /// Vowpal Wabbit based policy for string JSON based context. + /// public class VWJsonPolicy : VWBaseContextMapper, IPolicy { + /// + /// Creates a new instance. + /// public VWJsonPolicy(Stream vwModelStream = null) : base(vwModelStream) { } + /// + /// Determines the action to take for a given context. + /// This implementation should be thread-safe if multithreading is needed. + /// + /// The Vowpal Wabbit instance to use. + /// A user-defined context for the decision. + /// 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). protected override PolicyDecision MapContext(VowpalWabbit vw, string context) { using (var vwJson = new VowpalWabbitJsonSerializer(vw)) @@ -28,26 +42,46 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary } } + /// + /// Sub classes must override and create a new VW pool. + /// protected override VowpalWabbitThreadedPredictionBase CreatePool(VowpalWabbitSettings settings) { return new VowpalWabbitThreadedPrediction(settings); } } + /// + /// Vowpal Wabbit based ranker for string JSON based context. + /// public class VWJsonRanker : VWBaseContextMapper, IRanker, INumberOfActionsProvider { + /// + /// Creates a new instance. + /// public VWJsonRanker(Stream vwModelStream = null) : base(vwModelStream) { } + /// + /// Sub classes must override and create a new VW pool. + /// protected override VowpalWabbitThreadedPredictionBase CreatePool(VowpalWabbitSettings settings) { return new VowpalWabbitThreadedPrediction(settings); } + /// + /// Determines the action to take for a given context. + /// This implementation should be thread-safe if multithreading is needed. + /// + /// The Vowpal Wabbit instance to use. + /// A user-defined context for the decision. + /// 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). protected override PolicyDecision MapContext(VowpalWabbit vw, string context) { using (var vwJson = new VowpalWabbitJsonSerializer(vw)) @@ -63,6 +97,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary } } + /// + /// Returns the number of actions defined by this context. + /// public int GetNumberOfActions(string context) { return VowpalWabbitJsonSerializer.GetNumberOfActionDependentExamples(context); diff --git a/client/ClientDecisionServiceVowpalWabbit/VWJsonExplorer.cs b/client/ClientDecisionServiceVowpalWabbit/VWJsonExplorer.cs index 1077736c..cba06aab 100644 --- a/client/ClientDecisionServiceVowpalWabbit/VWJsonExplorer.cs +++ b/client/ClientDecisionServiceVowpalWabbit/VWJsonExplorer.cs @@ -11,20 +11,37 @@ using VW.Serializer; namespace Microsoft.Research.MultiWorldTesting.ClientLibrary { + /// + /// Vowpal Wabbit based explorer for JSON context. + /// public sealed class VWJsonExplorer : VWBaseContextMapper, IContextMapper, INumberOfActionsProvider { + /// + /// Creates a new instance. + /// public VWJsonExplorer(Stream vwModelStream = null, bool developmentMode = false) : base(vwModelStream, developmentMode: developmentMode) { } + /// + /// Sub classes must override and create a new VW pool. + /// protected override VowpalWabbitThreadedPredictionBase CreatePool(VowpalWabbitSettings settings) { return new VowpalWabbitThreadedPrediction(settings); } + /// + /// Determines the action to take for a given context. + /// This implementation should be thread-safe if multithreading is needed. + /// + /// The Vowpal Wabbit instance to use. + /// A user-defined context for the decision. + /// 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). protected override PolicyDecision MapContext(VowpalWabbit vw, string context) { using (var vwJson = new VowpalWabbitJsonSerializer(vw)) @@ -50,6 +67,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary } } + /// + /// Returns the number of actions defined by this context. + /// public int GetNumberOfActions(string context) { return VowpalWabbitJsonSerializer.GetNumberOfActionDependentExamples(context); diff --git a/client/ClientDecisionServiceVowpalWabbit/VWPolicy.cs b/client/ClientDecisionServiceVowpalWabbit/VWPolicy.cs index ed149e8c..8a9eb0b7 100644 --- a/client/ClientDecisionServiceVowpalWabbit/VWPolicy.cs +++ b/client/ClientDecisionServiceVowpalWabbit/VWPolicy.cs @@ -6,23 +6,37 @@ using VW.Serializer; namespace Microsoft.Research.MultiWorldTesting.ClientLibrary { + /// + /// Vowpal Wabbit based policy. + /// + /// public class VWPolicy : VWBaseContextMapper, TContext, int>, IPolicy { /// /// Constructor using a memory stream. /// - /// The VW model memory stream. public VWPolicy(Stream vwModelStream = null, ITypeInspector typeInspector = null, bool developmentMode = false) : base(vwModelStream, typeInspector, developmentMode) { } + /// + /// Sub classes must override and create a new VW pool. + /// protected override VowpalWabbitThreadedPredictionBase> CreatePool(VowpalWabbitSettings settings) { return new VowpalWabbitThreadedPrediction(settings); } + /// + /// Determines the action to take for a given context. + /// This implementation should be thread-safe if multithreading is needed. + /// + /// The Vowpal Wabbit instance to use. + /// A user-defined context for the decision. + /// 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). protected override PolicyDecision MapContext(VowpalWabbit vw, TContext context) { if (this.developmentMode) diff --git a/client/ClientDecisionServiceVowpalWabbit/VWRanker.cs b/client/ClientDecisionServiceVowpalWabbit/VWRanker.cs index 7bcfe983..cd2e45f7 100644 --- a/client/ClientDecisionServiceVowpalWabbit/VWRanker.cs +++ b/client/ClientDecisionServiceVowpalWabbit/VWRanker.cs @@ -9,6 +9,10 @@ using VW.Serializer; namespace Microsoft.Research.MultiWorldTesting.ClientLibrary { + /// + /// Vowpal Wabbit based ranker. + /// + /// public class VWRanker : VWBaseContextMapper, TContext, int[]>, IRanker, INumberOfActionsProvider @@ -18,7 +22,6 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary /// /// Constructor using a memory stream. /// - /// The VW model memory stream. public VWRanker(Stream vwModelStream = null, ITypeInspector typeInspector = null, bool developmentMode = false) : base(vwModelStream, typeInspector, developmentMode) { @@ -30,11 +33,22 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary }) as IVowpalWabbitMultiExampleSerializerCompiler; } + /// + /// Sub classes must override and create a new VW pool. + /// protected override VowpalWabbitThreadedPredictionBase> CreatePool(VowpalWabbitSettings settings) { return new VowpalWabbitThreadedPrediction(settings); } + /// + /// Determines the action to take for a given context. + /// This implementation should be thread-safe if multithreading is needed. + /// + /// The Vowpal Wabbit instance to use. + /// A user-defined context for the decision. + /// 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). protected override PolicyDecision MapContext(VowpalWabbit vw, TContext context) { if (this.developmentMode) @@ -54,12 +68,19 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary return PolicyDecision.Create(actions, state); } + /// + /// Returns the number of actions defined by this context. + /// + public int GetNumberOfActions(TContext context) { return this.serializer.GetNumberOfActionDependentExamples(context); } } + /// + /// Vowpal Wabbit based ranker using C# defined context and action dependent features. + /// public class VWRanker : VWBaseContextMapper, TContext, int[]>, IRanker, INumberOfActionsProvider @@ -69,7 +90,6 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary /// /// Constructor using a memory stream. /// - /// The VW model memory stream. public VWRanker( Func> getContextFeaturesFunc, Stream vwModelStream = null, @@ -80,11 +100,22 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary this.getContextFeaturesFunc = getContextFeaturesFunc; } + /// + /// Sub classes must override and create a new VW pool. + /// protected override VowpalWabbitThreadedPredictionBase> CreatePool(VowpalWabbitSettings settings) { return new VowpalWabbitThreadedPrediction(settings); } + /// + /// Determines the action to take for a given context. + /// This implementation should be thread-safe if multithreading is needed. + /// + /// The Vowpal Wabbit instance to use. + /// A user-defined context for the decision. + /// 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). protected override PolicyDecision MapContext(VowpalWabbit vw, TContext context) { if (this.developmentMode) @@ -104,6 +135,9 @@ namespace Microsoft.Research.MultiWorldTesting.ClientLibrary return PolicyDecision.Create(actions, state); } + /// + /// Returns the number of actions defined by this context. + /// public int GetNumberOfActions(TContext context) { var adfs = this.getContextFeaturesFunc(context); diff --git a/client/ClientDecisionServiceVowpalWabbit/VWState.cs b/client/ClientDecisionServiceVowpalWabbit/VWState.cs index 449c793e..5dcc974b 100644 --- a/client/ClientDecisionServiceVowpalWabbit/VWState.cs +++ b/client/ClientDecisionServiceVowpalWabbit/VWState.cs @@ -7,9 +7,15 @@ using System.Threading.Tasks; namespace Microsoft.Research.MultiWorldTesting.ClientLibrary { + /// + /// Defines the policy state for a VowpalWabbit model. + /// [JsonObject(Id = "stvw")] public class VWState { + /// + /// The model id used at scoring time. + /// [JsonProperty("m")] public string ModelId { get; set; } } diff --git a/client/JoinServerUploader/BaseEventUploader.cs b/client/JoinServerUploader/BaseEventUploader.cs index 2874bc9a..788f5157 100644 --- a/client/JoinServerUploader/BaseEventUploader.cs +++ b/client/JoinServerUploader/BaseEventUploader.cs @@ -33,12 +33,17 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader /// protected readonly BatchingConfiguration batchConfig; private readonly CancellationTokenSource cancellationTokenSource; + + /// + /// Cancellation token used for shutdown + /// protected CancellationToken cancellationToken; /// /// Constructs an uploader object. /// /// Optional; The batching configuration that controls the buffer size. + /// If true, enables additional logging and disables batching. public BaseEventUploader(BatchingConfiguration batchConfig = null, bool developmentMode = false) { this.cancellationTokenSource = new CancellationTokenSource(); @@ -96,6 +101,9 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader /// public event EventUploaderSuccessEventHandler SuccessHandler; + /// + /// Invoke when a batch completed. + /// public event EventUploaderCompletedEventHandler CompletionHandler; internal void FireErrorHandler(Exception e) diff --git a/client/JoinServerUploader/BatchingConfiguration.cs b/client/JoinServerUploader/BatchingConfiguration.cs index 20bc9c5c..0b63e038 100644 --- a/client/JoinServerUploader/BatchingConfiguration.cs +++ b/client/JoinServerUploader/BatchingConfiguration.cs @@ -6,10 +6,19 @@ using System.Threading.Tasks.Dataflow; namespace Microsoft.Research.MultiWorldTesting.JoinUploader { + /// + /// Delegate definition for success. + /// public delegate void EventUploaderSuccessEventHandler(object source, int eventCount, int sumSize, int inputQueueSize); + /// + /// Delegate definition for error. + /// public delegate void EventUploaderErrorEventHandler(object source, Exception e); + /// + /// Delegate definition for completion. + /// public delegate void EventUploaderCompletedEventHandler(object source, string blockName, Task task); /// diff --git a/client/JoinServerUploader/EventUploader.cs b/client/JoinServerUploader/EventUploader.cs index 19b611a4..57eb5353 100644 --- a/client/JoinServerUploader/EventUploader.cs +++ b/client/JoinServerUploader/EventUploader.cs @@ -48,7 +48,8 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader /// Optional; The batching configuration that controls the buffer size. /// Optional; The address of a custom HTTP logging service. When null, the join service address is used. /// Optional; The custom object to handle HTTP requests. - public EventUploader(BatchingConfiguration batchConfig = null, string loggingServiceBaseAddress = null, IHttpClient httpClient = null, bool developmentMode = false) + /// If true, enables additional logging and disables batching. + public EventUploader(BatchingConfiguration batchConfig = null, string loggingServiceBaseAddress = null, IHttpClient httpClient = null, bool developmentMode = false) : base(batchConfig, developmentMode) { this.loggingServiceBaseAddress = loggingServiceBaseAddress ?? ServiceConstants.JoinAddress; diff --git a/client/JoinServerUploader/EventUploaderAsa.cs b/client/JoinServerUploader/EventUploaderAsa.cs index 59e27982..def18898 100644 --- a/client/JoinServerUploader/EventUploaderAsa.cs +++ b/client/JoinServerUploader/EventUploaderAsa.cs @@ -31,6 +31,7 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader /// /// The Azure Stream Analytics connection string. /// Optional; The batching configuration to used when uploading data. + /// If true, enables additional logging and disables batching. public EventUploaderASA ( string eventHubConnectionString, @@ -126,7 +127,7 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader /// /// Uploads a single event to EventHub asynchronously. /// - /// The event to upload. + /// The event to upload. /// A Task object. private Task UploadToEventHubAsync(EventData evt) { diff --git a/client/JoinServerUploader/Events.cs b/client/JoinServerUploader/Events.cs index f552f6c6..13cbf8bb 100644 --- a/client/JoinServerUploader/Events.cs +++ b/client/JoinServerUploader/Events.cs @@ -30,17 +30,34 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader /// public string Key { get; set; } - // int, int[] + /// + /// The action or ranking (int, int[]) + /// public object Value { get; set; } + /// + /// The supplied context. + /// public object Context { get; set; } + /// + /// The state of the explorer (e.g. model id to be able to correlate back). + /// public object ExplorerState { get; set; } + /// + /// The state of the mapper (e.g. model id to be able to correlate back). + /// public object MapperState { get; set; } + /// + /// If pipeline overflows, we drop stochastically. + /// public float? ProbabilityOfDrop { get; set; } + /// + /// Create epsilon greedy interaction??? + /// public static Interaction CreateEpsilonGreedy(string key, TContext context, int action, float probability) { return Interaction.Create(key, context, action, new GenericExplorerState { Probability = probability }); diff --git a/client/JoinServerUploader/IEventUploader.cs b/client/JoinServerUploader/IEventUploader.cs index 91ea574e..ecead290 100644 --- a/client/JoinServerUploader/IEventUploader.cs +++ b/client/JoinServerUploader/IEventUploader.cs @@ -58,6 +58,9 @@ namespace Microsoft.Research.MultiWorldTesting.JoinUploader /// event EventUploaderSuccessEventHandler SuccessHandler; + /// + /// Invoked on pipeline completion. + /// event EventUploaderCompletedEventHandler CompletionHandler; } } diff --git a/client/JoinServerUploader/InteractionJsonConverter.cs b/client/JoinServerUploader/InteractionJsonConverter.cs index 95d6c8b5..6779dd03 100644 --- a/client/JoinServerUploader/InteractionJsonConverter.cs +++ b/client/JoinServerUploader/InteractionJsonConverter.cs @@ -8,18 +8,30 @@ using System.Threading.Tasks; namespace Microsoft.Research.MultiWorldTesting.JoinUploader { + /// + /// Custom JSON.NET serializer for interactions. + /// public class InteractionJsonConverter : JsonConverter { + /// + /// True, if it's an interaction type. + /// public override bool CanConvert(Type objectType) { return objectType == typeof(Interaction); } + /// + /// Not supported. + /// public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } + /// + /// Serializes the interaction. + /// public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var v = value as Interaction; diff --git a/client/MultiWorldTestingServiceContract/ApplicationBlobConstants.cs b/client/MultiWorldTestingServiceContract/ApplicationBlobConstants.cs index 4657c3f5..5d535d0a 100644 --- a/client/MultiWorldTestingServiceContract/ApplicationBlobConstants.cs +++ b/client/MultiWorldTestingServiceContract/ApplicationBlobConstants.cs @@ -6,18 +6,44 @@ namespace Microsoft.Research.MultiWorldTesting.Contract { + /// + /// Various blob and container blob names + /// public class ApplicationBlobConstants { - // Model blobs + /// + /// Container name for models. + /// public const string ModelContainerName = "mwt-models"; + + /// + /// Blob name for latest model. + /// public const string LatestModelBlobName = "current"; - // Settings blobs + /// + /// Container name for settings. + /// public const string SettingsContainerName = "mwt-settings"; + + /// + /// Blob name for client settings. + /// public const string LatestClientSettingsBlobName = "client"; + + /// + /// Blob name for trainer settings. + /// public const string LatestTrainerSettingsBlobName = "trainer"; + + /// + /// Blob name for extra settings. + /// public const string LatestExtraSettingsBlobName = "extra"; + /// + /// Container name for offline evaluation. + /// public const string OfflineEvalContainerName = "mwt-offline-eval"; } } diff --git a/client/MultiWorldTestingServiceContract/ApplicationMetadataUtil.cs b/client/MultiWorldTestingServiceContract/ApplicationMetadataUtil.cs index 159522ba..29eee365 100644 --- a/client/MultiWorldTestingServiceContract/ApplicationMetadataUtil.cs +++ b/client/MultiWorldTestingServiceContract/ApplicationMetadataUtil.cs @@ -5,8 +5,14 @@ using System.Net; namespace Microsoft.Research.MultiWorldTesting.Contract { + /// + /// Helper class to download meta data. + /// public static class ApplicationMetadataUtil { + /// + /// Download and deserialize settings. + /// public static TMetadata DownloadMetadata(string blobUri) { string jsonMetadata = ""; diff --git a/client/MultiWorldTestingServiceContract/ApplicationSettingConstants.cs b/client/MultiWorldTestingServiceContract/ApplicationSettingConstants.cs index 559706fe..0fc2cbc7 100644 --- a/client/MultiWorldTestingServiceContract/ApplicationSettingConstants.cs +++ b/client/MultiWorldTestingServiceContract/ApplicationSettingConstants.cs @@ -6,8 +6,14 @@ namespace Microsoft.Research.MultiWorldTesting.Contract { + /// + /// Unused class. + /// public class ApplicationSettingConstants { + /// + /// Unused. + /// public const string UseLatestModelSetting = "latest"; } } diff --git a/client/MultiWorldTestingServiceContract/ApplicationTransferMetadata.cs b/client/MultiWorldTestingServiceContract/ApplicationTransferMetadata.cs index c3264093..62c348f2 100644 --- a/client/MultiWorldTestingServiceContract/ApplicationTransferMetadata.cs +++ b/client/MultiWorldTestingServiceContract/ApplicationTransferMetadata.cs @@ -27,10 +27,20 @@ namespace Microsoft.Research.MultiWorldTesting.Contract /// public enum TrainFrequency { + /// + /// Low frequency. + /// Low = 0, + + /// + /// High frequency. + /// High } + /// + /// Defines the content of the client settings file. + /// public class ApplicationClientMetadata { /// @@ -68,9 +78,15 @@ namespace Microsoft.Research.MultiWorldTesting.Contract /// public string AppInsightsKey { get; set; } + /// + /// Amount of exploration to apply if no model is available yet. + /// public float InitialExplorationEpsilon { get; set; } } + /// + /// Defines the content of the "extra" settings file. + /// public class ApplicationExtraMetadata { /// diff --git a/client/MultiWorldTestingServiceContract/ServiceConstants.cs b/client/MultiWorldTestingServiceContract/ServiceConstants.cs index 783002e0..11795442 100644 --- a/client/MultiWorldTestingServiceContract/ServiceConstants.cs +++ b/client/MultiWorldTestingServiceContract/ServiceConstants.cs @@ -6,15 +6,39 @@ namespace Microsoft.Research.MultiWorldTesting.Contract { + /// + /// Service constants used for old join service. + /// public class ServiceConstants { - // Join Server + /// + /// public address of join server. + /// public const string JoinAddress = "http://decisionservice.cloudapp.net"; + + /// + /// Path for joining. + /// public const string JoinPostAddress = "/join"; + + /// + /// Authentication header. + /// public const string TokenAuthenticationScheme = "Bearer"; + + /// + /// Authentication scheme. + /// public const string ConnectionStringAuthenticationScheme = "AzureStorage"; + /// + /// Azure container name. + /// public const string IncompleteContainerPrefix = "incomplete"; + + /// + /// Azure container name. + /// public const string JoinedBlobContainerPrefix = "joined-examples"; } }