Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            List <long> data = new List <long>();

            DateTime timeBegin = DateTime.Now;
            //var generator = new IdGenerator(0);

            var epoch     = new DateTime(2020, 7, 22, 0, 0, 0, DateTimeKind.Utc);
            var structure = new IdStructure(45, 2, 16);
            var options   = new IdGeneratorOptions(structure, new DefaultTimeSource(epoch));
            var generator = new IdGenerator(0, options);

            for (int i = 0; i < 100000000; i++)
            {
                var id = generator.CreateId();
                data.Add(id);
                //Console.WriteLine($"生成id:{id}");
            }
            DateTime timeEnd = DateTime.Now;
            TimeSpan span    = timeEnd.Subtract(timeBegin);

            data.Add(data.Last());
            Console.WriteLine($"添加一个测试数据后:{data.Count}");
            data = data.Distinct().ToList();
            Console.WriteLine($"取出重复数据后:{data.Count}");
            Console.WriteLine($"耗时:{span.TotalSeconds}");
            Console.WriteLine($"平均每秒产生:{data.Count / span.TotalSeconds}");

            Console.ReadLine();
        }
Ejemplo n.º 2
0
        public void FromId_Returns_CorrectValue()
        {
            var s     = new IdStructure(42, 8, 13);
            var epoch = new DateTimeOffset(2018, 7, 31, 14, 48, 2, TimeSpan.FromHours(2));  // Just some "random" epoch...
            var ts    = new MockTimeSource(5, TimeSpan.FromSeconds(7), epoch);              // Set clock at 5 ticks; each tick being 7 seconds...
                                                                                            // Set generator ID to 234
            var g = new IdGenerator(234, new IdGeneratorOptions(s, ts));

            // Generate a bunch of id's
            long id = 0;

            for (var i = 0; i < 35; i++)
            {
                id = g.CreateId();
            }

            var target = g.FromId(id);


            Assert.AreEqual(34, target.SequenceNumber);                                     // We generated 35 id's in the same tick, so sequence should be at 34.
            Assert.AreEqual(234, target.GeneratorId);                                       // With generator id 234
            Assert.AreEqual(epoch.Add(TimeSpan.FromSeconds(5 * 7)), target.DateTimeOffset); // And the clock was at 5 ticks, with each tick being
                                                                                            // 7 seconds (so 35 seconds from epoch)
                                                                                            // And epoch was 2018-7-31 14:48:02 +02:00...
        }
Ejemplo n.º 3
0
        public static void Initialize(IdGenSettings settings)
        {
            //var epoch = new DateTime(2020, 12, 22, 0, 0, 0, DateTimeKind.Utc);
            var structure = new IdStructure(settings.TimestampBits, settings.GeneratorIdBits, settings.SequenceBits);
            var options   = new IdGeneratorOptions(structure, new DefaultTimeSource(settings.Epoch));

            StaticIdGen.IdGen = new IdGenDistributedId(settings.MachineId, options);
        }
Ejemplo n.º 4
0
        public void GeneratorId_ShouldBePresent_InID2()
        {
            // We setup our generator so that the time is 0 and generator id equals 4095 so that all 12 bits are set
            // for the generator.
            var ts = new MockTimeSource();
            var s  = new IdStructure(40, 12, 11); // We use a custom IdStructure with 12 bits for the generator this time
            var g  = new IdGenerator(4095, new IdGeneratorOptions(s, ts));

            // Make sure all expected bits are set
            Assert.AreEqual(-1 & ((1 << 12) - 1), g.Id);
            Assert.AreEqual((1 << 12) - 1 << 11, g.CreateId());
        }
Ejemplo n.º 5
0
        public IdManager()
        {
            // Fun fact: This is the exact moment that SpookVooper was terminated
            // which led to the development of Valour becoming more than just a side
            // project. Viva la Vooperia.
            var epoch = new DateTime(2021, 1, 11, 4, 37, 0);

            var structure = new IdStructure(45, 10, 8);

            var options = new IdGeneratorOptions(structure, new DefaultTimeSource(epoch));

            Generator = new IdGenerator(0, options);
        }
