Explorar o código

update to orlean2 new api

JasonWang %!s(int64=6) %!d(string=hai) anos
pai
achega
2e823860bc

+ 3 - 3
src/MineCase.Gateway/AppBootstrapper.cs

@@ -38,10 +38,10 @@ namespace MineCase.Gateway
 
         private static IConfiguration LoadConfiguration()
         {
-            var builder = new ConfigurationBuilder()
+            var configurationBuilder = new ConfigurationBuilder()
                 .SetBasePath(Directory.GetCurrentDirectory())
-                .AddJsonFile("config.json", true, false);
-            return builder.Build();
+                .AddJsonFile("config.json", false, false);
+            return configurationBuilder.Build();
         }
 
         private static void ConfigureLogging(ILoggingBuilder loggingBuilder)

+ 5 - 0
src/MineCase.Gateway/MineCase.Gateway.csproj

@@ -11,11 +11,15 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <None Remove="config.json" />
     <None Remove="OrleansConfiguration.dev.xml" />
     <None Remove="OrleansConfiguration.docker.xml" />
   </ItemGroup>
 
   <ItemGroup>
+    <Content Include="config.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="OrleansConfiguration.dev.xml">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
@@ -35,6 +39,7 @@
     <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
     <PackageReference Include="Microsoft.Extensions.ObjectPool" Version="2.0.0" />
     <PackageReference Include="Microsoft.Orleans.Client" Version="2.3.4" />
+    <PackageReference Include="Orleans.Providers.MongoDB" Version="2.4.0" />
     <PackageReference Include="Polly" Version="5.5.0" />
     <PackageReference Include="sharpcompress" Version="0.19.2" />
     <PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0006" />

+ 18 - 6
src/MineCase.Gateway/Program.cs

@@ -9,6 +9,8 @@ using System.Reflection;
 using System.Threading.Tasks;
 using Orleans.Runtime;
 using Polly;
+using Orleans.Configuration;
+using Orleans.ApplicationParts;
 
 namespace MineCase.Gateway
 {
@@ -29,10 +31,10 @@ namespace MineCase.Gateway
             _clusterClient?.Dispose();
         }
 
-        private static void ConfigureApplicationParts(IClientBuilder builder)
+        private static void ConfigureApplicationParts(IApplicationPartManager parts)
         {
             foreach (var assembly in _assemblies)
-                builder.AddApplicationPart(assembly);
+                parts.AddApplicationPart(assembly);
         }
 
         private static async void Startup()
