From f05fd8e7c0deb9fe5ab18e1f25d5d943d3c1de9d Mon Sep 17 00:00:00 2001 From: Young Bu Park Date: Fri, 4 Sep 2020 17:45:00 -0700 Subject: [PATCH 1/2] initial commit of actor presence test --- actor-presence/actor-presence.sln | 62 +++++++ actor-presence/load_generator/Program.cs | 107 +++++++++++ .../load_generator/load_generator.csproj | 16 ++ .../presence_actor_service/GameActor.cs | 170 ++++++++++++++++++ .../presence_actor_service/GameState.cs | 18 ++ .../presence_actor_service/PlayerActor.cs | 46 +++++ .../presence_actor_service/PlayerState.cs | 12 ++ .../presence_actor_service/PresenceActor.cs | 29 +++ .../presence_actor_service/Program.cs | 27 +++ .../Properties/launchSettings.json | 30 ++++ .../presence_actor_service/Startup.cs | 61 +++++++ .../presence_actor_service/appsettings.json | 10 ++ .../presence_actor_service/cd .json | 9 + .../presence_actor_service.csproj | 17 ++ .../presence_interface/GameStatus.cs | 28 +++ .../presence_interface/HeartbeatData.cs | 37 ++++ .../presence_interface/IGameActor.cs | 20 +++ .../presence_interface/IPlayerActor.cs | 19 ++ .../presence_interface/IPresenceActor.cs | 15 ++ .../presence_interface.csproj | 11 ++ 20 files changed, 744 insertions(+) create mode 100644 actor-presence/actor-presence.sln create mode 100644 actor-presence/load_generator/Program.cs create mode 100644 actor-presence/load_generator/load_generator.csproj create mode 100644 actor-presence/presence_actor_service/GameActor.cs create mode 100644 actor-presence/presence_actor_service/GameState.cs create mode 100644 actor-presence/presence_actor_service/PlayerActor.cs create mode 100644 actor-presence/presence_actor_service/PlayerState.cs create mode 100644 actor-presence/presence_actor_service/PresenceActor.cs create mode 100644 actor-presence/presence_actor_service/Program.cs create mode 100644 actor-presence/presence_actor_service/Properties/launchSettings.json create mode 100644 actor-presence/presence_actor_service/Startup.cs create mode 100644 actor-presence/presence_actor_service/appsettings.json create mode 100644 actor-presence/presence_actor_service/cd .json create mode 100644 actor-presence/presence_actor_service/presence_actor_service.csproj create mode 100644 actor-presence/presence_interface/GameStatus.cs create mode 100644 actor-presence/presence_interface/HeartbeatData.cs create mode 100644 actor-presence/presence_interface/IGameActor.cs create mode 100644 actor-presence/presence_interface/IPlayerActor.cs create mode 100644 actor-presence/presence_interface/IPresenceActor.cs create mode 100644 actor-presence/presence_interface/presence_interface.csproj diff --git a/actor-presence/actor-presence.sln b/actor-presence/actor-presence.sln new file mode 100644 index 00000000..be634299 --- /dev/null +++ b/actor-presence/actor-presence.sln @@ -0,0 +1,62 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "load_generator", "load_generator\load_generator.csproj", "{E8B44B23-4BC7-4B56-8C88-4A820F455875}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "presence_actor_service", "presence_actor_service\presence_actor_service.csproj", "{E93959C5-CF16-4974-AE77-CB97478642D4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "presence_interface", "presence_interface\presence_interface.csproj", "{76536772-3EBB-44BD-969E-58E8361A2F87}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Debug|x64.ActiveCfg = Debug|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Debug|x64.Build.0 = Debug|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Debug|x86.ActiveCfg = Debug|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Debug|x86.Build.0 = Debug|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Release|Any CPU.Build.0 = Release|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Release|x64.ActiveCfg = Release|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Release|x64.Build.0 = Release|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Release|x86.ActiveCfg = Release|Any CPU + {E8B44B23-4BC7-4B56-8C88-4A820F455875}.Release|x86.Build.0 = Release|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Debug|x64.ActiveCfg = Debug|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Debug|x64.Build.0 = Debug|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Debug|x86.ActiveCfg = Debug|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Debug|x86.Build.0 = Debug|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Release|Any CPU.Build.0 = Release|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Release|x64.ActiveCfg = Release|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Release|x64.Build.0 = Release|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Release|x86.ActiveCfg = Release|Any CPU + {E93959C5-CF16-4974-AE77-CB97478642D4}.Release|x86.Build.0 = Release|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Debug|x64.ActiveCfg = Debug|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Debug|x64.Build.0 = Debug|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Debug|x86.ActiveCfg = Debug|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Debug|x86.Build.0 = Debug|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Release|Any CPU.Build.0 = Release|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Release|x64.ActiveCfg = Release|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Release|x64.Build.0 = Release|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Release|x86.ActiveCfg = Release|Any CPU + {76536772-3EBB-44BD-969E-58E8361A2F87}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/actor-presence/load_generator/Program.cs b/actor-presence/load_generator/Program.cs new file mode 100644 index 00000000..e3fb0be9 --- /dev/null +++ b/actor-presence/load_generator/Program.cs @@ -0,0 +1,107 @@ +namespace Dapr.Tests.Actors.PresenceTest +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text.Json; + using System.Threading; + using System.Threading.Tasks; + + using Dapr.Actors; + using Dapr.Actors.Client; + + class Program + { + private static void Main() + { + const int nGames = 10; // number of games to simulate + const int nPlayersPerGame = 4; // number of players in each game + + var sendInterval = TimeSpan.FromSeconds(5); // interval for sending updates + + // Precreate base heartbeat data objects for each of the games. + // We'll modify them before every time before sending. + var heartbeats = new HeartbeatData[nGames]; + for (var i = 0; i < nGames; i++) + { + heartbeats[i] = new HeartbeatData(); + heartbeats[i].Game = Guid.NewGuid(); + for (var j = 0; j < nPlayersPerGame; j++) + { + var playerId = Guid.NewGuid(); + heartbeats[i].Status.Players.Add(playerId); + } + } + + var outstandingUpdates = new List(); + var outstandingScoreReads = new List>(); + var iteration = 0; + + while (true) + { + iteration++; + Console.WriteLine(); + Console.WriteLine("Sending heartbeat series # {0}", iteration); + + ulong high = ((ulong) iteration) << 32; + ulong low = (ulong) (iteration > 5 ? iteration - 5 : 0); + var value = high | low; + var score = BitConverter.GetBytes(value); + var presence = ActorProxy.Create(ActorId.CreateRandom(), "PresenceActor"); // get any stateless actor + outstandingUpdates.Clear(); + try + { + for (var i = 0; i < nGames; i++) + { + heartbeats[i].Status.Score = score; + + var heartbeatData = JsonSerializer.SerializeToUtf8Bytes(heartbeats[i]); + var t = presence.Heartbeat(heartbeatData); + outstandingUpdates.Add(t); + } + + // Wait for all calls to finish. + // It is okay to block the thread here because it's a client program with no parallelism. + // One should never block a thread in grain code. + Console.WriteLine("Wating for the tasks to finish"); + Task.WaitAll(outstandingUpdates.ToArray()); + } + catch (Exception e) + { + Console.WriteLine("Error: {0}", e); + } + + Console.WriteLine(); + Console.WriteLine("Getting game scores: "); + outstandingScoreReads.Clear(); + try + { + for (var i = 0; i < nGames; i++) + { + var t = ActorProxy.Create(new ActorId(heartbeats[i].Game.ToString()), "PresenceActor").GetGameScore(); + outstandingScoreReads.Add(t); + } + + // Wait for all calls to finish. + // It is okay to block the thread here because it's a client program with no parallelism. + // One should never block a thread in grain code. + Task.WhenAll(outstandingScoreReads.ToArray()).Wait(); + + for (var i = 0; i < nGames; i++) + { + Console.WriteLine("Game: {0}, Score: {1}", heartbeats[i].Game, String.Join(",", outstandingScoreReads[i].Result.Select(b => b.ToString()))); + } + } + catch (Exception e) + { + Console.WriteLine("Error: {0}", e); + } + + Console.WriteLine(); + Console.WriteLine("Sleeping for {0} seconds.", sendInterval.TotalSeconds); + Console.WriteLine("Press CTRL-C to exit"); + Thread.Sleep(sendInterval); + } + } + } +} \ No newline at end of file diff --git a/actor-presence/load_generator/load_generator.csproj b/actor-presence/load_generator/load_generator.csproj new file mode 100644 index 00000000..34cc2d55 --- /dev/null +++ b/actor-presence/load_generator/load_generator.csproj @@ -0,0 +1,16 @@ + + + + Exe + netcoreapp3.1 + + + + + + + + + + + diff --git a/actor-presence/presence_actor_service/GameActor.cs b/actor-presence/presence_actor_service/GameActor.cs new file mode 100644 index 00000000..722d9694 --- /dev/null +++ b/actor-presence/presence_actor_service/GameActor.cs @@ -0,0 +1,170 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Net; + using System.Threading.Tasks; + + using Dapr.Actors; + using Dapr.Actors.Client; + using Dapr.Actors.Runtime; + + class GameActor : Actor, IGameActor + { + private const string StateName = "state"; + + private byte[] ipAddressBytes; + + public GameActor(ActorService actorService, ActorId actorId) + : base(actorService, actorId) + { + } + + protected override async Task OnActivateAsync() + { + try + { + await this.StateManager.TryAddStateAsync(StateName, new GameState + { + Players = new HashSet(), + Status = new GameStatus {Score = new byte[1]} + }); + await base.OnActivateAsync(); + } + catch (Exception e) + { + System.Console.WriteLine($"Exception in OnActivateAsync: {e}"); + throw; + } + } + + public async Task Initialize(int scoreSizeInBytes) + { + try + { + var state = await this.StateManager.GetStateAsync(StateName); + state.Status.Score = new byte[scoreSizeInBytes]; + Random r = new Random(); + r.NextBytes(state.Status.Score); + await this.StateManager.SetStateAsync(StateName, state); + + return ""; + } + catch (Exception e) + { + System.Console.WriteLine($"Exception in InitializeScoreBuffer: {e}"); + throw; + } + } + + public async Task UpdateGameStatus(GameStatus newStatus) + { + try + { + IPAddress senderIPAddress; + int senderProcessId; + long requestId; + var scoreBuffer = newStatus.Score; + + if (scoreBuffer[0] == (byte)ScoreBufferContentType.NoRequestId) + { + return; + } + + var ipAddressLength = BitConverter.ToInt32(scoreBuffer, 1); + GetIPAddressBytes(scoreBuffer, 1+sizeof(int), ipAddressLength); + senderIPAddress = new IPAddress(this.ipAddressBytes); + senderProcessId = BitConverter.ToInt32(scoreBuffer, 1 + sizeof(int) + ipAddressLength); + requestId = BitConverter.ToInt64(scoreBuffer, 1 + (2*sizeof(int)) + ipAddressLength); + + try + { + var state = await this.StateManager.GetStateAsync(StateName); + state.Status = newStatus; + + // Check for new players that joined since last update + foreach (var player in newStatus.Players) + { + if (!state.Players.Contains(player)) + { + try + { + // Here we call player grains serially, which is less efficient than a fan-out but simpler to express. + await ActorProxy.Create(new ActorId(player.ToString()), "PlayerActor").JoinGame(this); + state.Players.Add(player); + } + catch + { + // Ignore exceptions while telling player grains to join the game. + // Since we didn't add the player to the list, this will be tried again with next update. + } + } + } + + // Check for players that left the game since last update + var promises = new List(); + foreach (var player in state.Players) + { + if (!newStatus.Players.Contains(player)) + { + try + { + // Here we do a fan-out with multiple calls going out in parallel. We join the promisses later. + // More code to write but we get lower latency when calling multiple player grains. + promises.Add(ActorProxy.Create(new ActorId(player.ToString()), "PlayerActor").LeaveGame(this)); + state.Players.Remove(player); + } + catch + { + // Ignore exceptions while telling player grains to leave the game. + // Since we didn't remove the player from the list, this will be tried again with next update. + } + } + } + + // Joining promises + await Task.WhenAll(promises); + + await this.StateManager.SetStateAsync(StateName, state); + } + finally + { + System.Console.WriteLine($"Processed request. {requestId},{senderProcessId},{senderIPAddress}"); + } + } + catch (Exception e) + { + System.Console.WriteLine($"Exception in UpdateGameStatus: {e}"); + throw; + } + } + + public async Task GetGameScore() + { + try + { + return (await this.StateManager.GetStateAsync(StateName)).Status.Score; + } + catch (Exception e) + { + System.Console.WriteLine($"Exception in GetGameScore: {e}"); + throw; + } + } + + private void GetIPAddressBytes(byte[] scoreBuffer, int startIndex, int length) + { + if ((null == this.ipAddressBytes) || (this.ipAddressBytes.Length != length)) + { + this.ipAddressBytes = new byte[length]; + } + Array.Copy(scoreBuffer, startIndex, this.ipAddressBytes, 0, length); + } + } +} \ No newline at end of file diff --git a/actor-presence/presence_actor_service/GameState.cs b/actor-presence/presence_actor_service/GameState.cs new file mode 100644 index 00000000..94222e29 --- /dev/null +++ b/actor-presence/presence_actor_service/GameState.cs @@ -0,0 +1,18 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using System; + using System.Collections.Generic; + using System.Runtime.Serialization; + + class GameState + { + public GameStatus Status; + + public HashSet Players; + } +} \ No newline at end of file diff --git a/actor-presence/presence_actor_service/PlayerActor.cs b/actor-presence/presence_actor_service/PlayerActor.cs new file mode 100644 index 00000000..8fa3a6d9 --- /dev/null +++ b/actor-presence/presence_actor_service/PlayerActor.cs @@ -0,0 +1,46 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using System.Threading.Tasks; + using Dapr.Actors; + using Dapr.Actors.Runtime; + + class PlayerActor : Actor, IPlayerActor + { + private const string StateName = "state"; + + public PlayerActor(ActorService actorService, ActorId actorId) + : base(actorService, actorId) + { + } + + protected override async Task OnActivateAsync() + { + await this.StateManager.TryAddStateAsync(StateName, new PlayerState()); + await base.OnActivateAsync(); + } + + public async Task GetCurrentGame() + { + return (await this.StateManager.GetStateAsync(StateName)).CurrentGame; + } + + public async Task JoinGame(IGameActor game) + { + var state = await this.StateManager.GetStateAsync(StateName); + state.CurrentGame = game; + await this.StateManager.SetStateAsync(StateName, state); + } + + public async Task LeaveGame(IGameActor nullgame) + { + var state = await this.StateManager.GetStateAsync(StateName); + state.CurrentGame = null; + await this.StateManager.SetStateAsync(StateName, state); + } + } +} \ No newline at end of file diff --git a/actor-presence/presence_actor_service/PlayerState.cs b/actor-presence/presence_actor_service/PlayerState.cs new file mode 100644 index 00000000..d4df0fdf --- /dev/null +++ b/actor-presence/presence_actor_service/PlayerState.cs @@ -0,0 +1,12 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + class PlayerState + { + public IGameActor CurrentGame; + } +} \ No newline at end of file diff --git a/actor-presence/presence_actor_service/PresenceActor.cs b/actor-presence/presence_actor_service/PresenceActor.cs new file mode 100644 index 00000000..053eea2a --- /dev/null +++ b/actor-presence/presence_actor_service/PresenceActor.cs @@ -0,0 +1,29 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using System.Threading.Tasks; + using System.Text.Json; + + using Dapr.Actors; + using Dapr.Actors.Client; + using Dapr.Actors.Runtime; + + class PresenceActor : Actor, IPresenceActor + { + public PresenceActor(ActorService actorService, ActorId actorId) + : base(actorService, actorId) + { + } + + public Task Heartbeat(byte[] data) + { + var heartbeatData = JsonSerializer.Deserialize(data); + var game = ActorProxy.Create(new ActorId(heartbeatData.Game.ToString()), "GameActor"); + return game.UpdateGameStatus(heartbeatData.Status); + } + } +} \ No newline at end of file diff --git a/actor-presence/presence_actor_service/Program.cs b/actor-presence/presence_actor_service/Program.cs new file mode 100644 index 00000000..a10c7fc5 --- /dev/null +++ b/actor-presence/presence_actor_service/Program.cs @@ -0,0 +1,27 @@ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using Dapr.Actors; + using Dapr.Actors.AspNetCore; + using Dapr.Actors.Runtime; + using Microsoft.AspNetCore; + using Microsoft.AspNetCore.Hosting; + + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + .UseActors(actorRuntime => + { + actorRuntime.RegisterActor(); + actorRuntime.RegisterActor(); + actorRuntime.RegisterActor(); + }); + } +} diff --git a/actor-presence/presence_actor_service/Properties/launchSettings.json b/actor-presence/presence_actor_service/Properties/launchSettings.json new file mode 100644 index 00000000..d2664890 --- /dev/null +++ b/actor-presence/presence_actor_service/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:2097", + "sslPort": 44385 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "presence_actor_service": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/actor-presence/presence_actor_service/Startup.cs b/actor-presence/presence_actor_service/Startup.cs new file mode 100644 index 00000000..c7e19f27 --- /dev/null +++ b/actor-presence/presence_actor_service/Startup.cs @@ -0,0 +1,61 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using Microsoft.AspNetCore.Builder; + using Microsoft.AspNetCore.Hosting; + + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + + /// + /// Startup class. + /// + public class Startup + { + /// + /// Initializes a new instance of the class. + /// + /// Configuration. + public Startup(IConfiguration configuration) + { + this.Configuration = configuration; + } + + /// + /// Gets the configuration. + /// + public IConfiguration Configuration { get; } + + /// + /// Configures Services. + /// + /// Service Collection. + public void ConfigureServices(IServiceCollection services) + { + services.AddRouting(); + } + + /// + /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + /// + /// Application builder. + /// Webhost environment. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } + } + } +} diff --git a/actor-presence/presence_actor_service/appsettings.json b/actor-presence/presence_actor_service/appsettings.json new file mode 100644 index 00000000..81ff8777 --- /dev/null +++ b/actor-presence/presence_actor_service/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/actor-presence/presence_actor_service/cd .json b/actor-presence/presence_actor_service/cd .json new file mode 100644 index 00000000..dba68eb1 --- /dev/null +++ b/actor-presence/presence_actor_service/cd .json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/actor-presence/presence_actor_service/presence_actor_service.csproj b/actor-presence/presence_actor_service/presence_actor_service.csproj new file mode 100644 index 00000000..4f1c51b8 --- /dev/null +++ b/actor-presence/presence_actor_service/presence_actor_service.csproj @@ -0,0 +1,17 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + + diff --git a/actor-presence/presence_interface/GameStatus.cs b/actor-presence/presence_interface/GameStatus.cs new file mode 100644 index 00000000..5bb9e08f --- /dev/null +++ b/actor-presence/presence_interface/GameStatus.cs @@ -0,0 +1,28 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using System; + using System.Collections.Generic; + + public enum ScoreBufferContentType : byte + { + NoRequestId, + HasRequestId + } + + public class GameStatus + { + public HashSet Players { get; private set; } + + public byte[] Score { get; set; } + + public GameStatus() + { + Players = new HashSet(); + } + } +} \ No newline at end of file diff --git a/actor-presence/presence_interface/HeartbeatData.cs b/actor-presence/presence_interface/HeartbeatData.cs new file mode 100644 index 00000000..8ae1c54e --- /dev/null +++ b/actor-presence/presence_interface/HeartbeatData.cs @@ -0,0 +1,37 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest { + + using System; + using System.Linq; + using System.Text; + + public class HeartbeatData + { + public Guid Game { get; set; } + + public GameStatus Status { get; private set; } + + public HeartbeatData() + { + Status = new GameStatus(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("Heartbeat:"); + sb.Append(",Game=").Append(Game); + var playerList = Status.Players.ToArray(); + for (int i = 0; i < playerList.Length; i++) + { + sb.AppendFormat(",Player{0}=", i + 1).Append(playerList[i]); + } + sb.AppendFormat(",Score={0}", Status.Score); + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/actor-presence/presence_interface/IGameActor.cs b/actor-presence/presence_interface/IGameActor.cs new file mode 100644 index 00000000..8b15c3a9 --- /dev/null +++ b/actor-presence/presence_interface/IGameActor.cs @@ -0,0 +1,20 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using System; + using System.Threading.Tasks; + using Dapr.Actors; + + public interface IGameActor : IActor + { + Task Initialize(int scoreSizeInBytes); + + Task UpdateGameStatus(GameStatus status); + + Task GetGameScore(); + } +} \ No newline at end of file diff --git a/actor-presence/presence_interface/IPlayerActor.cs b/actor-presence/presence_interface/IPlayerActor.cs new file mode 100644 index 00000000..f8de647b --- /dev/null +++ b/actor-presence/presence_interface/IPlayerActor.cs @@ -0,0 +1,19 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using System.Threading.Tasks; + using Dapr.Actors; + + public interface IPlayerActor : IActor + { + Task GetCurrentGame(); + + Task JoinGame(IGameActor game); + + Task LeaveGame(IGameActor game); + } +} \ No newline at end of file diff --git a/actor-presence/presence_interface/IPresenceActor.cs b/actor-presence/presence_interface/IPresenceActor.cs new file mode 100644 index 00000000..1ea1c11c --- /dev/null +++ b/actor-presence/presence_interface/IPresenceActor.cs @@ -0,0 +1,15 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest +{ + using System.Threading.Tasks; + using Dapr.Actors; + + public interface IPresenceActor : IActor + { + Task Heartbeat(byte[] data); + } +} \ No newline at end of file diff --git a/actor-presence/presence_interface/presence_interface.csproj b/actor-presence/presence_interface/presence_interface.csproj new file mode 100644 index 00000000..d01817f4 --- /dev/null +++ b/actor-presence/presence_interface/presence_interface.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp3.1 + + + + + + + From cfc06c4e9bfb4109c58aaf109c4d5a0d24519739 Mon Sep 17 00:00:00 2001 From: Young Bu Park Date: Fri, 4 Sep 2020 17:48:48 -0700 Subject: [PATCH 2/2] update license --- actor-presence/load_generator/Program.cs | 16 ++++++---------- .../presence_actor_service/GameActor.cs | 4 ++-- .../presence_actor_service/GameState.cs | 4 ++-- .../presence_actor_service/PlayerActor.cs | 4 ++-- .../presence_actor_service/PlayerState.cs | 4 ++-- .../presence_actor_service/PresenceActor.cs | 4 ++-- actor-presence/presence_actor_service/Program.cs | 4 ++++ actor-presence/presence_interface/GameStatus.cs | 4 ++-- .../presence_interface/HeartbeatData.cs | 4 ++-- actor-presence/presence_interface/IGameActor.cs | 4 ++-- .../presence_interface/IPlayerActor.cs | 4 ++-- .../presence_interface/IPresenceActor.cs | 4 ++-- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/actor-presence/load_generator/Program.cs b/actor-presence/load_generator/Program.cs index e3fb0be9..bfb0ed7d 100644 --- a/actor-presence/load_generator/Program.cs +++ b/actor-presence/load_generator/Program.cs @@ -1,4 +1,9 @@ -namespace Dapr.Tests.Actors.PresenceTest +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +namespace Dapr.Tests.Actors.PresenceTest { using System; using System.Collections.Generic; @@ -19,8 +24,6 @@ private static void Main() var sendInterval = TimeSpan.FromSeconds(5); // interval for sending updates - // Precreate base heartbeat data objects for each of the games. - // We'll modify them before every time before sending. var heartbeats = new HeartbeatData[nGames]; for (var i = 0; i < nGames; i++) { @@ -40,7 +43,6 @@ private static void Main() while (true) { iteration++; - Console.WriteLine(); Console.WriteLine("Sending heartbeat series # {0}", iteration); ulong high = ((ulong) iteration) << 32; @@ -82,9 +84,6 @@ private static void Main() outstandingScoreReads.Add(t); } - // Wait for all calls to finish. - // It is okay to block the thread here because it's a client program with no parallelism. - // One should never block a thread in grain code. Task.WhenAll(outstandingScoreReads.ToArray()).Wait(); for (var i = 0; i < nGames; i++) @@ -97,9 +96,6 @@ private static void Main() Console.WriteLine("Error: {0}", e); } - Console.WriteLine(); - Console.WriteLine("Sleeping for {0} seconds.", sendInterval.TotalSeconds); - Console.WriteLine("Press CTRL-C to exit"); Thread.Sleep(sendInterval); } } diff --git a/actor-presence/presence_actor_service/GameActor.cs b/actor-presence/presence_actor_service/GameActor.cs index 722d9694..1c8ed07f 100644 --- a/actor-presence/presence_actor_service/GameActor.cs +++ b/actor-presence/presence_actor_service/GameActor.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest diff --git a/actor-presence/presence_actor_service/GameState.cs b/actor-presence/presence_actor_service/GameState.cs index 94222e29..f8be726d 100644 --- a/actor-presence/presence_actor_service/GameState.cs +++ b/actor-presence/presence_actor_service/GameState.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest diff --git a/actor-presence/presence_actor_service/PlayerActor.cs b/actor-presence/presence_actor_service/PlayerActor.cs index 8fa3a6d9..ec780bad 100644 --- a/actor-presence/presence_actor_service/PlayerActor.cs +++ b/actor-presence/presence_actor_service/PlayerActor.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest diff --git a/actor-presence/presence_actor_service/PlayerState.cs b/actor-presence/presence_actor_service/PlayerState.cs index d4df0fdf..99116ff3 100644 --- a/actor-presence/presence_actor_service/PlayerState.cs +++ b/actor-presence/presence_actor_service/PlayerState.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest diff --git a/actor-presence/presence_actor_service/PresenceActor.cs b/actor-presence/presence_actor_service/PresenceActor.cs index 053eea2a..217b028a 100644 --- a/actor-presence/presence_actor_service/PresenceActor.cs +++ b/actor-presence/presence_actor_service/PresenceActor.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest diff --git a/actor-presence/presence_actor_service/Program.cs b/actor-presence/presence_actor_service/Program.cs index a10c7fc5..c0f26565 100644 --- a/actor-presence/presence_actor_service/Program.cs +++ b/actor-presence/presence_actor_service/Program.cs @@ -1,3 +1,7 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest { diff --git a/actor-presence/presence_interface/GameStatus.cs b/actor-presence/presence_interface/GameStatus.cs index 5bb9e08f..ad9abf98 100644 --- a/actor-presence/presence_interface/GameStatus.cs +++ b/actor-presence/presence_interface/GameStatus.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest diff --git a/actor-presence/presence_interface/HeartbeatData.cs b/actor-presence/presence_interface/HeartbeatData.cs index 8ae1c54e..93021280 100644 --- a/actor-presence/presence_interface/HeartbeatData.cs +++ b/actor-presence/presence_interface/HeartbeatData.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest { diff --git a/actor-presence/presence_interface/IGameActor.cs b/actor-presence/presence_interface/IGameActor.cs index 8b15c3a9..a3ef3808 100644 --- a/actor-presence/presence_interface/IGameActor.cs +++ b/actor-presence/presence_interface/IGameActor.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest diff --git a/actor-presence/presence_interface/IPlayerActor.cs b/actor-presence/presence_interface/IPlayerActor.cs index f8de647b..95bb9625 100644 --- a/actor-presence/presence_interface/IPlayerActor.cs +++ b/actor-presence/presence_interface/IPlayerActor.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest diff --git a/actor-presence/presence_interface/IPresenceActor.cs b/actor-presence/presence_interface/IPresenceActor.cs index 1ea1c11c..7a1bf0ce 100644 --- a/actor-presence/presence_interface/IPresenceActor.cs +++ b/actor-presence/presence_interface/IPresenceActor.cs @@ -1,6 +1,6 @@ // ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr.Tests.Actors.PresenceTest