Ejemplo n.º 6
0
        public SnowflakeEngine()
        {
            Epoch = new DateTime(2020, 7, 30, 0, 0, 0, DateTimeKind.Utc);

            //This is written @ 11:58 PM, 30/7/2020

            // Create an ID with 31 Bit for TimeStamp, 1 Bits for GeneratorID and 31 Bits for Sequence

            var IDStructure = new IdStructure(31, 1, 31);

            var Options = new IdGeneratorOptions(IDStructure, new DefaultTimeSource(Epoch));

            Generator = new IdGenerator(1, Options);
        }
Ejemplo n.º 7
0
        public void CreateId_Waits_OnSequenceOverflow()
        {
            // Use timesource that generates a new tick every 10 calls to GetTicks()
            var ts = new MockAutoIncrementingIntervalTimeSource(10);
            var s  = new IdStructure(61, 0, 2);
            var g  = new IdGenerator(0, new IdGeneratorOptions(idStructure: s, timeSource: ts, sequenceOverflowStrategy: SequenceOverflowStrategy.SpinWait));

            // We have a 2-bit sequence; generating 4 id's in a single time slot - wait for other then
            Assert.AreEqual(0, g.CreateId());
            Assert.AreEqual(1, g.CreateId());
            Assert.AreEqual(2, g.CreateId());
            Assert.AreEqual(3, g.CreateId());
            Assert.AreEqual(4, g.CreateId());   // This should trigger a spinwait and return the next ID
            Assert.AreEqual(5, g.CreateId());
        }
Ejemplo n.º 8
0
        public void CreateId_Throws_OnSequenceOverflow()
        {
            var ts = new MockTimeSource();
            var s  = new IdStructure(41, 20, 2);
            var g  = new IdGenerator(0, new IdGeneratorOptions(idStructure: s, timeSource: ts));

            // We have a 2-bit sequence; generating 4 id's shouldn't be a problem
            for (var i = 0; i < 4; i++)
            {
                Assert.AreEqual(i, g.CreateId());
            }

            // However, if we invoke once more we should get an SequenceOverflowException
            g.CreateId();
        }
Ejemplo n.º 9
0
        public void TryCreateId_Returns_False_OnSequenceOverflow()
        {
            var ts = new MockTimeSource();
            var s  = new IdStructure(41, 20, 2);
            var g  = new IdGenerator(0, new IdGeneratorOptions(idStructure: s, timeSource: ts));

            // We have a 2-bit sequence; generating 4 id's shouldn't be a problem
            for (var i = 0; i < 4; i++)
            {
                Assert.IsTrue(g.TryCreateId(out var _));
            }

            // However, if we invoke once more we should get an SequenceOverflowException
            // which should be indicated by the false return value
            Assert.IsFalse(g.TryCreateId(out var _));
        }
Ejemplo n.º 10
0
        static IdGenerator()
        {
            if (!IdGenGlobalState.IsCreated)
            {
                throw new InvalidOperationException("IdGenerator is not initialized");
            }

            var structure = new IdStructure(44, 6, 13);

            Generator = new IdGen.IdGenerator(IdGenGlobalState.InstanceId,
                                              new IdGeneratorOptions(
                                                  idStructure: structure,
                                                  timeSource: new DefaultTimeSource(IdGenGlobalState.Epoch),
                                                  sequenceOverflowStrategy: SequenceOverflowStrategy.SpinWait));

            Console.WriteLine("Max. generators       : {0}", structure.MaxGenerators);
            Console.WriteLine("Id's/ms per generator : {0}", structure.MaxSequenceIds);
            Console.WriteLine("Wraparound date       : {0:O}", structure.WraparoundDate(Generator.Options.TimeSource.Epoch, Generator.Options.TimeSource));
        }