@@ -46,12 +48,22 @@ namespace MineCase.Gateway
             await retryPolicy.ExecuteAsync(async () =>
             {
                 _clusterClient?.Dispose();
+                SelectAssemblies();
                 var builder = new ClientBuilder()
-                    .LoadConfiguration("OrleansConfiguration.dev.xml")
+                    .Configure<ClusterOptions>(options =>
+                    {
+                        options.ClusterId = "dev";
+                        options.ServiceId = "MineCaseService";
+                    })
                     .ConfigureServices(ConfigureServices)
-                    .ConfigureLogging(ConfigureLogging);
-                SelectAssemblies();
-                ConfigureApplicationParts(builder);
+                    .ConfigureLogging(ConfigureLogging)
+                    .ConfigureApplicationParts(ConfigureApplicationParts)
+                    .UseMongoDBClustering(options=>
+                    {
+                        options.ConnectionString = Configuration.GetSection("persistenceOptions")["connectionString"];
+                    });
+                
+                // ConfigureApplicationParts(builder);
                 _clusterClient = builder.Build();
 
                 var serviceProvider = _clusterClient.ServiceProvider;

+ 5 - 0
src/MineCase.Gateway/config.json

@@ -0,0 +1,5 @@
+{
+  "persistenceOptions": {
+    "connectionString": "mongodb://localhost:27017/minecase"
+  }
+}

+ 219 - 0
src/MineCase.Server.Grains/GrainObserverManager.cs

@@ -0,0 +1,219 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Orleans.Runtime;
+
+namespace Grains
+{
+    /// <summary>
+    /// Maintains a collection of grain observers.
+    /// </summary>
+    /// <typeparam name="T">
+    /// The grain observer type.
+    /// </typeparam>
+    public class GrainObserverManager<T> : IEnumerable<T>
+        where T : IAddressable
+    {
+        /// <summary>
+        /// The observers.
+        /// </summary>
+        private readonly Dictionary<T, DateTime> observers = new Dictionary<T, DateTime>();
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="GrainObserverManager{T}"/> class.
+        /// </summary>
+        public GrainObserverManager()
+        {
+            this.GetDateTime = () => DateTime.UtcNow;
+        }
+
+        /// <summary>
+        /// Gets or sets the delegate used to get the date and time, for expiry.
+        /// </summary>
+        public Func<DateTime> GetDateTime { get; set; }
+
+        /// <summary>
+        /// Gets or sets the expiration time span, after which observers are lazily removed.
+        /// </summary>
+        public TimeSpan ExpirationDuration { get; set; }
+
+        /// <summary>
+        /// Gets the number of observers.
+        /// </summary>
+        public int Count => this.observers.Count;
+
+        /// <summary>
+        /// Removes all observers.
+        /// </summary>
+        public void Clear()
+        {
+            this.observers.Clear();
+        }
+
+        /// <summary>
+        /// Ensures that the provided <paramref name="observer"/> is subscribed, renewing its subscription.
+        /// </summary>
+        /// <param name="observer">The observer.</param>
+        public void Subscribe(T observer)
+        {
+            // Add or update the subscription.
+            this.observers[observer] = this.GetDateTime();
+        }
+
+        /// <summary>
+        /// Ensures that the provided <paramref name="observer"/> is unsubscribed.
+        /// </summary>
+        /// <param name="observer">The observer.</param>
+        public void Unsubscribe(T observer)
+        {
+            this.observers.Remove(observer);
+        }
+
+        /// <summary>
+        /// Notifies all observers.
+        /// </summary>
+        /// <param name="notification">
+        /// The notification delegate to call on each observer.
+        /// </param>
+        /// <param name="predicate">The predicate used to select observers to notify.</param>
+        /// <returns>
+        /// A <see cref="Task"/> representing the work performed.
+        /// </returns>
+        public async Task Notify(Func<T, Task> notification, Func<T, bool> predicate = null)
+        {
+            var now = this.GetDateTime();
+            var defunct = default(List<T>);
+            foreach (var observer in this.observers)
+            {
+                if (observer.Value + this.ExpirationDuration < now)
+                {
+                    // Expired observers will be removed.
+                    defunct = defunct ?? new List<T>();
+                    defunct.Add(observer.Key);
+                    continue;
+                }
+
+                // Skip observers which don't match the provided predicate.
+                if (predicate != null && !predicate(observer.Key))
+                {
+                    continue;
+                }
+
+                try
+                {
+                    await notification(observer.Key);
+                }
+                catch (Exception)
+                {
+                    // Failing observers are considered defunct and will be removed..
+                    defunct = defunct ?? new List<T>();
+                    defunct.Add(observer.Key);
+                }
+            }
+
+            // Remove defunct observers.
+            if (defunct != default(List<T>))
+            {
+                foreach (var observer in defunct)
+                {
+                    this.observers.Remove(observer);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Notifies all observers which match the provided <paramref name="predicate"/>.
+        /// </summary>
+        /// <param name="notification">
+        /// The notification delegate to call on each observer.
+        /// </param>
+        /// <param name="predicate">The predicate used to select observers to notify.</param>
+        public void Notify(Action<T> notification, Func<T, bool> predicate = null)
+        {
+            var now = this.GetDateTime();
+            var defunct = default(List<T>);
+            foreach (var observer in this.observers)
+            {
+                if (observer.Value + this.ExpirationDuration < now)
+                {
+                    // Expired observers will be removed.
+                    defunct = defunct ?? new List<T>();
+                    defunct.Add(observer.Key);
+                    continue;
+                }
+
+                // Skip observers which don't match the provided predicate.
+                if (predicate != null && !predicate(observer.Key))
+                {
+                    continue;
+                }
+
+                try
+                {
+                    notification(observer.Key);
+                }
+                catch (Exception)
+                {
+                    // Failing observers are considered defunct and will be removed..
+                    defunct = defunct ?? new List<T>();
+                    defunct.Add(observer.Key);
+                }
+            }
+
+            // Remove defunct observers.
+            if (defunct != default(List<T>))
+            {
+                foreach (var observer in defunct)
+                {
+                    this.observers.Remove(observer);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Removed all expired observers.
+        /// </summary>
+        public void ClearExpired()
+        {
+            var now = this.GetDateTime();
+            var defunct = default(List<T>);
+            foreach (var observer in this.observers)
+            {
+                if (observer.Value + this.ExpirationDuration < now)
+                {
+                    // Expired observers will be removed.
+                    defunct = defunct ?? new List<T>();
+                    defunct.Add(observer.Key);
+                }
+            }
+
+            // Remove defunct observers.
+            if (defunct != default(List<T>))
+            {
+                foreach (var observer in defunct)
+                {
+                    this.observers.Remove(observer);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Returns the enumerator for all observers.
+        /// </summary>
+        /// <returns>The enumerator for all observers.</returns>
+        public IEnumerator<T> GetEnumerator()
+        {
+            return this.observers.Keys.GetEnumerator();
+        }
+
+        /// <summary>
+        /// Returns the enumerator for all observers.
+        /// </summary>
+        /// <returns>The enumerator for all observers.</returns>
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return this.observers.Keys.GetEnumerator();
+        }
+    }
+}

+ 2 - 2
src/MineCase.Server.Grains/Network/ClientboundPacketSinkGrain.cs

@@ -13,7 +13,7 @@ namespace MineCase.Server.Network
 {
     internal class ClientboundPacketSinkGrain : Grain, IClientboundPacketSink
     {
-        private ObserverSubscriptionManager<IClientboundPacketObserver> _subsManager;
+        private Grains.GrainObserverManager<IClientboundPacketObserver> _subsManager;
         private readonly IPacketPackager _packetPackager;
 
         public ClientboundPacketSinkGrain(IPacketPackager packetPackager)
@@ -23,7 +23,7 @@ namespace MineCase.Server.Network
 
         public override Task OnActivateAsync()
         {
-            _subsManager = new ObserverSubscriptionManager<IClientboundPacketObserver>();
+            _subsManager = new Grains.GrainObserverManager<IClientboundPacketObserver>();
             return base.OnActivateAsync();
         }
 

+ 6 - 2
src/MineCase.Server.Grains/User/UserLifecycle.cs

@@ -7,11 +7,15 @@ using Orleans.Runtime;
 
 namespace MineCase.Server.User
 {
-    internal class UserLifecycle : LifecycleObservable, IUserLifecycle
+    internal class UserLifecycle : IUserLifecycle
     {
         public UserLifecycle(ILogger logger)
-            : base(logger)
         {
         }
+
+        public IDisposable Subscribe(string observerName, int stage, ILifecycleObserver observer)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 2 - 2
src/MineCase.Server/MineCase.Server.csproj

@@ -27,8 +27,8 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Autofac" Version="4.6.2" />
-    <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.0" />
+    <PackageReference Include="Autofac" Version="4.9.2" />
+    <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.4.0" />
     <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
     <PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />

+ 28 - 12
src/MineCase.Server/Program.cs

@@ -7,6 +7,8 @@ using System.Threading;
 using System.Threading.Tasks;
 using MineCase.Serialization.Serializers;
 using Orleans;
+using Orleans.Configuration;
+using Orleans.ApplicationParts;
 
 namespace MineCase.Server
 {
@@ -26,13 +28,29 @@ namespace MineCase.Server
             ConfigureAppConfiguration(configBuilder);
             Configuration = configBuilder.Build();
 
+            SelectAssemblies();
             var builder = new SiloHostBuilder()
                 .ConfigureLogging(ConfigureLogging)
-                .UseConfiguration(LoadClusterConfiguration())
-                .UseDashboard()
+                .Configure<ClusterOptions>(options =>
+                {
+                    options.ClusterId = "dev";
+                    options.ServiceId = "MineCaseService";
+                })
+                .ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
+                .UseMongoDBReminders(options =>
+                {
+                    options.ConnectionString = Configuration.GetSection("persistenceOptions")["connectionString"];
+                })
+                .UseMongoDBClustering(c =>
+                {
+                    c.ConnectionString = Configuration.GetSection("persistenceOptions")["connectionString"];
+                    // c.UseJsonFormat = true;
+                })
+                .ConfigureApplicationParts(ConfigureApplicationParts)
+                .UseDashboard(options => { })
                 .UseServiceProviderFactory(ConfigureServices);
-            SelectAssemblies();
-            ConfigureApplicationParts(builder);
+            
+            // ConfigureApplicationParts(builder);
             _siloHost = builder.Build();
             await StartAsync();
             Console.WriteLine("Press Ctrl+C to terminate...");
@@ -49,24 +67,22 @@ namespace MineCase.Server
             Serializers.RegisterAll(_siloHost.Services);
             await _siloHost.StartAsync();
         }
-
+        
+        /*
         private static ClusterConfiguration LoadClusterConfiguration()
         {
             var cluster = new ClusterConfiguration();
             cluster.LoadFromFile("OrleansConfiguration.dev.xml");
             cluster.RegisterDashboard();
-            cluster.AddMongoDBStorageProvider("PubSubStore", c =>
-            {
-                c.ConnectionString = Configuration.GetSection("persistenceOptions")["connectionString"];
-                c.UseJsonFormat = true;
-            });
+            cluster.AddMongoDBStorageProvider();
             return cluster;
         }
+        */
 
-        private static void ConfigureApplicationParts(ISiloHostBuilder builder)
+        private static void ConfigureApplicationParts(IApplicationPartManager parts)
         {
             foreach (var assembly in _assemblies)
-                builder.AddApplicationPart(assembly);
+                parts.AddApplicationPart(assembly);
         }
     }
 }