├── actor-hierarchy.png ├── Start ├── Messages │ ├── DumpSales.cs │ ├── DumpBackorders.cs │ ├── ActivateScanner.cs │ ├── ScanningCompleted.cs │ ├── ScanItem.cs │ ├── BackorderProduct.cs │ ├── PurchaseProduct.cs │ ├── SellProduct.cs │ ├── ProductPurchased.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Messages.csproj ├── Actors │ ├── packages.config │ ├── Models │ │ ├── Product.cs │ │ ├── Backorder.cs │ │ ├── Sale.cs │ │ ├── InventoryItem.cs │ │ └── Inventory.cs │ ├── Randomizer.cs │ ├── app.config │ ├── InventoryActor.cs │ ├── ScannerActor.cs │ ├── StoreActor.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── BackorderActor.cs │ ├── SalesActor.cs │ ├── ProductActor.cs │ ├── CustomerActor.cs │ └── Actors.csproj ├── Warehouse │ ├── packages.config │ ├── App.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Program.cs │ └── Warehouse.csproj ├── DemoApp.sln ├── .gitattributes └── .gitignore ├── Remoting ├── Messages │ ├── DumpSales.cs │ ├── DumpBackorders.cs │ ├── ActivateScanner.cs │ ├── ScanningCompleted.cs │ ├── ScanItem.cs │ ├── PurchaseProduct.cs │ ├── BackorderProduct.cs │ ├── SellProduct.cs │ ├── ProductPurchased.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Messages.csproj ├── Actors │ ├── packages.config │ ├── Models │ │ ├── Product.cs │ │ ├── Backorder.cs │ │ ├── Sale.cs │ │ ├── InventoryItem.cs │ │ └── Inventory.cs │ ├── Randomizer.cs │ ├── app.config │ ├── InventoryActor.cs │ ├── ScannerActor.cs │ ├── StoreActor.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── BackorderActor.cs │ ├── SalesActor.cs │ ├── ProductActor.cs │ ├── CustomerActor.cs │ └── Actors.csproj ├── Sales │ ├── Program.cs │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── App.config │ ├── CHANGES.txt │ └── Sales.csproj ├── Warehouse │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Program.cs │ ├── App.config │ └── Warehouse.csproj ├── DemoApp.sln ├── .gitattributes └── .gitignore ├── Persistence ├── Messages │ ├── DumpSales.cs │ ├── DumpBackorders.cs │ ├── ActivateScanner.cs │ ├── ScanningCompleted.cs │ ├── ScanItem.cs │ ├── BackorderProduct.cs │ ├── PurchaseProduct.cs │ ├── SellProduct.cs │ ├── ProductPurchased.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Messages.csproj ├── preparepersistence.ps1 ├── Actors │ ├── Models │ │ ├── Product.cs │ │ ├── Backorder.cs │ │ ├── Sale.cs │ │ ├── InventoryItem.cs │ │ └── Inventory.cs │ ├── packages.config │ ├── Randomizer.cs │ ├── Events │ │ └── ProductSold.cs │ ├── app.config │ ├── InventoryActor.cs │ ├── ScannerActor.cs │ ├── StoreActor.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── BackorderActor.cs │ ├── ProductActor.cs │ ├── CustomerActor.cs │ ├── SalesActor.cs │ └── Actors.csproj ├── Sales │ ├── Program.cs │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── App.config │ ├── CHANGES.txt │ └── Sales.csproj ├── Warehouse │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Program.cs │ ├── App.config │ └── Warehouse.csproj ├── .gitattributes ├── DemoApp.sln └── .gitignore ├── Building Actor Model systems using Akka-NET - Edwin van Wijk.pdf ├── .gitattributes ├── .gitignore └── README.md /actor-hierarchy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdwinVW/akka.net-warehouse-sample/HEAD/actor-hierarchy.png -------------------------------------------------------------------------------- /Start/Messages/DumpSales.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class DumpSales 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Remoting/Messages/DumpSales.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class DumpSales 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Persistence/Messages/DumpSales.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class DumpSales 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Start/Messages/DumpBackorders.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class DumpBackorders 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Remoting/Messages/DumpBackorders.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class DumpBackorders 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Persistence/Messages/DumpBackorders.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class DumpBackorders 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Persistence/preparepersistence.ps1: -------------------------------------------------------------------------------- 1 | cd "C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator" 2 | .\AzureStorageEmulator.exe start 3 | .\AzureStorageEmulator.exe clear table 4 | -------------------------------------------------------------------------------- /Building Actor Model systems using Akka-NET - Edwin van Wijk.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdwinVW/akka.net-warehouse-sample/HEAD/Building Actor Model systems using Akka-NET - Edwin van Wijk.pdf -------------------------------------------------------------------------------- /Start/Messages/ActivateScanner.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ActivateScanner 4 | { 5 | public string ScannerId { get; private set; } 6 | 7 | public ActivateScanner(string scannerId) 8 | { 9 | ScannerId = scannerId; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Start/Messages/ScanningCompleted.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ScanningCompleted 4 | { 5 | public int ScannerId { get; private set; } 6 | 7 | public ScanningCompleted(int scannerId) 8 | { 9 | ScannerId = scannerId; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Persistence/Messages/ActivateScanner.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ActivateScanner 4 | { 5 | public string ScannerId { get; private set; } 6 | 7 | public ActivateScanner(string scannerId) 8 | { 9 | ScannerId = scannerId; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Persistence/Messages/ScanningCompleted.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ScanningCompleted 4 | { 5 | public int ScannerId { get; private set; } 6 | 7 | public ScanningCompleted(int scannerId) 8 | { 9 | ScannerId = scannerId; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Remoting/Messages/ActivateScanner.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ActivateScanner 4 | { 5 | public string ScannerId { get; private set; } 6 | 7 | public ActivateScanner(string scannerId) 8 | { 9 | ScannerId = scannerId; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Remoting/Messages/ScanningCompleted.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ScanningCompleted 4 | { 5 | public int ScannerId { get; private set; } 6 | 7 | public ScanningCompleted(int scannerId) 8 | { 9 | ScannerId = scannerId; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Start/Messages/ScanItem.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ScanItem 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public ScanItem(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Remoting/Messages/ScanItem.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ScanItem 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public ScanItem(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Persistence/Messages/ScanItem.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ScanItem 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public ScanItem(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Remoting/Messages/PurchaseProduct.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class PurchaseProduct 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public PurchaseProduct(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Start/Messages/BackorderProduct.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class BackorderProduct 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public BackorderProduct(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Start/Messages/PurchaseProduct.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class PurchaseProduct 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public PurchaseProduct(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Persistence/Messages/BackorderProduct.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class BackorderProduct 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public BackorderProduct(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Persistence/Messages/PurchaseProduct.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class PurchaseProduct 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public PurchaseProduct(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Remoting/Actors/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Remoting/Messages/BackorderProduct.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class BackorderProduct 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public BackorderProduct(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Start/Actors/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Remoting/Actors/Models/Product.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class Product 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } 7 | public decimal Price { get; set; } 8 | 9 | public Product(int id, string name, decimal price) 10 | { 11 | Id = id; 12 | Name = name; 13 | Price = price; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Start/Actors/Models/Product.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class Product 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } 7 | public decimal Price { get; set; } 8 | 9 | public Product(int id, string name, decimal price) 10 | { 11 | Id = id; 12 | Name = name; 13 | Price = price; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Persistence/Actors/Models/Product.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class Product 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } 7 | public decimal Price { get; set; } 8 | 9 | public Product(int id, string name, decimal price) 10 | { 11 | Id = id; 12 | Name = name; 13 | Price = price; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Persistence/Sales/Program.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using System; 3 | 4 | namespace Sales 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | // start system 11 | using (ActorSystem system = ActorSystem.Create("sales")) 12 | { 13 | Console.WriteLine("Sales system online. Press any key to stop"); 14 | 15 | Console.ReadKey(true); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Remoting/Sales/Program.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using System; 3 | 4 | namespace Sales 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | // start system 11 | using (ActorSystem system = ActorSystem.Create("sales")) 12 | { 13 | Console.WriteLine("Sales system online. Press any key to stop"); 14 | 15 | Console.ReadKey(true); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Start/Actors/Models/Backorder.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class Backorder 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public Backorder(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | 14 | public void Increase(int amount) 15 | { 16 | Amount += amount; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Remoting/Actors/Models/Backorder.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class Backorder 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public Backorder(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | 14 | public void Increase(int amount) 15 | { 16 | Amount += amount; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Remoting/Messages/SellProduct.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class SellProduct 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | public decimal TotalPrice { get; private set; } 8 | 9 | public SellProduct(int productId, int amount, decimal totalPrice) 10 | { 11 | ProductId = productId; 12 | Amount = amount; 13 | TotalPrice = totalPrice; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Start/Messages/SellProduct.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class SellProduct 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | public decimal TotalPrice { get; private set; } 8 | 9 | public SellProduct(int productId, int amount, decimal totalPrice) 10 | { 11 | ProductId = productId; 12 | Amount = amount; 13 | TotalPrice = totalPrice; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Persistence/Actors/Models/Backorder.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class Backorder 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | 8 | public Backorder(int productId, int amount) 9 | { 10 | ProductId = productId; 11 | Amount = amount; 12 | } 13 | 14 | public void Increase(int amount) 15 | { 16 | Amount += amount; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Persistence/Messages/SellProduct.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class SellProduct 4 | { 5 | public int ProductId { get; private set; } 6 | public int Amount { get; private set; } 7 | public decimal TotalPrice { get; private set; } 8 | 9 | public SellProduct(int productId, int amount, decimal totalPrice) 10 | { 11 | ProductId = productId; 12 | Amount = amount; 13 | TotalPrice = totalPrice; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Start/Messages/ProductPurchased.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ProductPurchased 4 | { 5 | public int ProductId { get; private set; } 6 | public int AmountPurchased { get; private set; } 7 | public int AmountBackorder { get; private set; } 8 | 9 | public ProductPurchased(int productId, int amountPurchased, int amountBackorder) 10 | { 11 | ProductId = productId; 12 | AmountPurchased = amountPurchased; 13 | AmountBackorder = amountBackorder; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Remoting/Messages/ProductPurchased.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ProductPurchased 4 | { 5 | public int ProductId { get; private set; } 6 | public int AmountPurchased { get; private set; } 7 | public int AmountBackorder { get; private set; } 8 | 9 | public ProductPurchased(int productId, int amountPurchased, int amountBackorder) 10 | { 11 | ProductId = productId; 12 | AmountPurchased = amountPurchased; 13 | AmountBackorder = amountBackorder; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Persistence/Messages/ProductPurchased.cs: -------------------------------------------------------------------------------- 1 | namespace Messages 2 | { 3 | public class ProductPurchased 4 | { 5 | public int ProductId { get; private set; } 6 | public int AmountPurchased { get; private set; } 7 | public int AmountBackorder { get; private set; } 8 | 9 | public ProductPurchased(int productId, int amountPurchased, int amountBackorder) 10 | { 11 | ProductId = productId; 12 | AmountPurchased = amountPurchased; 13 | AmountBackorder = amountBackorder; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Persistence/Actors/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Start/Actors/Randomizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Actors 4 | { 5 | public static class Randomizer 6 | { 7 | private static Random _rnd = new Random((int)DateTime.Now.Ticks); 8 | 9 | public static int Next() 10 | { 11 | return _rnd.Next(); 12 | } 13 | 14 | public static int Next(int maxValue) 15 | { 16 | return _rnd.Next(maxValue); 17 | } 18 | 19 | public static int Next(int minValue, int maxValue) 20 | { 21 | return _rnd.Next(minValue, maxValue); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Persistence/Actors/Randomizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Actors 4 | { 5 | public static class Randomizer 6 | { 7 | private static Random _rnd = new Random((int)DateTime.Now.Ticks); 8 | 9 | public static int Next() 10 | { 11 | return _rnd.Next(); 12 | } 13 | 14 | public static int Next(int maxValue) 15 | { 16 | return _rnd.Next(maxValue); 17 | } 18 | 19 | public static int Next(int minValue, int maxValue) 20 | { 21 | return _rnd.Next(minValue, maxValue); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Remoting/Actors/Randomizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Actors 4 | { 5 | public static class Randomizer 6 | { 7 | private static Random _rnd = new Random((int)DateTime.Now.Ticks); 8 | 9 | public static int Next() 10 | { 11 | return _rnd.Next(); 12 | } 13 | 14 | public static int Next(int maxValue) 15 | { 16 | return _rnd.Next(maxValue); 17 | } 18 | 19 | public static int Next(int minValue, int maxValue) 20 | { 21 | return _rnd.Next(minValue, maxValue); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Remoting/Actors/Models/Sale.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class Sale 4 | { 5 | public int ProductId { get; private set; } 6 | public int TotalAmount { get; private set; } 7 | public decimal TotalPrice { get; private set; } 8 | 9 | public Sale(int productId, int amount, decimal totalPrice) 10 | { 11 | ProductId = productId; 12 | TotalAmount = amount; 13 | TotalPrice = totalPrice; 14 | } 15 | 16 | public void Increase(int amount, decimal totalPrice) 17 | { 18 | TotalAmount += amount; 19 | TotalPrice += totalPrice; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Start/Actors/Models/Sale.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class Sale 4 | { 5 | public int ProductId { get; private set; } 6 | public int TotalAmount { get; private set; } 7 | public decimal TotalPrice { get; private set; } 8 | 9 | public Sale(int productId, int amount, decimal totalPrice) 10 | { 11 | ProductId = productId; 12 | TotalAmount = amount; 13 | TotalPrice = totalPrice; 14 | } 15 | 16 | public void Increase(int amount, decimal totalPrice) 17 | { 18 | TotalAmount += amount; 19 | TotalPrice += totalPrice; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Persistence/Actors/Events/ProductSold.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Actors.Events 9 | { 10 | public class ProductSold 11 | { 12 | public int ProductId { get; private set; } 13 | public int Amount { get; private set; } 14 | public decimal TotalPrice { get; private set; } 15 | 16 | public ProductSold(int productId, int amount, decimal totalPrice) 17 | { 18 | ProductId = productId; 19 | Amount = amount; 20 | TotalPrice = totalPrice; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Persistence/Actors/Models/Sale.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class Sale 4 | { 5 | public int ProductId { get; private set; } 6 | public int TotalAmount { get; private set; } 7 | public decimal TotalPrice { get; private set; } 8 | 9 | public Sale(int productId, int amount, decimal totalPrice) 10 | { 11 | ProductId = productId; 12 | TotalAmount = amount; 13 | TotalPrice = totalPrice; 14 | } 15 | 16 | public void Increase(int amount, decimal totalPrice) 17 | { 18 | TotalAmount += amount; 19 | TotalPrice += totalPrice; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Remoting/Actors/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Start/Actors/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Persistence/Actors/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Remoting/Sales/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Start/Warehouse/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Remoting/Warehouse/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Start/Actors/Models/InventoryItem.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class InventoryItem 4 | { 5 | public Product Product { get; private set; } 6 | public int Stock { get; private set; } 7 | 8 | public InventoryItem(Product product, int initialStock) 9 | { 10 | Product = product; 11 | Stock = initialStock; 12 | } 13 | 14 | public int Purchase(int amount) 15 | { 16 | int backorderAmount = 0; 17 | if (Stock < amount) 18 | { 19 | backorderAmount = amount - Stock; 20 | Stock = 0; 21 | } 22 | else 23 | { 24 | Stock -= amount; 25 | } 26 | return backorderAmount; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Persistence/Actors/Models/InventoryItem.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class InventoryItem 4 | { 5 | public Product Product { get; private set; } 6 | public int Stock { get; private set; } 7 | 8 | public InventoryItem(Product product, int initialStock) 9 | { 10 | Product = product; 11 | Stock = initialStock; 12 | } 13 | 14 | public int Purchase(int amount) 15 | { 16 | int backorderAmount = 0; 17 | if (Stock < amount) 18 | { 19 | backorderAmount = amount - Stock; 20 | Stock = 0; 21 | } 22 | else 23 | { 24 | Stock -= amount; 25 | } 26 | return backorderAmount; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Remoting/Actors/Models/InventoryItem.cs: -------------------------------------------------------------------------------- 1 | namespace Actors.Models 2 | { 3 | public class InventoryItem 4 | { 5 | public Product Product { get; private set; } 6 | public int Stock { get; private set; } 7 | 8 | public InventoryItem(Product product, int initialStock) 9 | { 10 | Product = product; 11 | Stock = initialStock; 12 | } 13 | 14 | public int Purchase(int amount) 15 | { 16 | int backorderAmount = 0; 17 | if (Stock < amount) 18 | { 19 | backorderAmount = amount - Stock; 20 | Stock = 0; 21 | } 22 | else 23 | { 24 | Stock -= amount; 25 | } 26 | return backorderAmount; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Persistence/Warehouse/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Start/Actors/InventoryActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Actors.Models; 3 | using Messages; 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Actors 8 | { 9 | public class InventoryActor : ReceiveActor 10 | { 11 | private Inventory _inventory; 12 | private List _productActors = new List(); 13 | 14 | public InventoryActor() 15 | { 16 | _inventory = new Inventory(); 17 | 18 | // start a product actor for each inventoryitem 19 | foreach (InventoryItem item in _inventory.Items) 20 | { 21 | string actorName = $"product-{item.Product.Id}"; 22 | Props props = new Props(typeof(ProductActor), new object[] { item.Product, item.Stock }); 23 | _productActors.Add(Context.ActorOf(props, actorName)); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Persistence/Actors/InventoryActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Actors.Models; 3 | using Messages; 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Actors 8 | { 9 | public class InventoryActor : ReceiveActor 10 | { 11 | private Inventory _inventory; 12 | private List _productActors = new List(); 13 | 14 | public InventoryActor() 15 | { 16 | _inventory = new Inventory(); 17 | 18 | // start a product actor for each inventoryitem 19 | foreach (InventoryItem item in _inventory.Items) 20 | { 21 | string actorName = $"product-{item.Product.Id}"; 22 | Props props = new Props(typeof(ProductActor), new object[] { item.Product, item.Stock }); 23 | _productActors.Add(Context.ActorOf(props, actorName)); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Remoting/Actors/InventoryActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Actors.Models; 3 | using Messages; 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Actors 8 | { 9 | public class InventoryActor : ReceiveActor 10 | { 11 | private Inventory _inventory; 12 | private List _productActors = new List(); 13 | 14 | public InventoryActor() 15 | { 16 | _inventory = new Inventory(); 17 | 18 | // start a product actor for each inventoryitem 19 | foreach (InventoryItem item in _inventory.Items) 20 | { 21 | string actorName = $"product-{item.Product.Id}"; 22 | Props props = new Props(typeof(ProductActor), new object[] { item.Product, item.Stock }); 23 | _productActors.Add(Context.ActorOf(props, actorName)); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Start/Actors/ScannerActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System; 4 | using Messages; 5 | 6 | namespace Actors 7 | { 8 | public class ScannerActor : TypedActor, IHandle 9 | { 10 | private string _scannerId; 11 | private IActorRef _storeActor; 12 | 13 | public ScannerActor(string scannerId) 14 | { 15 | // setup state 16 | _scannerId = scannerId; 17 | 18 | // define other actors 19 | _storeActor = Context.Parent; 20 | } 21 | 22 | public void Handle(ScanItem message) 23 | { 24 | // purchase product 25 | string productPath = $"/user/inventory/product-{message.ProductId}"; 26 | Context.ActorSelection(productPath) 27 | .Tell(new PurchaseProduct(message.ProductId, message.Amount)); 28 | 29 | // show status 30 | ColorConsole.WriteLine($"Scanner #{_scannerId} : scanned {message.Amount} units of product {message.ProductId}.".Yellow()); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Persistence/Actors/ScannerActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System; 4 | using Messages; 5 | 6 | namespace Actors 7 | { 8 | public class ScannerActor : TypedActor, IHandle 9 | { 10 | private string _scannerId; 11 | private IActorRef _storeActor; 12 | 13 | public ScannerActor(string scannerId) 14 | { 15 | // setup state 16 | _scannerId = scannerId; 17 | 18 | // define other actors 19 | _storeActor = Context.Parent; 20 | } 21 | 22 | public void Handle(ScanItem message) 23 | { 24 | // purchase product 25 | string productPath = $"/user/inventory/product-{message.ProductId}"; 26 | Context.ActorSelection(productPath) 27 | .Tell(new PurchaseProduct(message.ProductId, message.Amount)); 28 | 29 | // show status 30 | ColorConsole.WriteLine($"Scanner #{_scannerId} : scanned {message.Amount} units of product {message.ProductId}.".Yellow()); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Remoting/Actors/ScannerActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System; 4 | using Messages; 5 | 6 | namespace Actors 7 | { 8 | public class ScannerActor : TypedActor, IHandle 9 | { 10 | private string _scannerId; 11 | private IActorRef _storeActor; 12 | 13 | public ScannerActor(string scannerId) 14 | { 15 | // setup state 16 | _scannerId = scannerId; 17 | 18 | // define other actors 19 | _storeActor = Context.Parent; 20 | } 21 | 22 | public void Handle(ScanItem message) 23 | { 24 | // purchase product 25 | string productPath = $"/user/inventory/product-{message.ProductId}"; 26 | Context.ActorSelection(productPath) 27 | .Tell(new PurchaseProduct(message.ProductId, message.Amount)); 28 | 29 | // show status 30 | ColorConsole.WriteLine($"Scanner #{_scannerId} : scanned {message.Amount} units of product {message.ProductId}.".Yellow()); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Start/Actors/Models/Inventory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Actors.Models 6 | { 7 | public class Inventory 8 | { 9 | private int MIN_INITIAL_STOCK = 5; 10 | private const int MAX_INITIAL_STOCK = 25; 11 | private const double MIN_PRICE = 1.95; 12 | private const double MAX_PRICE = 999.95; 13 | private Random _rnd = new Random(); 14 | private List _items = new List(); 15 | 16 | public IEnumerable Items 17 | { 18 | get 19 | { 20 | return _items; 21 | } 22 | } 23 | 24 | public Inventory() 25 | { 26 | for (int i = 1; i <= 25; i++) 27 | { 28 | var product = new Product( 29 | i, 30 | $"Product #{i}", 31 | Math.Round(RandomNumberBetween(MIN_PRICE, MAX_PRICE), 2)); 32 | var inventoryItem = new InventoryItem(product, _rnd.Next(MIN_INITIAL_STOCK, MAX_INITIAL_STOCK)); 33 | _items.Add(inventoryItem); 34 | } 35 | } 36 | 37 | private decimal RandomNumberBetween(double minValue, double maxValue) 38 | { 39 | var next = _rnd.NextDouble(); 40 | 41 | return (decimal)(minValue + (next * (maxValue - minValue))); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Remoting/Actors/Models/Inventory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Actors.Models 6 | { 7 | public class Inventory 8 | { 9 | private int MIN_INITIAL_STOCK = 5; 10 | private const int MAX_INITIAL_STOCK = 25; 11 | private const double MIN_PRICE = 1.95; 12 | private const double MAX_PRICE = 999.95; 13 | private Random _rnd = new Random(); 14 | private List _items = new List(); 15 | 16 | public IEnumerable Items 17 | { 18 | get 19 | { 20 | return _items; 21 | } 22 | } 23 | 24 | public Inventory() 25 | { 26 | for (int i = 1; i <= 25; i++) 27 | { 28 | var product = new Product( 29 | i, 30 | $"Product #{i}", 31 | Math.Round(RandomNumberBetween(MIN_PRICE, MAX_PRICE), 2)); 32 | var inventoryItem = new InventoryItem(product, _rnd.Next(MIN_INITIAL_STOCK, MAX_INITIAL_STOCK)); 33 | _items.Add(inventoryItem); 34 | } 35 | } 36 | 37 | private decimal RandomNumberBetween(double minValue, double maxValue) 38 | { 39 | var next = _rnd.NextDouble(); 40 | 41 | return (decimal)(minValue + (next * (maxValue - minValue))); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Persistence/Actors/Models/Inventory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Actors.Models 6 | { 7 | public class Inventory 8 | { 9 | private int MIN_INITIAL_STOCK = 5; 10 | private const int MAX_INITIAL_STOCK = 25; 11 | private const double MIN_PRICE = 1.95; 12 | private const double MAX_PRICE = 999.95; 13 | private Random _rnd = new Random(); 14 | private List _items = new List(); 15 | 16 | public IEnumerable Items 17 | { 18 | get 19 | { 20 | return _items; 21 | } 22 | } 23 | 24 | public Inventory() 25 | { 26 | for (int i = 1; i <= 25; i++) 27 | { 28 | var product = new Product( 29 | i, 30 | $"Product #{i}", 31 | Math.Round(RandomNumberBetween(MIN_PRICE, MAX_PRICE), 2)); 32 | var inventoryItem = new InventoryItem(product, _rnd.Next(MIN_INITIAL_STOCK, MAX_INITIAL_STOCK)); 33 | _items.Add(inventoryItem); 34 | } 35 | } 36 | 37 | private decimal RandomNumberBetween(double minValue, double maxValue) 38 | { 39 | var next = _rnd.NextDouble(); 40 | 41 | return (decimal)(minValue + (next * (maxValue - minValue))); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Start/Warehouse/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Start/Actors/StoreActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using Messages; 4 | 5 | namespace Actors 6 | { 7 | public class StoreActor : ReceiveActor 8 | { 9 | private int _storeId; 10 | private int _numberOfCustomers = 1; 11 | private int _activeScanners = 0; 12 | 13 | public StoreActor(int storeId) 14 | { 15 | _storeId = storeId; 16 | 17 | // setup message-handling 18 | Receive(msg => Handle(msg)); 19 | Receive(msg => Handle(msg)); 20 | 21 | for (int i = 0; i < _numberOfCustomers; i++) 22 | { 23 | Props props = Props.Create(new object[] { _storeId, i }); 24 | Context.ActorOf(props, $"user{_storeId}-{i}"); 25 | } 26 | } 27 | 28 | private void Handle(ActivateScanner message) 29 | { 30 | _activeScanners++; 31 | ColorConsole.WriteLine($"Scanner #{message.ScannerId} activated.".White()); 32 | } 33 | 34 | private void Handle(ScanningCompleted message) 35 | { 36 | ColorConsole.WriteLine($"Scanner #{message.ScannerId} returned.".White()); 37 | 38 | _activeScanners--; 39 | if (_activeScanners == 0) 40 | { 41 | ColorConsole.WriteLine($"All scanners in store {_storeId} have been returned.".White()); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Persistence/Actors/StoreActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using Messages; 4 | 5 | namespace Actors 6 | { 7 | public class StoreActor : ReceiveActor 8 | { 9 | private int _storeId; 10 | private int _numberOfCustomers = 1; 11 | private int _activeScanners = 0; 12 | 13 | public StoreActor(int storeId) 14 | { 15 | _storeId = storeId; 16 | 17 | // setup message-handling 18 | Receive(msg => Handle(msg)); 19 | Receive(msg => Handle(msg)); 20 | 21 | for (int i = 0; i < _numberOfCustomers; i++) 22 | { 23 | Props props = Props.Create(new object[] { _storeId, i }); 24 | Context.ActorOf(props, $"user{_storeId}-{i}"); 25 | } 26 | } 27 | 28 | private void Handle(ActivateScanner message) 29 | { 30 | _activeScanners++; 31 | ColorConsole.WriteLine($"Scanner #{message.ScannerId} activated.".White()); 32 | } 33 | 34 | private void Handle(ScanningCompleted message) 35 | { 36 | ColorConsole.WriteLine($"Scanner #{message.ScannerId} returned.".White()); 37 | 38 | _activeScanners--; 39 | if (_activeScanners == 0) 40 | { 41 | ColorConsole.WriteLine($"All scanners in store {_storeId} have been returned.".White()); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Persistence/Sales/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Remoting/Actors/StoreActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using Messages; 4 | 5 | namespace Actors 6 | { 7 | public class StoreActor : ReceiveActor 8 | { 9 | private int _storeId; 10 | private int _numberOfCustomers = 1; 11 | private int _activeScanners = 0; 12 | 13 | public StoreActor(int storeId) 14 | { 15 | _storeId = storeId; 16 | 17 | // setup message-handling 18 | Receive(msg => Handle(msg)); 19 | Receive(msg => Handle(msg)); 20 | 21 | for (int i = 0; i < _numberOfCustomers; i++) 22 | { 23 | Props props = Props.Create(new object[] { _storeId, i }); 24 | Context.ActorOf(props, $"user{_storeId}-{i}"); 25 | } 26 | } 27 | 28 | private void Handle(ActivateScanner message) 29 | { 30 | _activeScanners++; 31 | ColorConsole.WriteLine($"Scanner #{message.ScannerId} activated.".White()); 32 | } 33 | 34 | private void Handle(ScanningCompleted message) 35 | { 36 | ColorConsole.WriteLine($"Scanner #{message.ScannerId} returned.".White()); 37 | 38 | _activeScanners--; 39 | if (_activeScanners == 0) 40 | { 41 | ColorConsole.WriteLine($"All scanners in store {_storeId} have been returned.".White()); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Persistence/Sales/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Sales")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Sales")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c03236e9-d67b-40a3-973d-7f1b8700d44a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Remoting/Actors/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Actors")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Actors")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f4aff44d-9f2b-4e10-b954-12e16f9f3e9b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Remoting/Sales/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Sales")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Sales")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c03236e9-d67b-40a3-973d-7f1b8700d44a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Start/Actors/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Actors")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Actors")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f4aff44d-9f2b-4e10-b954-12e16f9f3e9b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Persistence/Actors/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Actors")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Actors")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f4aff44d-9f2b-4e10-b954-12e16f9f3e9b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Remoting/Messages/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Messages")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Messages")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8fb4e144-9233-4f30-a1a8-c77143f6410b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Start/Messages/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Messages")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Messages")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8fb4e144-9233-4f30-a1a8-c77143f6410b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Start/Warehouse/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Warehouse")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Warehouse")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("143d9ecd-377f-42f9-a1e6-18e19267d94a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Persistence/Messages/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Messages")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Messages")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8fb4e144-9233-4f30-a1a8-c77143f6410b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Remoting/Warehouse/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Warehouse")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Warehouse")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("143d9ecd-377f-42f9-a1e6-18e19267d94a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Persistence/Warehouse/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Warehouse")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Warehouse")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("143d9ecd-377f-42f9-a1e6-18e19267d94a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Persistence/Warehouse/Program.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using System; 3 | using Actors; 4 | using Messages; 5 | 6 | namespace Warehouse 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | int numberOfStores = 1; 13 | 14 | // start system 15 | using (ActorSystem system = ActorSystem.Create("warehouse")) 16 | { 17 | // create child actors 18 | IActorRef inventoryActor = system.ActorOf("inventory"); 19 | IActorRef salesActor = system.ActorOf("sales"); 20 | salesActor.Tell(new DumpSales()); 21 | IActorRef backorderActor = system.ActorOf("backorder"); 22 | 23 | Console.WriteLine("Press any key to open the stores..."); 24 | Console.ReadKey(true); 25 | 26 | // start store simulation 27 | for (int i = 0; i < numberOfStores; i++) 28 | { 29 | Props props = Props.Create(new object[] { i }); 30 | system.ActorOf(props, $"store{i}"); 31 | } 32 | 33 | Console.ReadKey(true); // keep the actorsystem alive 34 | 35 | // dump backorders 36 | Console.WriteLine("\nDumping backorders"); 37 | system.ActorSelection("/user/backorder").Tell(new DumpBackorders()); 38 | Console.ReadKey(true); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Remoting/Warehouse/Program.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using System; 3 | using Actors; 4 | using Messages; 5 | 6 | namespace Warehouse 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | int numberOfStores = 1; 13 | 14 | // start system 15 | using (ActorSystem system = ActorSystem.Create("warehouse")) 16 | { 17 | // create child actors 18 | IActorRef inventoryActor = system.ActorOf("inventory"); 19 | IActorRef salesActor = system.ActorOf("sales"); 20 | salesActor.Tell(new DumpSales()); 21 | IActorRef backorderActor = system.ActorOf("backorder"); 22 | 23 | Console.WriteLine("Press any key to open the stores..."); 24 | Console.ReadKey(true); 25 | 26 | // start store simulation 27 | for (int i = 0; i < numberOfStores; i++) 28 | { 29 | Props props = Props.Create(new object[] { i }); 30 | system.ActorOf(props, $"store{i}"); 31 | } 32 | 33 | Console.ReadKey(true); // keep the actorsystem alive 34 | 35 | // dump backorders 36 | Console.WriteLine("\nDumping backorders"); 37 | system.ActorSelection("/user/backorder").Tell(new DumpBackorders()); 38 | Console.ReadKey(true); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Start/Warehouse/Program.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using System; 3 | using Actors; 4 | using Messages; 5 | 6 | namespace Warehouse 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | int numberOfStores = 1; 13 | 14 | // start system 15 | using (ActorSystem system = ActorSystem.Create("warehouse")) 16 | { 17 | // create child actors 18 | IActorRef inventoryActor = system.ActorOf("inventory"); 19 | IActorRef salesActor = system.ActorOf("sales"); 20 | IActorRef backorderActor = system.ActorOf("backorder"); 21 | 22 | Console.WriteLine("Press any key to open the stores..."); 23 | Console.ReadKey(true); 24 | 25 | // start store simulation 26 | for (int i = 0; i < numberOfStores; i++) 27 | { 28 | Props props = Props.Create(new object[] { i }); 29 | system.ActorOf(props, $"store{i}"); 30 | } 31 | 32 | Console.ReadKey(true); // keep the actorsystem alive 33 | 34 | // dump backorders 35 | Console.WriteLine("\nDumping sales"); 36 | salesActor.Tell(new DumpSales()); 37 | Console.ReadKey(true); 38 | 39 | // dump backorders 40 | Console.WriteLine("\nDumping backorders"); 41 | backorderActor.Tell(new DumpBackorders()); 42 | Console.ReadKey(true); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Remoting/Actors/BackorderActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Messages; 6 | using Actors.Models; 7 | 8 | namespace Actors 9 | { 10 | public class BackorderActor : TypedActor, IHandle, IHandle 11 | { 12 | private List _backorders; 13 | 14 | public BackorderActor() 15 | { 16 | _backorders = new List(); 17 | } 18 | 19 | public void Handle(BackorderProduct message) 20 | { 21 | UpdateState(message); 22 | 23 | ColorConsole.WriteLine($"Backorder {message.Amount} units of product {message.ProductId}".Red()); 24 | } 25 | 26 | public void Handle(DumpBackorders message) 27 | { 28 | ColorConsole.WriteLine("Backorder overview:".Red()); 29 | ColorConsole.WriteLine("===================".Red()); 30 | foreach (var backorder in _backorders.OrderBy(b => b.ProductId)) 31 | { 32 | ColorConsole.WriteLine($"Product {backorder.ProductId} : {backorder.Amount} units.".Red()); 33 | } 34 | } 35 | 36 | private void UpdateState(BackorderProduct message) 37 | { 38 | var backorder = _backorders.FirstOrDefault(b => b.ProductId == message.ProductId); 39 | if (backorder == null) 40 | { 41 | backorder = new Backorder(message.ProductId, message.Amount); 42 | _backorders.Add(backorder); 43 | } 44 | else 45 | { 46 | backorder.Increase(message.Amount); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Start/Actors/BackorderActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Messages; 6 | using Actors.Models; 7 | 8 | namespace Actors 9 | { 10 | public class BackorderActor : TypedActor, IHandle, IHandle 11 | { 12 | private List _backorders; 13 | 14 | public BackorderActor() 15 | { 16 | _backorders = new List(); 17 | } 18 | 19 | public void Handle(BackorderProduct message) 20 | { 21 | UpdateState(message); 22 | 23 | ColorConsole.WriteLine($"Backorder {message.Amount} units of product {message.ProductId}".Red()); 24 | } 25 | 26 | public void Handle(DumpBackorders message) 27 | { 28 | ColorConsole.WriteLine("Backorder overview:".Red()); 29 | ColorConsole.WriteLine("===================".Red()); 30 | foreach (var backorder in _backorders.OrderBy(b => b.ProductId)) 31 | { 32 | ColorConsole.WriteLine($"Product {backorder.ProductId} : {backorder.Amount} units.".Red()); 33 | } 34 | } 35 | 36 | private void UpdateState(BackorderProduct message) 37 | { 38 | var backorder = _backorders.FirstOrDefault(b => b.ProductId == message.ProductId); 39 | if (backorder == null) 40 | { 41 | backorder = new Backorder(message.ProductId, message.Amount); 42 | _backorders.Add(backorder); 43 | } 44 | else 45 | { 46 | backorder.Increase(message.Amount); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Persistence/Actors/BackorderActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Messages; 6 | using Actors.Models; 7 | 8 | namespace Actors 9 | { 10 | public class BackorderActor : TypedActor, IHandle, IHandle 11 | { 12 | private List _backorders; 13 | 14 | public BackorderActor() 15 | { 16 | _backorders = new List(); 17 | } 18 | 19 | public void Handle(BackorderProduct message) 20 | { 21 | UpdateState(message); 22 | 23 | ColorConsole.WriteLine($"Backorder {message.Amount} units of product {message.ProductId}".Red()); 24 | } 25 | 26 | public void Handle(DumpBackorders message) 27 | { 28 | ColorConsole.WriteLine("Backorder overview:".Red()); 29 | ColorConsole.WriteLine("===================".Red()); 30 | foreach (var backorder in _backorders.OrderBy(b => b.ProductId)) 31 | { 32 | ColorConsole.WriteLine($"Product {backorder.ProductId} : {backorder.Amount} units.".Red()); 33 | } 34 | } 35 | 36 | private void UpdateState(BackorderProduct message) 37 | { 38 | var backorder = _backorders.FirstOrDefault(b => b.ProductId == message.ProductId); 39 | if (backorder == null) 40 | { 41 | backorder = new Backorder(message.ProductId, message.Amount); 42 | _backorders.Add(backorder); 43 | } 44 | else 45 | { 46 | backorder.Increase(message.Amount); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Start/Actors/SalesActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Messages; 6 | using Actors.Models; 7 | using System; 8 | 9 | namespace Actors 10 | { 11 | public class SalesActor : TypedActor, IHandle, IHandle 12 | { 13 | private List _sales; 14 | 15 | public SalesActor() 16 | { 17 | _sales = new List(); 18 | } 19 | 20 | public void Handle(SellProduct message) 21 | { 22 | UpdateState(message); 23 | } 24 | 25 | public void Handle(DumpSales message) 26 | { 27 | ColorConsole.WriteLine($"Sales overview ({DateTime.Now.ToString("HH:mm:ss")}):".Cyan()); 28 | ColorConsole.WriteLine("==========================".Cyan()); 29 | decimal totalSales = 0; 30 | foreach (var sale in _sales.OrderBy(s => s.ProductId)) 31 | { 32 | ColorConsole.WriteLine($"Product {sale.ProductId} : {sale.TotalAmount} units - {sale.TotalPrice} Euro.".Cyan()); 33 | totalSales += sale.TotalPrice; 34 | } 35 | ColorConsole.WriteLine($"Total: {totalSales} Euro".Cyan()); 36 | } 37 | 38 | private void UpdateState(SellProduct message) 39 | { 40 | var sale = _sales.FirstOrDefault(s => s.ProductId == message.ProductId); 41 | if (sale == null) 42 | { 43 | sale = new Sale(message.ProductId, message.Amount, message.TotalPrice); 44 | _sales.Add(sale); 45 | } 46 | else 47 | { 48 | sale.Increase(message.Amount, message.TotalPrice); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Remoting/Sales/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Remoting/Actors/SalesActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Messages; 6 | using Actors.Models; 7 | using System; 8 | 9 | namespace Actors 10 | { 11 | public class SalesActor : TypedActor, IHandle, IHandle 12 | { 13 | private List _sales; 14 | 15 | public SalesActor() 16 | { 17 | _sales = new List(); 18 | } 19 | 20 | public void Handle(SellProduct message) 21 | { 22 | UpdateState(message); 23 | } 24 | 25 | public void Handle(DumpSales message) 26 | { 27 | Console.Clear(); 28 | ColorConsole.WriteLine($"Sales overview ({DateTime.Now.ToString("HH:mm:ss")}):".Cyan()); 29 | ColorConsole.WriteLine("==========================".Cyan()); 30 | decimal totalSales = 0; 31 | foreach (var sale in _sales.OrderBy(s => s.ProductId)) 32 | { 33 | ColorConsole.WriteLine($"Product {sale.ProductId} : {sale.TotalAmount} units - {sale.TotalPrice} Euro.".Cyan()); 34 | totalSales += sale.TotalPrice; 35 | } 36 | ColorConsole.WriteLine($"Total: {totalSales} Euro".Cyan()); 37 | } 38 | 39 | private void UpdateState(SellProduct message) 40 | { 41 | var sale = _sales.FirstOrDefault(s => s.ProductId == message.ProductId); 42 | if (sale == null) 43 | { 44 | sale = new Sale(message.ProductId, message.Amount, message.TotalPrice); 45 | _sales.Add(sale); 46 | } 47 | else 48 | { 49 | sale.Increase(message.Amount, message.TotalPrice); 50 | } 51 | Self.Tell(new DumpSales()); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Remoting/Warehouse/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Persistence/Warehouse/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Start/DemoApp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Warehouse", "Warehouse\Warehouse.csproj", "{143D9ECD-377F-42F9-A1E6-18E19267D94A}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Messages", "Messages\Messages.csproj", "{8FB4E144-9233-4F30-A1A8-C77143F6410B}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Actors", "Actors\Actors.csproj", "{F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /Start/Actors/ProductActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using Messages; 4 | using Actors.Models; 5 | using System; 6 | 7 | namespace Actors 8 | { 9 | public class ProductActor : TypedActor, IHandle 10 | { 11 | private Product _product; 12 | private int _stock; 13 | ActorSelection _backorderActor; 14 | ActorSelection _salesActor; 15 | 16 | public ProductActor(Product product, int currentStock) 17 | { 18 | _product = product; 19 | _stock = currentStock; 20 | _backorderActor = Context.ActorSelection("/user/backorder"); 21 | _salesActor = Context.ActorSelection("/user/sales"); 22 | } 23 | 24 | public void Handle(PurchaseProduct message) 25 | { 26 | // determine backorder 27 | int backorderAmount = PurchaseProduct(message.Amount); 28 | 29 | // show status 30 | int purchased = message.Amount - backorderAmount; 31 | ColorConsole.WriteLine($"ProductActor for product {message.ProductId}: purchased {purchased} units.".Green()); 32 | 33 | // handle sales 34 | decimal totalPrice = CalculatePrice(purchased); 35 | _salesActor.Tell(new SellProduct(message.ProductId, purchased, totalPrice)); 36 | 37 | // handle backorder 38 | if (backorderAmount > 0) 39 | { 40 | _backorderActor.Tell(new BackorderProduct(message.ProductId, backorderAmount)); 41 | } 42 | 43 | // update scanner 44 | Sender.Tell(new ProductPurchased(message.ProductId, purchased, backorderAmount)); 45 | } 46 | 47 | private int PurchaseProduct(int amount) 48 | { 49 | int backorderAmount = 0; 50 | if (_stock < amount) 51 | { 52 | backorderAmount = amount - _stock; 53 | _stock = 0; 54 | } 55 | else 56 | { 57 | _stock -= amount; 58 | } 59 | return backorderAmount; 60 | } 61 | 62 | private decimal CalculatePrice(int amount) 63 | { 64 | return amount * _product.Price; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Persistence/Actors/ProductActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using Messages; 4 | using Actors.Models; 5 | using System; 6 | 7 | namespace Actors 8 | { 9 | public class ProductActor : TypedActor, IHandle 10 | { 11 | private Product _product; 12 | private int _stock; 13 | ActorSelection _backorderActor; 14 | ActorSelection _salesActor; 15 | 16 | public ProductActor(Product product, int currentStock) 17 | { 18 | _product = product; 19 | _stock = currentStock; 20 | _backorderActor = Context.ActorSelection("/user/backorder"); 21 | _salesActor = Context.ActorSelection("/user/sales"); 22 | } 23 | 24 | public void Handle(PurchaseProduct message) 25 | { 26 | // determine backorder 27 | int backorderAmount = PurchaseProduct(message.Amount); 28 | 29 | // show status 30 | int purchased = message.Amount - backorderAmount; 31 | ColorConsole.WriteLine($"ProductActor for product {message.ProductId}: purchased {purchased} units.".Green()); 32 | 33 | // handle sales 34 | decimal totalPrice = CalculatePrice(purchased); 35 | _salesActor.Tell(new SellProduct(message.ProductId, purchased, totalPrice)); 36 | 37 | // handle backorder 38 | if (backorderAmount > 0) 39 | { 40 | _backorderActor.Tell(new BackorderProduct(message.ProductId, backorderAmount)); 41 | } 42 | 43 | // update scanner 44 | Sender.Tell(new ProductPurchased(message.ProductId, purchased, backorderAmount)); 45 | } 46 | 47 | private int PurchaseProduct(int amount) 48 | { 49 | int backorderAmount = 0; 50 | if (_stock < amount) 51 | { 52 | backorderAmount = amount - _stock; 53 | _stock = 0; 54 | } 55 | else 56 | { 57 | _stock -= amount; 58 | } 59 | return backorderAmount; 60 | } 61 | 62 | private decimal CalculatePrice(int amount) 63 | { 64 | return amount * _product.Price; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Remoting/Actors/ProductActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using Messages; 4 | using Actors.Models; 5 | using System; 6 | 7 | namespace Actors 8 | { 9 | public class ProductActor : TypedActor, IHandle 10 | { 11 | private Product _product; 12 | private int _stock; 13 | ActorSelection _backorderActor; 14 | ActorSelection _salesActor; 15 | 16 | public ProductActor(Product product, int currentStock) 17 | { 18 | _product = product; 19 | _stock = currentStock; 20 | _backorderActor = Context.ActorSelection("/user/backorder"); 21 | _salesActor = Context.ActorSelection("/user/sales"); 22 | } 23 | 24 | public void Handle(PurchaseProduct message) 25 | { 26 | // determine backorder 27 | int backorderAmount = PurchaseProduct(message.Amount); 28 | 29 | // show status 30 | int purchased = message.Amount - backorderAmount; 31 | ColorConsole.WriteLine($"ProductActor for product {message.ProductId}: purchased {purchased} units.".Green()); 32 | 33 | // handle sales 34 | decimal totalPrice = CalculatePrice(purchased); 35 | _salesActor.Tell(new SellProduct(message.ProductId, purchased, totalPrice)); 36 | 37 | // handle backorder 38 | if (backorderAmount > 0) 39 | { 40 | _backorderActor.Tell(new BackorderProduct(message.ProductId, backorderAmount)); 41 | } 42 | 43 | // update scanner 44 | Sender.Tell(new ProductPurchased(message.ProductId, purchased, backorderAmount)); 45 | } 46 | 47 | private int PurchaseProduct(int amount) 48 | { 49 | int backorderAmount = 0; 50 | if (_stock < amount) 51 | { 52 | backorderAmount = amount - _stock; 53 | _stock = 0; 54 | } 55 | else 56 | { 57 | _stock -= amount; 58 | } 59 | return backorderAmount; 60 | } 61 | 62 | private decimal CalculatePrice(int amount) 63 | { 64 | return amount * _product.Price; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Start/Actors/CustomerActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System; 4 | using Messages; 5 | 6 | namespace Actors 7 | { 8 | public class CustomerActor : TypedActor 9 | { 10 | private int _storeId; 11 | private int _userId; 12 | private string _scannerId; 13 | private int _scannedItems = 0; // number of items scanned 14 | private int _minimalAmountRequired; // minimal amount of items required 15 | private IActorRef _scannerActor; 16 | private ActorSelection _storeActor; 17 | 18 | public CustomerActor(int storeId, int userId) 19 | { 20 | // setup state 21 | _storeId = storeId; 22 | _userId = userId; 23 | _scannerId = $"scanner{_storeId}-{_userId}"; 24 | _minimalAmountRequired = Randomizer.Next(25, 150); 25 | 26 | // define actors 27 | var props = Props.Create(new object[] { _scannerId }); 28 | _scannerActor = Context.ActorOf(props, _scannerId); 29 | _storeActor = Context.ActorSelection($"/user/store{_storeId}"); 30 | 31 | // activate scanner 32 | _storeActor.Tell(new ActivateScanner(_scannerId)); 33 | 34 | // start scanning immediately 35 | ScheduleNextScan(); 36 | } 37 | 38 | private void ScheduleNextScan() 39 | { 40 | // create a ScanItem message 41 | int amount = Randomizer.Next(1, 15); // random amount ... 42 | int productId = Randomizer.Next(1, 26); // ... of a random product 43 | ScanItem message = new ScanItem(productId, amount); 44 | 45 | // schedule message at a random interval 46 | int delayInMilliSeconds = Randomizer.Next(500, 1000); 47 | Context.System.Scheduler.ScheduleTellOnce( 48 | TimeSpan.FromMilliseconds(delayInMilliSeconds), Self, message, Self); 49 | } 50 | 51 | public void Handle(ScanItem message) 52 | { 53 | _scannerActor.Tell(message); 54 | 55 | // update stats 56 | _scannedItems += message.Amount; 57 | 58 | // determine progress 59 | if (_scannedItems < _minimalAmountRequired) 60 | { 61 | ScheduleNextScan(); 62 | } 63 | else 64 | { 65 | _storeActor.Tell(new ScanningCompleted(_userId)); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Remoting/Actors/CustomerActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System; 4 | using Messages; 5 | 6 | namespace Actors 7 | { 8 | public class CustomerActor : TypedActor 9 | { 10 | private int _storeId; 11 | private int _userId; 12 | private string _scannerId; 13 | private int _scannedItems = 0; // number of items scanned 14 | private int _minimalAmountRequired; // minimal amount of items required 15 | private IActorRef _scannerActor; 16 | private ActorSelection _storeActor; 17 | 18 | public CustomerActor(int storeId, int userId) 19 | { 20 | // setup state 21 | _storeId = storeId; 22 | _userId = userId; 23 | _scannerId = $"scanner{_storeId}-{_userId}"; 24 | _minimalAmountRequired = Randomizer.Next(25, 150); 25 | 26 | // define actors 27 | var props = Props.Create(new object[] { _scannerId }); 28 | _scannerActor = Context.ActorOf(props, _scannerId); 29 | _storeActor = Context.ActorSelection($"/user/store{_storeId}"); 30 | 31 | // activate scanner 32 | _storeActor.Tell(new ActivateScanner(_scannerId)); 33 | 34 | // start scanning immediately 35 | ScheduleNextScan(); 36 | } 37 | 38 | private void ScheduleNextScan() 39 | { 40 | // create a ScanItem message 41 | int amount = Randomizer.Next(1, 15); // random amount ... 42 | int productId = Randomizer.Next(1, 26); // ... of a random product 43 | ScanItem message = new ScanItem(productId, amount); 44 | 45 | // schedule message at a random interval 46 | int delayInMilliSeconds = Randomizer.Next(500, 1000); 47 | Context.System.Scheduler.ScheduleTellOnce( 48 | TimeSpan.FromMilliseconds(delayInMilliSeconds), Self, message, Self); 49 | } 50 | 51 | public void Handle(ScanItem message) 52 | { 53 | _scannerActor.Tell(message); 54 | 55 | // update stats 56 | _scannedItems += message.Amount; 57 | 58 | // determine progress 59 | if (_scannedItems < _minimalAmountRequired) 60 | { 61 | ScheduleNextScan(); 62 | } 63 | else 64 | { 65 | _storeActor.Tell(new ScanningCompleted(_userId)); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Persistence/Actors/CustomerActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System; 4 | using Messages; 5 | 6 | namespace Actors 7 | { 8 | public class CustomerActor : TypedActor 9 | { 10 | private int _storeId; 11 | private int _userId; 12 | private string _scannerId; 13 | private int _scannedItems = 0; // number of items scanned 14 | private int _minimalAmountRequired; // minimal amount of items required 15 | private IActorRef _scannerActor; 16 | private ActorSelection _storeActor; 17 | 18 | public CustomerActor(int storeId, int userId) 19 | { 20 | // setup state 21 | _storeId = storeId; 22 | _userId = userId; 23 | _scannerId = $"scanner{_storeId}-{_userId}"; 24 | _minimalAmountRequired = Randomizer.Next(25, 150); 25 | 26 | // define actors 27 | var props = Props.Create(new object[] { _scannerId }); 28 | _scannerActor = Context.ActorOf(props, _scannerId); 29 | _storeActor = Context.ActorSelection($"/user/store{_storeId}"); 30 | 31 | // activate scanner 32 | _storeActor.Tell(new ActivateScanner(_scannerId)); 33 | 34 | // start scanning immediately 35 | ScheduleNextScan(); 36 | } 37 | 38 | private void ScheduleNextScan() 39 | { 40 | // create a ScanItem message 41 | int amount = Randomizer.Next(1, 15); // random amount ... 42 | int productId = Randomizer.Next(1, 26); // ... of a random product 43 | ScanItem message = new ScanItem(productId, amount); 44 | 45 | // schedule message at a random interval 46 | int delayInMilliSeconds = Randomizer.Next(500, 1000); 47 | Context.System.Scheduler.ScheduleTellOnce( 48 | TimeSpan.FromMilliseconds(delayInMilliSeconds), Self, message, Self); 49 | } 50 | 51 | public void Handle(ScanItem message) 52 | { 53 | _scannerActor.Tell(message); 54 | 55 | // update stats 56 | _scannedItems += message.Amount; 57 | 58 | // determine progress 59 | if (_scannedItems < _minimalAmountRequired) 60 | { 61 | ScheduleNextScan(); 62 | } 63 | else 64 | { 65 | _storeActor.Tell(new ScanningCompleted(_userId)); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Remoting/DemoApp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Warehouse", "Warehouse\Warehouse.csproj", "{143D9ECD-377F-42F9-A1E6-18E19267D94A}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Messages", "Messages\Messages.csproj", "{8FB4E144-9233-4F30-A1A8-C77143F6410B}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Actors", "Actors\Actors.csproj", "{F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sales", "Sales\Sales.csproj", "{C03236E9-D67B-40A3-973D-7F1B8700D44A}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {C03236E9-D67B-40A3-973D-7F1B8700D44A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {C03236E9-D67B-40A3-973D-7F1B8700D44A}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {C03236E9-D67B-40A3-973D-7F1B8700D44A}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {C03236E9-D67B-40A3-973D-7F1B8700D44A}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Remoting/.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Start/.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Persistence/.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Persistence/DemoApp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Warehouse", "Warehouse\Warehouse.csproj", "{143D9ECD-377F-42F9-A1E6-18E19267D94A}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Messages", "Messages\Messages.csproj", "{8FB4E144-9233-4F30-A1A8-C77143F6410B}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Actors", "Actors\Actors.csproj", "{F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sales", "Sales\Sales.csproj", "{C03236E9-D67B-40A3-973D-7F1B8700D44A}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1D8CF699-66B0-42AA-9AF0-B6FD8CDCBDCF}" 15 | ProjectSection(SolutionItems) = preProject 16 | preparepersistence.ps1 = preparepersistence.ps1 17 | EndProjectSection 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Any CPU = Debug|Any CPU 22 | Release|Any CPU = Release|Any CPU 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {143D9ECD-377F-42F9-A1E6-18E19267D94A}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {8FB4E144-9233-4F30-A1A8-C77143F6410B}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {C03236E9-D67B-40A3-973D-7F1B8700D44A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {C03236E9-D67B-40A3-973D-7F1B8700D44A}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {C03236E9-D67B-40A3-973D-7F1B8700D44A}.Release|Any CPU.ActiveCfg = Release|Any CPU 40 | {C03236E9-D67B-40A3-973D-7F1B8700D44A}.Release|Any CPU.Build.0 = Release|Any CPU 41 | EndGlobalSection 42 | GlobalSection(SolutionProperties) = preSolution 43 | HideSolutionNode = FALSE 44 | EndGlobalSection 45 | EndGlobal 46 | -------------------------------------------------------------------------------- /Persistence/Actors/SalesActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using ColoredConsole; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Messages; 6 | using Actors.Models; 7 | using System; 8 | using Akka.Persistence; 9 | using Actors.Events; 10 | using Newtonsoft.Json.Linq; 11 | 12 | namespace Actors 13 | { 14 | public class SalesActor : ReceivePersistentActor 15 | { 16 | private List _sales; 17 | 18 | public override string PersistenceId { get; } = "PersistentSalesActor"; 19 | 20 | public SalesActor() 21 | { 22 | _sales = new List(); 23 | Self.Tell(new DumpSales()); 24 | 25 | Command(cmd => { 26 | ProductSold productSoldEvent = 27 | new ProductSold(cmd.ProductId, cmd.Amount, cmd.TotalPrice); 28 | Persist(productSoldEvent, Handle); 29 | return true; 30 | }); 31 | 32 | Command(cmd => Handle(cmd)); 33 | 34 | Recover(evt => { 35 | ProductSold productSold = evt.ToObject(); 36 | if (productSold != null) 37 | { 38 | Handle(productSold); 39 | } 40 | }); 41 | } 42 | 43 | private void Handle(ProductSold @event) 44 | { 45 | UpdateSales(@event); 46 | 47 | // show sales (only when not recovering from eventstore) 48 | if (!IsRecovering) 49 | { 50 | Self.Tell(new DumpSales()); 51 | } 52 | } 53 | 54 | private void Handle(DumpSales command) 55 | { 56 | Console.Clear(); 57 | ColorConsole.WriteLine($"Sales overview ({DateTime.Now.ToString("HH:mm:ss")}):".Cyan()); 58 | ColorConsole.WriteLine("==========================".Cyan()); 59 | decimal totalSales = 0; 60 | foreach (var sale in _sales.OrderBy(s => s.ProductId)) 61 | { 62 | ColorConsole.WriteLine($"Product {sale.ProductId} : {sale.TotalAmount} units - {sale.TotalPrice} Euro.".Cyan()); 63 | totalSales += sale.TotalPrice; 64 | } 65 | ColorConsole.WriteLine($"Total: {totalSales} Euro".Cyan()); 66 | } 67 | 68 | private void UpdateSales(ProductSold @event) 69 | { 70 | var sale = _sales.FirstOrDefault(s => s.ProductId == @event.ProductId); 71 | if (sale == null) 72 | { 73 | sale = new Sale(@event.ProductId, @event.Amount, @event.TotalPrice); 74 | _sales.Add(sale); 75 | } 76 | else 77 | { 78 | sale.Increase(@event.Amount, @event.TotalPrice); 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Remoting/Messages/Messages.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8FB4E144-9233-4F30-A1A8-C77143F6410B} 8 | Library 9 | Properties 10 | Messages 11 | Messages 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /Start/Messages/Messages.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8FB4E144-9233-4F30-A1A8-C77143F6410B} 8 | Library 9 | Properties 10 | Messages 11 | Messages 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /Persistence/Messages/Messages.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8FB4E144-9233-4F30-A1A8-C77143F6410B} 8 | Library 9 | Properties 10 | Messages 11 | Messages 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /Persistence/Sales/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /Start/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /Remoting/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /Persistence/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /Remoting/Actors/Actors.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B} 8 | Library 9 | Properties 10 | Actors 11 | Actors 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Akka.1.1.3\lib\net45\Akka.dll 35 | True 36 | 37 | 38 | ..\packages\ColoredConsole.0.5.0\lib\net45\ColoredConsole.dll 39 | True 40 | 41 | 42 | ..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll 43 | True 44 | 45 | 46 | 47 | ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll 48 | True 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | {8fb4e144-9233-4f30-a1a8-c77143f6410b} 77 | Messages 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 92 | -------------------------------------------------------------------------------- /Start/Actors/Actors.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B} 8 | Library 9 | Properties 10 | Actors 11 | Actors 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Akka.1.1.3\lib\net45\Akka.dll 35 | True 36 | 37 | 38 | ..\packages\ColoredConsole.0.5.0\lib\net45\ColoredConsole.dll 39 | True 40 | 41 | 42 | ..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll 43 | True 44 | 45 | 46 | 47 | ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll 48 | True 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | {8fb4e144-9233-4f30-a1a8-c77143f6410b} 77 | Messages 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 92 | -------------------------------------------------------------------------------- /Remoting/Sales/CHANGES.txt: -------------------------------------------------------------------------------- 1 | =============================================================================== 2 | Welcome to the C# port of Google Protocol Buffers, written by Jon Skeet 3 | (skeet@pobox.com) based on the work of many talented people. 4 | 5 | For more information about this port, visit its homepage: 6 | http://protobuf-csharp-port.googlecode.com 7 | 8 | For more information about Protocol Buffers in general, visit the project page 9 | for the C++, Java and Python project: 10 | http://protobuf.googlecode.com 11 | =============================================================================== 12 | RELEASE NOTES - Version 2.4.1.473 13 | =============================================================================== 14 | 15 | Features: 16 | - Added option service_generator_type to control service generation with 17 | NONE, GENERIC, INTERFACE, or IRPCDISPATCH 18 | - Added interfaces IRpcDispatch and IRpcServerStub to provide for blocking 19 | services and implementations. 20 | - Added ProtoGen.exe command-line argument "--protoc_dir=" to specify the 21 | location of protoc.exe. 22 | - Extracted interfaces for ICodedInputStream and ICodedOutputStream to allow 23 | custom implementation of writers with both speed and size optimizations. 24 | - Addition of the "Google.ProtoBuffers.Serialization" assembly to support 25 | reading and writing messages to/from XML, JSON, IDictionary<,> and others. 26 | - Several performance related fixes and tweeks 27 | - Issue 3: Add option to mark generated code with attribute 28 | - Issue 20: Support for decorating classes [Serializable] 29 | - Issue 21: Decorate fields with [deprecated=true] as [System.Obsolete] 30 | - Issue 22: Reusable Builder classes 31 | - Issue 24: Support for using Json/Xml formats with ICodedInputStream 32 | - Issue 25: Added support for NuGet packages 33 | - Issue 31: Upgraded protoc.exe and descriptor to 2.4.1 34 | 35 | Fixes: 36 | - Issue 13: Message with Field same name as message causes uncompilable .cs 37 | - Issue 16: Does not integrate well with other tooling 38 | - Issue 19: Support for negative enum values 39 | - Issue 26: AddRange in GeneratedBuilder iterates twice. 40 | - Issue 27: Remove XML documentation output from test projects to clear 41 | warnings/errors. 42 | - Issue 28: Circular message dependencies result in null default values for 43 | Message fields. 44 | - Issue 29: Message classes generated have a public default constructor. You 45 | can disable private ctor generation with the option generate_private_ctor. 46 | - Issue 35: Fixed a bug in ProtoGen handling of arguments with trailing \ 47 | - Big-endian support for float, and double on Silverlight 48 | - Packed and Unpacked parsing allow for all repeated, as per version 2.3 49 | - Fix for leaving Builder a public ctor on internal classes for use with 50 | generic "where T: new()" constraints. 51 | 52 | Other: 53 | - Changed the code signing key to a privately held key 54 | - Reformatted all code and line-endings to C# defaults 55 | - Reworking of performance benchmarks to produce reliable results, option /v2 56 | - Issue 34: Silverlight assemblies are now unit tested 57 | 58 | =============================================================================== 59 | RELEASE NOTES - Version 2.3.0.277 60 | =============================================================================== 61 | 62 | Features: 63 | - Added cls_compliance option to generate attributes indicating 64 | non-CLS-compliance. 65 | - Added file_extension option to control the generated output file's extension. 66 | - Added umbrella_namespace option to place the umbrella class into a nested 67 | namespace to address issues with proto files having the same name as a 68 | message it contains. 69 | - Added output_directory option to set the output path for the source file(s). 70 | - Added ignore_google_protobuf option to avoid generating code for includes 71 | from the google.protobuf package. 72 | - Added the LITE framework (Google.ProtoBuffersLite.dll) and the ability to 73 | generate code with "option optimize_for = LITE_RUNTIME;". 74 | - Added ability to invoke protoc.exe from within ProtoGen.exe. 75 | - Upgraded to protoc.exe (2.3) compiler. 76 | 77 | Fixes: 78 | - Issue 9: Class cannot be static and sealed error 79 | - Issue 12: default value for enumerate fields must be filled out 80 | 81 | Other: 82 | - Rewrite of build using MSBbuild instead of NAnt 83 | - Moved to NUnit Version 2.2.8.0 84 | - Changed to using secure .snk for releases 85 | 86 | =============================================================================== 87 | RELEASE NOTES - Version 0.9.1 88 | =============================================================================== 89 | 90 | Fixes: 91 | - issue 10: Incorrect encoding of packed fields when serialized 92 | 93 | =============================================================================== 94 | RELEASE NOTES - Version 0.9.0 95 | =============================================================================== 96 | 97 | - Initial release 98 | 99 | =============================================================================== -------------------------------------------------------------------------------- /Persistence/Sales/CHANGES.txt: -------------------------------------------------------------------------------- 1 | =============================================================================== 2 | Welcome to the C# port of Google Protocol Buffers, written by Jon Skeet 3 | (skeet@pobox.com) based on the work of many talented people. 4 | 5 | For more information about this port, visit its homepage: 6 | http://protobuf-csharp-port.googlecode.com 7 | 8 | For more information about Protocol Buffers in general, visit the project page 9 | for the C++, Java and Python project: 10 | http://protobuf.googlecode.com 11 | =============================================================================== 12 | RELEASE NOTES - Version 2.4.1.473 13 | =============================================================================== 14 | 15 | Features: 16 | - Added option service_generator_type to control service generation with 17 | NONE, GENERIC, INTERFACE, or IRPCDISPATCH 18 | - Added interfaces IRpcDispatch and IRpcServerStub to provide for blocking 19 | services and implementations. 20 | - Added ProtoGen.exe command-line argument "--protoc_dir=" to specify the 21 | location of protoc.exe. 22 | - Extracted interfaces for ICodedInputStream and ICodedOutputStream to allow 23 | custom implementation of writers with both speed and size optimizations. 24 | - Addition of the "Google.ProtoBuffers.Serialization" assembly to support 25 | reading and writing messages to/from XML, JSON, IDictionary<,> and others. 26 | - Several performance related fixes and tweeks 27 | - Issue 3: Add option to mark generated code with attribute 28 | - Issue 20: Support for decorating classes [Serializable] 29 | - Issue 21: Decorate fields with [deprecated=true] as [System.Obsolete] 30 | - Issue 22: Reusable Builder classes 31 | - Issue 24: Support for using Json/Xml formats with ICodedInputStream 32 | - Issue 25: Added support for NuGet packages 33 | - Issue 31: Upgraded protoc.exe and descriptor to 2.4.1 34 | 35 | Fixes: 36 | - Issue 13: Message with Field same name as message causes uncompilable .cs 37 | - Issue 16: Does not integrate well with other tooling 38 | - Issue 19: Support for negative enum values 39 | - Issue 26: AddRange in GeneratedBuilder iterates twice. 40 | - Issue 27: Remove XML documentation output from test projects to clear 41 | warnings/errors. 42 | - Issue 28: Circular message dependencies result in null default values for 43 | Message fields. 44 | - Issue 29: Message classes generated have a public default constructor. You 45 | can disable private ctor generation with the option generate_private_ctor. 46 | - Issue 35: Fixed a bug in ProtoGen handling of arguments with trailing \ 47 | - Big-endian support for float, and double on Silverlight 48 | - Packed and Unpacked parsing allow for all repeated, as per version 2.3 49 | - Fix for leaving Builder a public ctor on internal classes for use with 50 | generic "where T: new()" constraints. 51 | 52 | Other: 53 | - Changed the code signing key to a privately held key 54 | - Reformatted all code and line-endings to C# defaults 55 | - Reworking of performance benchmarks to produce reliable results, option /v2 56 | - Issue 34: Silverlight assemblies are now unit tested 57 | 58 | =============================================================================== 59 | RELEASE NOTES - Version 2.3.0.277 60 | =============================================================================== 61 | 62 | Features: 63 | - Added cls_compliance option to generate attributes indicating 64 | non-CLS-compliance. 65 | - Added file_extension option to control the generated output file's extension. 66 | - Added umbrella_namespace option to place the umbrella class into a nested 67 | namespace to address issues with proto files having the same name as a 68 | message it contains. 69 | - Added output_directory option to set the output path for the source file(s). 70 | - Added ignore_google_protobuf option to avoid generating code for includes 71 | from the google.protobuf package. 72 | - Added the LITE framework (Google.ProtoBuffersLite.dll) and the ability to 73 | generate code with "option optimize_for = LITE_RUNTIME;". 74 | - Added ability to invoke protoc.exe from within ProtoGen.exe. 75 | - Upgraded to protoc.exe (2.3) compiler. 76 | 77 | Fixes: 78 | - Issue 9: Class cannot be static and sealed error 79 | - Issue 12: default value for enumerate fields must be filled out 80 | 81 | Other: 82 | - Rewrite of build using MSBbuild instead of NAnt 83 | - Moved to NUnit Version 2.2.8.0 84 | - Changed to using secure .snk for releases 85 | 86 | =============================================================================== 87 | RELEASE NOTES - Version 0.9.1 88 | =============================================================================== 89 | 90 | Fixes: 91 | - issue 10: Incorrect encoding of packed fields when serialized 92 | 93 | =============================================================================== 94 | RELEASE NOTES - Version 0.9.0 95 | =============================================================================== 96 | 97 | - Initial release 98 | 99 | =============================================================================== -------------------------------------------------------------------------------- /Persistence/Actors/Actors.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F4AFF44D-9F2B-4E10-B954-12E16F9F3E9B} 8 | Library 9 | Properties 10 | Actors 11 | Actors 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Akka.1.1.3\lib\net45\Akka.dll 35 | True 36 | 37 | 38 | ..\packages\Akka.Persistence.1.1.3.32-beta\lib\net45\Akka.Persistence.dll 39 | True 40 | 41 | 42 | ..\packages\ColoredConsole.0.5.0\lib\net45\ColoredConsole.dll 43 | True 44 | 45 | 46 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll 47 | True 48 | 49 | 50 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll 51 | True 52 | 53 | 54 | ..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll 55 | True 56 | 57 | 58 | 59 | ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll 60 | True 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | {8fb4e144-9233-4f30-a1a8-c77143f6410b} 90 | Messages 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /Remoting/Sales/Sales.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C03236E9-D67B-40A3-973D-7F1B8700D44A} 8 | Exe 9 | Properties 10 | Sales 11 | Sales 12 | v4.6 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\Akka.1.1.3\lib\net45\Akka.dll 38 | True 39 | 40 | 41 | ..\packages\Akka.Remote.1.1.3\lib\net45\Akka.Remote.dll 42 | True 43 | 44 | 45 | ..\packages\Akka.Serialization.Hyperion.1.1.3.32-beta\lib\net45\Akka.Serialization.Hyperion.dll 46 | True 47 | 48 | 49 | ..\packages\ColoredConsole.0.5.0\lib\net45\ColoredConsole.dll 50 | True 51 | 52 | 53 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll 54 | True 55 | 56 | 57 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll 58 | True 59 | 60 | 61 | ..\packages\Helios.2.1.2\lib\net45\Helios.dll 62 | True 63 | 64 | 65 | ..\packages\Hyperion.0.9.2\lib\net45\Hyperion.dll 66 | True 67 | 68 | 69 | ..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll 70 | True 71 | 72 | 73 | 74 | ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll 75 | True 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | {f4aff44d-9f2b-4e10-b954-12e16f9f3e9b} 96 | Actors 97 | 98 | 99 | {8fb4e144-9233-4f30-a1a8-c77143f6410b} 100 | Messages 101 | 102 | 103 | 104 | 111 | -------------------------------------------------------------------------------- /Start/Warehouse/Warehouse.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {143D9ECD-377F-42F9-A1E6-18E19267D94A} 8 | Exe 9 | Properties 10 | Warehouse 11 | Warehouse 12 | v4.6 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\Akka.1.1.3\lib\net45\Akka.dll 38 | True 39 | 40 | 41 | ..\packages\Akka.Remote.1.1.3\lib\net45\Akka.Remote.dll 42 | True 43 | 44 | 45 | ..\packages\Akka.Serialization.Hyperion.1.1.3.32-beta\lib\net45\Akka.Serialization.Hyperion.dll 46 | True 47 | 48 | 49 | ..\packages\ColoredConsole.0.5.0\lib\net45\ColoredConsole.dll 50 | True 51 | 52 | 53 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll 54 | True 55 | 56 | 57 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll 58 | True 59 | 60 | 61 | ..\packages\Helios.2.1.2\lib\net45\Helios.dll 62 | True 63 | 64 | 65 | ..\packages\Hyperion.0.9.2\lib\net45\Hyperion.dll 66 | True 67 | 68 | 69 | ..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll 70 | True 71 | 72 | 73 | 74 | ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll 75 | True 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | {f4aff44d-9f2b-4e10-b954-12e16f9f3e9b} 96 | Actors 97 | 98 | 99 | {8fb4e144-9233-4f30-a1a8-c77143f6410b} 100 | Messages 101 | 102 | 103 | 104 | 111 | -------------------------------------------------------------------------------- /Remoting/Warehouse/Warehouse.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {143D9ECD-377F-42F9-A1E6-18E19267D94A} 8 | Exe 9 | Properties 10 | Warehouse 11 | Warehouse 12 | v4.6 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\Akka.1.1.3\lib\net45\Akka.dll 38 | True 39 | 40 | 41 | ..\packages\Akka.Remote.1.1.3\lib\net45\Akka.Remote.dll 42 | True 43 | 44 | 45 | ..\packages\Akka.Serialization.Hyperion.1.1.3.32-beta\lib\net45\Akka.Serialization.Hyperion.dll 46 | True 47 | 48 | 49 | ..\packages\ColoredConsole.0.5.0\lib\net45\ColoredConsole.dll 50 | True 51 | 52 | 53 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll 54 | True 55 | 56 | 57 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll 58 | True 59 | 60 | 61 | ..\packages\Helios.2.1.2\lib\net45\Helios.dll 62 | True 63 | 64 | 65 | ..\packages\Hyperion.0.9.2\lib\net45\Hyperion.dll 66 | True 67 | 68 | 69 | ..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll 70 | True 71 | 72 | 73 | 74 | ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll 75 | True 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | {f4aff44d-9f2b-4e10-b954-12e16f9f3e9b} 96 | Actors 97 | 98 | 99 | {8fb4e144-9233-4f30-a1a8-c77143f6410b} 100 | Messages 101 | 102 | 103 | 104 | 111 | -------------------------------------------------------------------------------- /Persistence/Warehouse/Warehouse.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {143D9ECD-377F-42F9-A1E6-18E19267D94A} 8 | Exe 9 | Properties 10 | Warehouse 11 | Warehouse 12 | v4.6 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\Akka.1.1.3\lib\net45\Akka.dll 38 | True 39 | 40 | 41 | ..\packages\Akka.Persistence.1.1.3.32-beta\lib\net45\Akka.Persistence.dll 42 | True 43 | 44 | 45 | ..\packages\Akka.Remote.1.1.3\lib\net45\Akka.Remote.dll 46 | True 47 | 48 | 49 | ..\packages\Akka.Serialization.Hyperion.1.1.3.32-beta\lib\net45\Akka.Serialization.Hyperion.dll 50 | True 51 | 52 | 53 | ..\packages\ColoredConsole.0.5.0\lib\net45\ColoredConsole.dll 54 | True 55 | 56 | 57 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll 58 | True 59 | 60 | 61 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll 62 | True 63 | 64 | 65 | ..\packages\Helios.2.1.2\lib\net45\Helios.dll 66 | True 67 | 68 | 69 | ..\packages\Hyperion.0.9.2\lib\net45\Hyperion.dll 70 | True 71 | 72 | 73 | ..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll 74 | True 75 | 76 | 77 | 78 | ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll 79 | True 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | {f4aff44d-9f2b-4e10-b954-12e16f9f3e9b} 100 | Actors 101 | 102 | 103 | {8fb4e144-9233-4f30-a1a8-c77143f6410b} 104 | Messages 105 | 106 | 107 | 108 | 115 | -------------------------------------------------------------------------------- /Persistence/Sales/Sales.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C03236E9-D67B-40A3-973D-7F1B8700D44A} 8 | Exe 9 | Properties 10 | Sales 11 | Sales 12 | v4.6 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\Akka.1.1.3\lib\net45\Akka.dll 38 | True 39 | 40 | 41 | ..\packages\Akka.Persistence.1.1.2.30-beta\lib\net45\Akka.Persistence.dll 42 | True 43 | 44 | 45 | ..\packages\Akka.Persistence.AzureTable.0.2.0-beta\lib\net45\Akka.Persistence.AzureTable.dll 46 | True 47 | 48 | 49 | ..\packages\Akka.Remote.1.1.3\lib\net45\Akka.Remote.dll 50 | True 51 | 52 | 53 | ..\packages\Akka.Serialization.Hyperion.1.1.3.32-beta\lib\net45\Akka.Serialization.Hyperion.dll 54 | True 55 | 56 | 57 | ..\packages\ColoredConsole.0.5.0\lib\net45\ColoredConsole.dll 58 | True 59 | 60 | 61 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll 62 | True 63 | 64 | 65 | ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll 66 | True 67 | 68 | 69 | ..\packages\Helios.2.1.2\lib\net45\Helios.dll 70 | True 71 | 72 | 73 | ..\packages\Hyperion.0.9.2\lib\net45\Hyperion.dll 74 | True 75 | 76 | 77 | ..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll 78 | True 79 | 80 | 81 | ..\packages\Microsoft.Data.Edm.5.7.0\lib\net40\Microsoft.Data.Edm.dll 82 | True 83 | 84 | 85 | ..\packages\Microsoft.Data.OData.5.7.0\lib\net40\Microsoft.Data.OData.dll 86 | True 87 | 88 | 89 | ..\packages\Microsoft.Data.Services.Client.5.7.0\lib\net40\Microsoft.Data.Services.Client.dll 90 | True 91 | 92 | 93 | ..\packages\WindowsAzure.Storage.7.2.1\lib\net40\Microsoft.WindowsAzure.Storage.dll 94 | True 95 | 96 | 97 | ..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll 98 | True 99 | 100 | 101 | 102 | ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll 103 | True 104 | 105 | 106 | 107 | ..\packages\System.Spatial.5.7.0\lib\net40\System.Spatial.dll 108 | True 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | {f4aff44d-9f2b-4e10-b954-12e16f9f3e9b} 128 | Actors 129 | 130 | 131 | {8fb4e144-9233-4f30-a1a8-c77143f6410b} 132 | Messages 133 | 134 | 135 | 136 | 143 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Akka.NET - Warehouse Sample 2 | This is a sample application demonstrating some aspects of Akka.NET. I use this application for demos during talks I give on Building Actor Model systems using Akka.NET ([download the slides](Building%20Actor%20Model%20systems%20using%20Akka-NET%20-%20Edwin%20van%20Wijk.pdf)). 3 | 4 | This repo contains 3 folders: 5 | 6 | | Folder | Description | 7 | |:------------|:--------------------------------------------------------------------------------------------------------| 8 | | Start | The base demo with all actors running in 1 single process. | 9 | | Remoting | The demo with the sales actor running in a remote process (demonstrating *Akka.Remoting*). | 10 | | Persistence | The demo with the sales actor persisting state in Azure Table storage (demonstrating *Akka.Persistence*). | 11 | 12 | ## Demo description 13 | This application simulates a central warehouse system with multiple stores that allow customers to scan products in order to purchase them. The system consists of the following parts: 14 | 15 | * **Inventory** - keeps track of the amount of products in stock. 16 | * **Sales** - keeps track of how many money the company has made on sales. 17 | * **Back-order** - keeps track of products which need to be back-ordered (because of insufficient stock). 18 | * **Store** - keeps tracks of scanners being used by customers in the store. 19 | * **Scanners** - represent bar-code scanners used by customers to purchase products (by scanning them and entering an amount). 20 | 21 | ## Actor Hierarchy 22 | The following Actor hierarchy is used in the system: 23 | 24 | ![Actor Hierarchy](actor-hierarchy.png) 25 | 26 | For every store a *Store* actor is created. The store actor creates a *Customer* actor per customer. Every customer actor creates a *Scanner* actor to represent a bar-code scanner. In this demo, customers with a scanner are simulated by letting the customer actor repeatedly send a scheduled message to *Self* at random intervals. 27 | 28 | The *Sales* actor accumulates all sales. Only products actually sold are added - back-ordered products will not show up in the sales report. 29 | 30 | The *BackOrder* actor tracks the list of products that must be back-ordered because of insufficient stock. 31 | 32 | ### Handling concurrency on inventory 33 | Because multiple customers could order the same product at the same time, I needed to serialize access to the products' stock-amount. I solved this problem by letting the *Inventory* actor create a *Product* actor per available product in the inventory. Every product actor has as its state the amount of products in stock. 34 | 35 | ### Refactoring 36 | In my initial design, I tried to solve the concurrency problem by letting a single inventory actor handle this. While this solution worked, it introduced a performance bottle-neck at the inventory Actor. Its mailbox filled up quite rapidly which decreased the performance of the system. 37 | 38 | This demonstrates that it's important that you experiment with several solutions for your problem or partition your problem in a different way in order to solve it efficiently using an Actor Model approach. My advice would be to always start drawing out the actor hierarchy on a whiteboard (or do some [Event Storming](http://eventstorming.com/)) to validate your design before implementing it. 39 | 40 | ## Start Solution 41 | The *Start* solution contains the initial version of the demo application. All actors run in a single process. This process is the *Warehouse* console application. When this project is started, the application initializes and waits for a keypress before starting the simulation. 42 | 43 | ### Simulating concurrency 44 | By default, only 1 store with 1 customer is simulated. You can increase this by setting the following variables: 45 | 46 | * *numberOfStores* in *Program.cs* in the *Warehouse* project. 47 | * *_numberOfCustomers* in *StoreActor.cs* in the *Actors* project. 48 | 49 | ### Simulation output 50 | Throughout the simulation, information about what's going on is printed to the console. I've used different colors to identify which actor prints the message: 51 | 52 | | Color | Emitted by | 53 | |:----------|:------------------| 54 | | White | Store actor | 55 | | Yellow | Scanner actor | 56 | | Green | Product actor | 57 | | Cyan | Sales actor | 58 | | Red | BackOrder actor | 59 | 60 | ### Getting started 61 | Make sure you browse the code of the start solution first to see how I've used Akka.NET to build this system. Make sure you're familiar with the structure of this solution before looking at the other sample solutions in this repo. 62 | 63 | ## Remoting solution 64 | The *Remoting* solution demonstrates location transparency using *Akka.Remote* (see the [documentation](http://getakka.net/docs/remoting)). It contains an additional project *Sales* which is a console application. In this solution, the *Sales* actor will be created in the process of this second console application. Make sure you set both the *Warehouse* project and the *Sales* project as start-up projects. 65 | 66 | ### Configuration 67 | The code in this solution is almost identical to the code in the *Start* solution. The magic is primarily in the *App.config* of the console applications. 68 | 69 | In the *Warehouse* project, remoting is configured: 70 | 71 | ```JSON  72 | actor {  73 | provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote"     74 | 75 | deployment {   76 | /sales {  remote = "akka.tcp://sales@localhost:9999" }               77 | }   78 | } 79 | 80 | remote {  81 | helios.tcp {   82 | port = 0 # bound to a dynamic port assigned by the OS   83 | hostname = localhost  84 | }  85 | } 86 | ``` 87 | Notice that the actor named */sales* will be created at address: *akka.tcp://sales@localhost:9999*. 88 | 89 | The app.config of the *Sales* project also contains remoting configuration: 90 | 91 | ```JSON  92 | actor {  93 | provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote"  94 | }   95 | 96 | remote {  97 | helios.tcp {   98 | port = 9999   99 | hostname = localhost  100 | }  101 | } 102 | ``` 103 | Notice that this process will be configured to listen for remoting messages on port *9999*. 104 | 105 | The *Sales* actor is changed slightly in this solution to make sure it dumps its sales report to the console after every sale. 106 | 107 | ## Persistence solution 108 | The *Persistence* solution demonstrates Actor state persistence using *Akka.Persistence* (see the [documentation](http://getakka.net/docs/persistence/architecture)) to enable an actor to store its state and survive restarts. By default, *event-sourcing* is used to store the state of the actor. This means that updating the state will always be done by handling events. 109 | 110 | ### Peristent Sales actor 111 | For this demo I've chosen to make the *Sales* actor persistent. I could've also chosen the *Product* actor - which would made more sense in real-life. But because the *Sales* actor was already living in a seperate process, I selected that one. 112 | 113 | ### Storage provider 114 | Akka.Persistence comes with several pluggable storage-providers. For this sample, I've chosen the *Azure Table Storage* provider. This means that you need to have the Azure Storage SDK with the local Storage Emulator installed on your machine in order to run this demo. Another option would be to configure a different storage provider (as described [here](http://getakka.net/docs/persistence/storage-plugins)).   115 | 116 | ### Configuration 117 | The structure for this solution is basically the same as the *Remoting* solution with the following changes: 118 | 119 | * In the *app.config* of the *Sales* project Akka.Persistence is configured. 120 | * The *Sales* actor derives from *ReceivePersistentActor* to make it persistent. 121 | 122 | ### Setting up the persistent actor 123 | In the constructor of the *Sales* actor you can see how I've used the *Command* method from the base-class to specify how the actor handles incoming commands by: 124 | 125 | 1. creating an event based on the command, 126 | 2. persist this event and 127 | 3. update the state of the actor and handle the event using the *Persist* method from the base-class. 128 | 129 | Also the constructor shows how the actor handles recovering from restarts using the *Recover* method from the base-class. In this sample I've used a generic JObject to deserialize the events from storage. 130 | 131 | Notice how I use the convenient *IsRecovering* property from the base-class to determine whether I'm handling a new event as a result of command that came in (*false*) or I'm replaying a historical event (*true*). 132 | 133 | ### Initializing Azure Table Storage 134 | In the solution I've included a Powershell script *preparepersistence.ps1*. This script does 2 things: 135 | 136 | 1. Start the local Azure Storage Emulator. 137 | 2. Delete **any** existing tables in development storage. 138 | 139 | You can use this script to initialize the environment before running the sample. 140 | 141 | ## Disclaimer 142 | This is sample code and should be treated as such. I've demonstrated only a small portion of the Akka.NET framework and possibilities. Also I've cut a lot of corners which I wouldn't ever do in production code. 143 | 144 | ## Resources 145 | Check out the [Akka.NET documentation](http://getakka.net) to get started with Akka.Net. 146 | 147 | If you have some time, I would also advice you to do the [Akka.NET Bootcamp](http://learnakka.net/). 148 | --------------------------------------------------------------------------------