Ejemplo n.º 11
0
        public JsonResult AddBill(string name, string address, string phone, string email, int payment)
        {
            try {
                Bill bill = new Bill();

                //Declare snowflake algorithm
                DateTime epoch = new DateTime(2021, 1, 1, 0, 0, 0, DateTimeKind.Utc);

                //41 bit for time
                //12 bit for number of shard
                //10 bit for sequence
                IdStructure        structure = new IdStructure(41, 12, 10);
                IdGeneratorOptions option    = new IdGeneratorOptions(structure, new DefaultTimeSource(epoch));
                IdGenerator        generator = new IdGenerator(0, option);

                //create new id and declare properties to bill
                long billID = generator.CreateId();

                bill.BillID      = billID;
                bill.userName    = name;
                bill.address     = address;
                bill.phoneNumber = phone;
                bill.email       = email;
                bill.payment     = payment;
                bill.status      = 1;
                bill.orderTime   = DateTime.Now;

                //email content
                string content = $"You have successfully booked your order, the ready-made product will be delivered within {DateTime.Now.AddDays(3).Date} to {DateTime.Now.AddDays(7).Date}<br/><br/>";
                content += $"Order ID: {billID}<br/><br/>";
                //head row of table
                content += "<table><tr style=\"color: white; background-color: #7fad39;\"><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">Product</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">Price</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">Quantity</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">Total</td></tr>";
                decimal totalValue = 0;

                //is loged User
                if (Session["user"] == null)
                {
                    //didn't log in case, storage cart in cookies

                    Dictionary <string, int> cart;

                    //check is exsisted cart in cookies
                    if (Session["cart"] != null)
                    {
                        //exsisted case, pick up it
                        cart = (Dictionary <string, int>)Session["cart"];

                        Dictionary <string, int> .KeyCollection keys = cart.Keys;


                        //add bill to database
                        foreach (string key in keys)
                        {
                            bill.productid = Int32.Parse(key);
                            bill.quantity  = cart[key];
                            Product p = db.Products.Find(bill.productid = Int32.Parse(key));
                            bill.amount = p.price;

                            //add into bill
                            db.Bills.Add(bill);
                            db.SaveChanges();

                            //add middle row of table
                            decimal total = p.price * cart[key];
                            content    += $"<tr style=\"background - color: #eeeeee;\"><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">{p.title}</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">{p.price.ToString("C")}</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">{cart[key]}</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">{total.ToString("C")}</td>";
                            totalValue += total;
                        }
                        Session.Remove("cart");
                    }
                    else
                    {
                        //in null case of cart
                        return(Json("Please put item into cart before check out!", JsonRequestBehavior.AllowGet));
                    }
                }
                else
                {
                    //loged in case
                    Account account = db.Accounts.Find(Int32.Parse(Session["user"].ToString()));
                    bill.userid = account.userID;

                    //load cart infor from database
                    List <Cart> carts = db.Carts.ToList().Select(cart => new Cart {
                        cartid    = cart.cartid,
                        userid    = cart.userid,
                        productid = cart.productid,
                        quantity  = cart.quantity,
                        Account   = db.Accounts.Find(cart.userid),
                        Product   = db.Products.Find(cart.productid)
                    }).Where(c => c.userid == account.userID).ToList();

                    //check is exsisted any item in cart in database
                    if (carts.Count > 0)
                    {
                        foreach (Cart cart in carts)
                        {
                            bill.productid = cart.productid;
                            bill.quantity  = cart.quantity;
                            bill.amount    = cart.Product.price;

                            //add bill
                            db.Bills.Add(bill);

                            //add middle row of table
                            decimal total = cart.Product.price * cart.quantity;
                            content    += $"<tr style=\"background - color: #eeeeee;\"><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">{cart.Product.title}</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">{cart.Product.price.ToString("C")}</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">{cart.quantity}</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">{total.ToString("C")}</td>";
                            totalValue += total;

                            //remove item from cart
                            db.Carts.Remove(db.Carts.Find(cart.cartid));
                            db.SaveChanges();
                        }
                    }
                    else
                    {
                        //in null case of cart
                        return(Json(new {
                            type = 2,
                            message = "Please put item into cart before check out!"
                        }, JsonRequestBehavior.AllowGet));
                    }
                }

                Session["tempBillID"] = billID;

                //last row of table
                content += $"<tr style=\"background-color: #F5F5F5;\"><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\"></td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\"></td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">Total order value</td><td style=\"padding: 5px 10px 5px 10px; font-size: 15px;\">{totalValue.ToString("C")}</td></tr></table>";

                try {
                    //send email to user
                    MailAddress senderEmail   = new MailAddress("*****@*****.**", "BookStore");
                    MailAddress receiverEmail = new MailAddress(email, "Receiver");
                    string      password      = "******";
                    string      subject       = "Order successfull";
                    string      body          = content;
                    SmtpClient  smtp          = new SmtpClient {
                        Host                  = "smtp.gmail.com",
                        Port                  = 587,
                        EnableSsl             = true,
                        DeliveryMethod        = SmtpDeliveryMethod.Network,
                        UseDefaultCredentials = false,
                        Credentials           = new NetworkCredential(senderEmail.Address, password)
                    };
                    using (MailMessage mess = new MailMessage(senderEmail, receiverEmail)
                    {
                        Subject = subject,
                        Body = body
                    }) {
                        mess.IsBodyHtml = true;
                        smtp.Send(mess);
                    }

                    return(Json(new {
                        type = 1,
                        message = "Check Out Success!"
                    }, JsonRequestBehavior.AllowGet));
                } catch {
                    return(Json(new {
                        type = 2,
                        message = "Send email fail!"
                    }, JsonRequestBehavior.AllowGet));
                }
            } catch {
                return(Json(new {
                    type = 2,
                    message = "Check Out Fail!"
                }, JsonRequestBehavior.AllowGet));
            }
        }
