Example #1
0
        /// <summary>
        /// Am I Primary?
        /// </summary>
        /// <param name="info">ElectorInfo</param>
        /// <returns>True, if so</returns>
        public bool AmIPrimary(ElectorInfo info)
        {
            bool amI = false;

            ConnectionMultiplexer redis;
            IDatabase             db;
            ITransaction          trans;

            DateTime stamp = DateTime.UtcNow;

            ElectorInfo otherInfo;

            int expireMS = GetExpirationMilliseconds();

            try
            {
                redis = ConnectionMultiplexer.Connect(this._config.RedisConnectionString());
                redis.IncludeDetailInExceptions = true;
                db = redis.GetDatabase();

                trans = db.CreateTransaction();

                var text = db.StringGet(info.ApplicationName);
                if (string.IsNullOrWhiteSpace(text))
                {
                    otherInfo = info;
                }
                else
                {
                    otherInfo = JsonConvert.DeserializeObject <ElectorInfo>(text);
                }

                if (otherInfo.UniqueInstanceId == info.UniqueInstanceId)
                {
                    UpdateKey(db, info, stamp);
                    amI = true;
                }
                else
                {
                    var ts  = stamp - otherInfo.LastCallUtc;
                    var age = ts.TotalMilliseconds;
                    if (age > expireMS)
                    {
                        UpdateKey(db, info, stamp);
                        amI = true;
                    }
                }

                trans.Execute();
            }

            finally
            {
                db    = null;
                trans = null;
                redis = null;
            }

            return(amI);
        }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="applicationName"></param>
        /// <returns></returns>
        public bool ForceElection(string applicationName)
        {
            ConnectionMultiplexer redis;
            IDatabase             db;
            ITransaction          trans;

            try
            {
                redis = ConnectionMultiplexer.Connect(this._config.RedisConnectionString());
                redis.IncludeDetailInExceptions = true;
                db = redis.GetDatabase();

                trans = db.CreateTransaction();

                DateTime stamp = DateTime.UtcNow.AddDays(-1);
                var      info  = new ElectorInfo()
                {
                    LastCallUtc = stamp, ApplicationName = applicationName, UniqueInstanceId = NO_INSTANCE
                };
                UpdateKey(db, info, stamp);

                trans.Execute();
            }
            finally
            {
                db    = null;
                trans = null;
                redis = null;
            }

            return(true);
        }
Example #3
0
        private void UpdateKey(IDatabase db, ElectorInfo info, DateTime stamp)
        {
            info.LastCallUtc = stamp;
            var text = JsonConvert.SerializeObject(info);

            db.KeyDelete(info.ApplicationName);
            db.StringSet(info.ApplicationName, text);
        }
Example #4
0
        public void ConCurr_1()
        {
            bool amIPrimary = false;

            RedisElectorProvider prov = new RedisElectorProvider(redisConfig);

            prov.SetExpirationMilliseconds(RedisElectorProvider.Recommended_ExpirationMilliseconds);

            DateTime stamp = DateTime.UtcNow;

            var agent1 = new ElectorInfo()
            {
                ApplicationName  = ApplicationName,
                LastCallUtc      = stamp,
                UniqueInstanceId = Guid.NewGuid().ToString()
            };

            amIPrimary = prov.AmIPrimary(agent1);
            Assert.IsTrue(amIPrimary, "Agent 1");

            var agent2 = new ElectorInfo()
            {
                ApplicationName  = ApplicationName,
                LastCallUtc      = stamp,
                UniqueInstanceId = Guid.NewGuid().ToString()
            };

            amIPrimary = prov.AmIPrimary(agent2);
            Assert.IsFalse(amIPrimary, "Agent 2");

            Thread.Sleep(RedisElectorProvider.Recommended_ExpirationMilliseconds + 1000);

            agent2.LastCallUtc = DateTime.UtcNow;

            amIPrimary = prov.AmIPrimary(agent2);
            Assert.IsTrue(amIPrimary, "Agent 2");

            agent1.UpdateLastCallUtc();

            amIPrimary = prov.AmIPrimary(agent1);
            Assert.IsFalse(amIPrimary, "Agent 1");

            amIPrimary = prov.AmIPrimary(agent1);
            Assert.IsFalse(amIPrimary, "Agent 1");

            amIPrimary = prov.AmIPrimary(agent2);
            Assert.IsTrue(amIPrimary, "Agent 2");
        }
        static int Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            logger = LogFactoryHelper.CreateLogger <Program>();

            string fallbackFilename = @"VCAP_Services.json";

            if (args.Length > 0)
            {
                fallbackFilename = args[0];
            }

            // Get Assembly Object, casting it to this class type
            var assembly = typeof(Program).Assembly;

            // Get all custom attribute data
            foreach (var attribute in assembly.GetCustomAttributesData())
            {
                // try to find a value
                if (!attribute.TryParse(out string value))
                {
                    value = string.Empty;
                }
                // write name and value
                if (!string.IsNullOrWhiteSpace(value))
                {
                    logger.LogInformation($"{attribute.AttributeType.Name} - {value}");
                }
            }

            var whoIAm = new ElectorInfo()
            {
                ApplicationName = "Demo_RedisElector_Singleton", LastCallUtc = DateTime.UtcNow, UniqueInstanceId = Guid.NewGuid().ToString()
            };

            logger.LogInformation("I Am: {0}", whoIAm.ToString());

            var redisConfig = GetConfig("p-redis", fallbackFilename);
            var prov        = new RedisElectorProvider(redisConfig);

            prov.SetExpirationMilliseconds(RedisElectorProvider.Recommended_ExpirationMilliseconds);

            while (shouldRun)
            {
                if (prov.AmIPrimary(whoIAm))
                {
                    if (dice.Next(1, 100) > 70)
                    {
                        int waiter = RedisElectorProvider.Recommended_ExpirationMilliseconds * 2;
                        logger.LogWarning("{0} for {1} ms, Primary Faulting", whoIAm.UniqueInstanceId, waiter);
                        prov.ForceElection(whoIAm.ApplicationName);
                        Thread.Sleep(waiter);
                    }
                    else
                    {
                        // Fake: Unit of Work
                        int waiter = dice.Next(RedisElectorProvider.Minimim_ExpirationMilliseconds, RedisElectorProvider.Recommended_ExpirationMilliseconds * 2);
                        logger.LogInformation("{0} for {1} ms, Primary Working", whoIAm.UniqueInstanceId, waiter);
                        Thread.Sleep(waiter);
                    }
                }
                else
                {
                    int waiter = RedisElectorProvider.Minimim_ExpirationMilliseconds;
                    logger.LogInformation("{0} for {1} ms, Not Primary", whoIAm.UniqueInstanceId, waiter);
                    Thread.Sleep(waiter);
                }
            }

            Environment.ExitCode = exitCode;
            return(exitCode);
        }