Ejemplo n.º 12
0
        public void ConfigureServices(IServiceCollection services)
        {
            Log.Information("Startup::ConfigureServices");

            try
            {
                services.AddControllers(
                    opt =>
                {
                    //Custom filters can be added here
                    //opt.Filters.Add(typeof(CustomFilterAttribute));
                    //opt.Filters.Add(new ProducesAttribute("application/json"));
                }
                    ).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

                #region "API versioning"
                //API versioning service
                services.AddApiVersioning(
                    o =>
                {
                    //o.Conventions.Controller<UserController>().HasApiVersion(1, 0);
                    o.AssumeDefaultVersionWhenUnspecified = true;
                    o.ReportApiVersions = true;
                    o.DefaultApiVersion = new ApiVersion(1, 0);
                    o.ApiVersionReader  = new UrlSegmentApiVersionReader();
                }
                    );

                // format code as "'v'major[.minor][-status]"
                services.AddVersionedApiExplorer(
                    options =>
                {
                    options.GroupNameFormat = "'v'VVV";
                    //versioning by url segment
                    options.SubstituteApiVersionInUrl = true;
                });
                #endregion

                #region Database
                // Register Database Entity Maps
                services.AddSingleton <IEntityTypeMap, UserMap>();
                services.AddSingleton <IEntityTypeMap, DroneMap>();
                services.AddSingleton <IEntityTypeMap, MissionMap>();
                services.AddSingleton <IEntityTypeMap, CompanyAccountMap>();
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <DroneCommands>());
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <DroneNetworkSettings>());
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <DroneOnvifSettings>());
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <GeoArea>());
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <GeoPoint>());
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <PatrolConfig>());
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <Drone>());
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <ObjectDetection>());
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <PlannedRoute>());
                services.AddSingleton <IEntityTypeMap>(new BaseEntityMap <StatusReport>());

                //DB service
                if (Configuration["ConnectionStrings:UseInMemoryDatabase"] == "True")
                {
                    services.AddDbContext <DefaultDbContext>(opt => opt.UseInMemoryDatabase("TestDB-" + Guid.NewGuid().ToString()));
                }
                else
                {
                    services.AddDbContext <DefaultDbContext>(options => options.UseNpgsql(
                                                                 Configuration["ConnectionStrings:Moonlimit.DroneAPIDB"],
                                                                 o => o.UseNetTopologySuite())
                                                             , ServiceLifetime.Transient);
                }
                #endregion

                #region "Authentication"
                if (Configuration["Authentication:UseIdentityServer4"] == "False")
                {
                    //JWT API authentication service
                    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        options.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuer           = true,
                            ValidateAudience         = true,
                            ValidateLifetime         = true,
                            ValidateIssuerSigningKey = true,
                            ValidIssuer      = Configuration["Jwt:Issuer"],
                            ValidAudience    = Configuration["Jwt:Issuer"],
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
                        };
                    }
                                  );
                }
                else
                {
                    //Identity Server 4 API authentication service
                    services.AddAuthorization();
                    //.AddJsonFormatters();
                    services.AddAuthentication("Bearer")
                    .AddIdentityServerAuthentication(option =>
                    {
                        option.Authority            = Configuration["Authentication:IdentityServer4IP"];
                        option.RequireHttpsMetadata = false;
                        //option.ApiSecret = "secret";
                        option.ApiName = "Moonlimit.DroneAPI";  //This is the resourceAPI that we defined in the Config.cs in the AuthServ project (apiresouces.json and clients.json). They have to be named equal.
                    });
                }
                #endregion

                #region "CORS"
                // include support for CORS
                // More often than not, we will want to specify that our API accepts requests coming from other origins (other domains). When issuing AJAX requests, browsers make preflights to check if a server accepts requests from the domain hosting the web app. If the response for these preflights don't contain at least the Access-Control-Allow-Origin header specifying that accepts requests from the original domain, browsers won't proceed with the real requests (to improve security).
                services.AddCors(options =>
                {
                    options.AddPolicy("CorsPolicy-public",
                                      builder => builder.AllowAnyOrigin() //WithOrigins and define a specific origin to be allowed (e.g. https://mydomain.com)
                                      .AllowAnyMethod()
                                      .AllowAnyHeader()
                                      //.AllowCredentials()
                                      .Build());
                });
                #endregion

                #region "MVC and JSON options"
                //mvc service (set to ignore ReferenceLoopHandling in json serialization like Users[0].Account.Users)
                //in case you need to serialize entity children use commented out option instead
                services.AddMvc(option => option.EnableEndpointRouting = false)
                .AddNewtonsoftJson(options => { options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; }); //NO entity classes' children serialization
                                                                                                                                                     //.AddNewtonsoftJson(ops =>
                                                                                                                                                     //{
                                                                                                                                                     //    ops.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
                                                                                                                                                     //    ops.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
                                                                                                                                                     //}); //WITH entity classes' children serialization
                #endregion

                #region "DI code"
                //ID Generator
                var epoch = new DateTime(2021, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                // Create an ID with 31 (68 years if measured in seconds) bits for timestamp, 16 for generator-id and 16 for sequence(65536 per sec.)
                var structure = new IdStructure(31, 16, 16);
                // Prepare options
                var options = new IdGeneratorOptions(structure, new DefaultTimeSource(epoch, TimeSpan.FromSeconds(1.0)), SequenceOverflowStrategy.SpinWait);
                services.AddSingleton(new IdGenerator(0, options)); //Gen0 is for testing

                //general unitofwork injections
                services.AddTransient <IUnitOfWork, UnitOfWork>();

                //services injections
                services.AddTransient(typeof(CompanyAccountService <,>), typeof(CompanyAccountService <,>));
                services.AddTransient(typeof(UserService <,>), typeof(UserService <,>));
                services.AddTransient(typeof(CompanyAccountServiceAsync <,>), typeof(CompanyAccountServiceAsync <,>));
                services.AddTransient(typeof(UserServiceAsync <,>), typeof(UserServiceAsync <,>));
                //
                SetAdditionalDIServices(services);
                //...add other services
                //
                services.AddTransient(typeof(IService <,>), typeof(GenericService <,>));
                services.AddTransient(typeof(IServiceAsync <,>), typeof(GenericServiceAsync <,>));
                services.AddHttpContextAccessor();
                services.AddScoped <IClaimsData, HttpClaimsData>();
                services.AddScoped <IClaimValidator <Drone>, BasicClaimValidator <Drone> >();
                services.AddScoped <IClaimValidator <DroneNetworkSettings>, BasicClaimValidator <DroneNetworkSettings> >();
                services.AddScoped <IClaimValidator <Mission>, BasicClaimValidator <Mission> >();
                #endregion

                //data mapper services configuration
                services.AddAutoMapper(typeof(MappingProfile));

                #region "Swagger API"
                //Swagger API documentation
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo {
                        Title = "Moonlimit.DroneAPI API", Version = "v1"
                    });
                    c.SwaggerDoc("v2", new OpenApiInfo {
                        Title = "Moonlimit.DroneAPI API", Version = "v2"
                    });

                    //In Test project find attached swagger.auth.pdf file with instructions how to run Swagger authentication
                    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
                    {
                        Description = "Authorization header using the Bearer scheme",
                        Name        = "Authorization",
                        In          = ParameterLocation.Header,
                        Type        = SecuritySchemeType.ApiKey
                    });


                    c.AddSecurityRequirement(new OpenApiSecurityRequirement {
                        {
                            new OpenApiSecurityScheme {
                                Reference = new OpenApiReference {
                                    Id   = "Bearer", //The name of the previously defined security scheme.
                                    Type = ReferenceType.SecurityScheme
                                }
                            }, new List <string>()
                        }
                    });

                    //c.DocumentFilter<api.infrastructure.filters.SwaggerSecurityRequirementsDocumentFilter>();
                });
                #endregion
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
        }
Ejemplo n.º 13
0
        private static async Task <ISiloHost> CreateSilo()
        {
            var conf = new RedisConfiguration()
            {
                AbortOnConnectFail = true,
                Hosts = new RedisHost[]
                {
                    new RedisHost
                    {
                        Host = Configuration.GetSection("RedisCache")["Connection"],
                        Port = int.Parse(Configuration.GetSection("RedisCache")["Port"])
                    }
                },
                AllowAdmin                = true,
                ConnectTimeout            = 1000,
                ServerEnumerationStrategy = new ServerEnumerationStrategy()
                {
                    Mode       = ServerEnumerationStrategy.ModeOptions.All,
                    TargetRole = ServerEnumerationStrategy.TargetRoleOptions.Any,
                    UnreachableServerAction = ServerEnumerationStrategy.UnreachableServerActionOptions.Throw
                }
            };

            var builder = new SiloHostBuilder()
                          .Configure <ClusterOptions>(options =>
            {
                options.ClusterId = Configuration.GetSection("Orleans")["ClusterId"];
                options.ServiceId = Configuration.GetSection("Orleans")["ServiceId"];
            })
                          .Configure <SchedulingOptions>(options =>
            {
                options.AllowCallChainReentrancy = true;
                options.PerformDeadlockDetection = true;
            })
                          .Configure <SerializationProviderOptions>(options =>
            {
                options.SerializationProviders.Add(typeof(ProtobufNetSerializer));
                options.FallbackSerializationProvider = typeof(ProtobufNetSerializer);
            })
                          .Configure <EndpointOptions>(options => options.AdvertisedIPAddress = IPAddress.Loopback)
                          .UseMongoDBClient(Configuration.GetSection("Orleans")["Connection"])
                          .UseMongoDBReminders(options =>
            {
                options.DatabaseName            = Configuration.GetSection("Orleans")["Database"];
                options.CreateShardKeyForCosmos = false;
            })
                          .UseMongoDBClustering(c =>
            {
                c.DatabaseName            = Configuration.GetSection("Orleans")["Database"];
                c.CreateShardKeyForCosmos = false;
            })
                          .AddMongoDBGrainStorageAsDefault(c => c.Configure(options =>
            {
                options.DatabaseName            = Configuration.GetSection("Orleans")["Database"];
                options.CreateShardKeyForCosmos = false;
            }))
                          .AddMongoDBGrainStorage("PubSubStore", options =>
            {
                options.DatabaseName            = Configuration.GetSection("Orleans")["Database"];
                options.CreateShardKeyForCosmos = false;
            })
                          .ConfigureLogging(builder =>
            {
                builder.AddSerilog(new LoggerConfiguration()
                                   .Enrich.WithMachineName()
                                   .ReadFrom.Configuration(Configuration)
                                   .CreateLogger());
            })
                          .AddStartupTask <NStartupTask>()
                          .ConfigureApplicationParts(parts =>
            {
                parts.AddFromApplicationBaseDirectory().WithReferences();
            })
                          //.AddApplicationPart(typeof(Node).Assembly).WithReferences())
                          .ConfigureServices(services =>
            {
                services.AddIdGenerator(x =>
                {
                    string appIdStr = Configuration.GetSection("IdGen")["AppId"];
                    if (!ushort.TryParse(appIdStr, out ushort appid))
                    {
                        throw new Exception("Please config appid in 'config.json'");
                    }

                    x.AppId            = appid;
                    x.GeneratorOptions = new IdGeneratorOptions();
                    // Let's say we take april 1st 2020 as our epoch
                    var epoch            = DateTime.Parse(Configuration.GetSection("IdGen")["Epoch"]);
                    byte timestampBits   = byte.Parse(Configuration.GetSection("IdGen")["TimestampBits"]);
                    byte generatorIdBits = byte.Parse(Configuration.GetSection("IdGen")["GeneratorIdBits"]);
                    byte sequenceBits    = byte.Parse(Configuration.GetSection("IdGen")["SequenceBits"]);

                    // Create an ID with 45 bits for timestamp, 2 for generator-id
                    // and 16 for sequence
                    var structure = new IdStructure(timestampBits, generatorIdBits, sequenceBits);
                    // Prepare options
                    x.GeneratorOptions = new IdGeneratorOptions(structure, new DefaultTimeSource(epoch));
                });
                services.AddStackExchangeRedisExtensions <CacheSerializer>(conf);
                string connection = Configuration.GetSection("MongoPersist")["Connection"];
                services.AddSingleton <MongoDB.Driver.IMongoClient>(s => new MongoDB.Driver.MongoClient(connection));
                services.AddSingleton <IAccountDB, AccountDB>();
                services.AddSingleton <IRealmDB, RealmDB>();
                services.AddSingleton <IEntityDB, EntityDB>();
            })
                          //need to configure a grain storage called "PubSubStore" for using streaming with ExplicitSubscribe pubsub type
                          //.AddMemoryGrainStorage("PubSubStore")
                          //Depends on your application requirements, you can configure your silo with other stream providers, which can provide other features,
                          //such as persistence or recoverability. For more information, please see http://dotnet.github.io/orleans/Documentation/Orleans-Streams/Stream-Providers.html
                          .AddSimpleMessageStreamProvider(StreamProviders.AgentProvider);

            var host = builder.Build();
            await host.StartAsync();

            return(host);
        }