Example #1
0
        /// <summary>
        /// Fits the equivalent circuit.
        /// </summary>
        /// <param name="circuitModel">The circuit model.</param>
        /// <param name="fitOptions">The fit options.</param>
        /// <param name="fitProgress">The fit progress.</param>
        /// <returns></returns>
        /// <exception cref="Exception">
        /// Wait untill SimpleCurve is finished before detecting peaks
        /// or
        /// No impedimetric readings available in parent SimpleMeasurement
        /// or
        /// The circuit model must be defined
        /// </exception>
        public async Task <FitResult> FitEquivalentCircuit(CircuitModel circuitModel, FitOptionsCircuit fitOptions = null, FitProgress fitProgress = null)
        {
            if (!IsFinished)
            {
                throw new Exception("Wait untill SimpleCurve is finished before detecting peaks");
            }
            if (_simpleMeasurement.Measurement.nEISdata == 0)
            {
                throw new Exception("No impedimetric readings available in parent SimpleMeasurement");
            }
            if (circuitModel == null)
            {
                throw new Exception("The circuit model must be defined");
            }

            if (fitOptions == null)
            {
                fitOptions         = new FitOptionsCircuit();
                fitOptions.Model   = circuitModel;
                fitOptions.RawData = _simpleMeasurement.Measurement.EISdata[0];
            }

            FitAlgorithm fit = FitAlgorithm.FromAlgorithm(fitOptions);

            return(await fit.ApplyFitCircuitAsync(fitProgress));
        }
Example #2
0
        private void submitCircuit(object sender, EventArgs e)
        {
            if (Application.Current.Properties.ContainsKey("tempExercises") && circuitName.Text != "")
            {
                var          exerciseList = Application.Current.Properties["tempExercises"] as List <ExerciseModel>;       //get exercises
                CircuitModel circuit      = new CircuitModel();
                circuit.circuit = exerciseList;
                circuit.name    = circuitName.Text;

                if (Application.Current.Properties.ContainsKey("circuits"))
                {
                    var circuits = Application.Current.Properties["circuits"] as List <CircuitModel>;
                    Application.Current.Properties.Remove("circuits");
                    circuits.Add(circuit);
                    Application.Current.Properties["circuits"] = circuits;
                }
                else
                {
                    var circuitList = new List <CircuitModel>();
                    circuitList.Add(circuit);
                    Application.Current.Properties["circuits"] = circuitList;
                }

                list.ItemsSource = "";                                  //clear circuit
                circuitName.Text = "";                                  //clear circuit name
                Application.Current.Properties.Remove("tempExercises"); //clear the temp circuit
            }
        }
Example #3
0
        private void UpdateCircuit(CircuitModel model, CircuitModel.FailureReasonEnum failure, Stopwatch sw, DateTime attemptStartedDateTime)
        {
            //keeping a running tally of total calls and attempt stats (includes open circuit status attempts)
            model.Calls++;
            model.LastAttemptTimeTaken = sw.Elapsed.TotalMilliseconds;
            model.LastAttemptTimestamp = attemptStartedDateTime;

            //moves between closed/half-open/open depending on current cooldown period, status, and recent call attempt outcome
            if (failure != CircuitModel.FailureReasonEnum.OpenCircuit)
            {
                if (failure == CircuitModel.FailureReasonEnum.None)
                {
                    //reduce errocount with each successfull call attempt
                    if (model.ErrorCount > 0)
                    {
                        model.LastFailedAttemptTimestamp = null;
                        model.LastLogSerialized          = null;
                        model.ErrorCount--;
                    }
                }
                else
                {
                    model.LastFailedAttemptTimestamp = attemptStartedDateTime;
                    model.ErrorCount++;

                    if (model.BreakStatus == CircuitModel.BreakStatusEnum.Open)
                    {
                        //model.BreakStatus;
                        //model.LastAttemptFailureReason;
                        //model;

                        //use EmailHelper to queue an email with model data
                        // maybe EmailHelper should handle a quota of failures before it triggers
                        // or trigger a few times before giving up
                        // or wait before sending 1-2 emails, to make sure its not 50 emails, the either send
                        //  1 email "crm is down" or 2 emails for individual methods
                    }
                }

                //irrelevant of success or failure, update FailureReasonEnum with success/failure status to keep it fresh
                model.LastAttemptFailureReason = failure;
            }
            else
            {
                //if circuit is open, and either the last attempt was not a failure, or last failure was older than cooling off period
                if ((model.LastFailedAttemptTimestamp == null) || (attemptStartedDateTime.Subtract(model.LastFailedAttemptTimestamp.Value).TotalSeconds > model.Cooldown))
                {
                    //pretend there are no errors
                    model.LastFailedAttemptTimestamp = null;
                    model.LastAttemptFailureReason   = CircuitModel.FailureReasonEnum.None;

                    //reduce error count by 1 (this will allow 1 call attempt before the circuit re-opens in case of failure)
                    if (model.ErrorCount > 0)
                    {
                        model.ErrorCount--;
                    }
                }
            }
        }
Example #4
0
        public CircuitPage(CircuitModel circuit)
        {
            var stack = new StackLayout()
            {
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions   = LayoutOptions.StartAndExpand,
                Padding           = 50
            };

            label.Text      = circuit.name;
            label.TextColor = Color.Black;

            List <string> names = new List <string>();

            foreach (var circ in circuit.circuit)
            {
                names.Add(circ.name);
            }

            list.ItemsSource   = names;
            list.ItemSelected += async(sender, e) =>
            {
                if (e.SelectedItem != null)
                {
                    ExerciseModel exerc = null;
                    foreach (var exercise in circuit.circuit)
                    {
                        if (exercise.name.Equals(e.SelectedItem))
                        {
                            exerc = exercise;
                            break;
                        }
                    }
                    var exercisePage = new ExercisePage(exerc);
                    await Navigation.PushModalAsync(exercisePage);
                }
            };

            Button backButton = new Button()
            {
                Text              = "Back",
                TextColor         = Color.Black,
                BackgroundColor   = Color.SkyBlue,
                WidthRequest      = 40,
                VerticalOptions   = LayoutOptions.End,
                HorizontalOptions = LayoutOptions.Start
            };

            backButton.Clicked += async(sender, e) =>
            {
                await Navigation.PopModalAsync(); //go back to viewpage
            };

            stack.Children.Add(label);
            stack.Children.Add(backButton);
            this.BackgroundColor = Color.LightGray;

            Content = stack;
        }
Example #5
0
 public void SetCachedCircuit(CircuitModel model)
 {
     if (model != null)
     {
         _cachingHelper.AddCacheItem(_circuitConfigElement, model, model.MethodKey);
         AppendToCircuitStatusHashTable(model.MethodKey);
     }
 }
Example #6
0
        private void LogCallDetails <TResult>(Delegate method, object[] args, CircuitModel model, TResult result = default(TResult), Stopwatch sw = null)
        {
            var log = new Dictionary <string, object>();

            log["Method"] = model.MethodKey;

            if (sw != null)
            {
                log["TimeTaken"] = sw.Elapsed;
            }

            if (model.LastAttemptFailureReason != CircuitModel.FailureReasonEnum.None)
            {
                log["Failed"] = model.LastAttemptFailureReason;
            }

            var argslist = new Dictionary <string, object>();

            if (args != null)
            {
                var definitionParams = method.Method.GetParameters();
                for (int i = 0; i < args.Length; i++)
                {
                    argslist[definitionParams[i].Name] = args[i];
                }
            }
            log["Request"] = argslist;

            //some objects don't have paramaterless constructors,
            // and some objects have properties which call other services (which means recursive .ToJSON() could indirectly trigger more service calls to siebel)
            ////if (result != null && result.ToJSON().ToMD5().Equals(Activator.CreateInstance(result.GetType()).ToJSON().ToMD5())) log.EmptyResponse = true;

            if (result != null)
            {
                try
                {
                    //this might seem pointless, but if ToJSON fails, it will cause an error here as a timeout attempt.
                    // Instead of the logging system recursively writing logs and calling siebel over and over if the result has a GET property which calls a service
                    // If there is a safe way to remove this line, performance could be increased on the circuitbreaker while logging is active
                    result.ToJSON();

                    log["Response"] = result;
                }
                catch (Exception e)
                {
                    log["ResponseSerializationFailure"] = e.Message;
                }
            }

            model.LastLogSerialized = log.ToJSON();
            Task.Run(() => _loggingHelper.Log(log));
        }
Example #7
0
        public CircuitModel CloseCircuit(CircuitModel circuit)
        {
            if (circuit.ErrorCount >= circuit.LimitBreak)
            {
                //set errors to limit to cause instant circuit break
                circuit.ErrorCount = circuit.LimitBreak - 1;

                //update cache to save these changes
                SetCachedCircuit(circuit);
            }

            return(circuit);
        }
Example #8
0
        private void LogExceptionDetails <TResult>(Delegate method, object[] args, CircuitModel model, Exception exception, Stopwatch sw = null)
        {
            var log = new Dictionary <string, object>();

            log["Method"] = model.MethodKey;

            //look back in the stacktrace to find parent calling method
            var methodBase = (new StackTrace()).GetFrame(6).GetMethod();
            var classType  = methodBase.ReflectedType;

            if (classType != null)
            {
                var namespaceName = classType.Namespace;
                log["CalledFrom"] = namespaceName + "." + classType.Name + "." + methodBase.Name;
            }

            if (sw != null)
            {
                log["TimeTaken"] = sw.Elapsed;
            }

            if (args != null)
            {
                var definitionParams = method.Method.GetParameters();
                var argslist         = new Dictionary <string, object>();
                for (int i = 0; i < args.Length; i++)
                {
                    argslist[definitionParams[i].Name] = args[i];
                }
                if (argslist.Count > 0)
                {
                    log["Request"] = argslist;
                }
            }

            var loggableExceptionData = new Dictionary <string, object>();

            if (exception != null)
            {
                loggableExceptionData["ClassName"]        = exception.GetType().FullName;
                loggableExceptionData["Message"]          = exception.Message;
                loggableExceptionData["InnerException"]   = exception.InnerException;
                loggableExceptionData["StackTraceString"] = exception.GetType().FullName + exception.StackTrace.Replace("\r\n", "");
                loggableExceptionData["Source"]           = exception.Source;
            }
            log["Exception"] = loggableExceptionData;

            model.LastLogSerialized = log.ToJSON();
            Task.Run(() => _loggingHelper.Log(log));
        }
Example #9
0
        public CircuitModel OpenCircuit(CircuitModel circuit)
        {
            if (circuit.ErrorCount < circuit.LimitBreak)
            {
                //set errors to limit to cause instant circuit break
                circuit.ErrorCount = circuit.LimitBreak;

                //set last failed attempt to now, to force maximum cooldown period
                circuit.LastFailedAttemptTimestamp = DateTime.Now;

                //update cache to save these changes
                SetCachedCircuit(circuit);
            }

            return(circuit);
        }
Example #10
0
        /// <summary>
        /// Fits the equivalent circuit.
        /// </summary>
        /// <param name="cdc">The circuit descriptor code (CDC) defining the circuit.</param>
        /// <param name="initialParameters">The initial parameters.</param>
        /// <param name="fitOptions">The fit options.</param>
        /// <param name="fitProgress">The fit progress.</param>
        /// <returns></returns>
        /// <exception cref="Exception">
        /// Wait untill SimpleCurve is finished before detecting peaks
        /// or
        /// No impedimetric readings available in parent SimpleMeasurement
        /// </exception>
        /// <exception cref="ArgumentNullException">The circuit descriptor code (cdc) must be specified</exception>
        /// <exception cref="ArgumentException">
        /// Invalid circuit descriptor code (cdc)
        /// or
        /// The amount of parameters in the model does not match the number of parameters specified in the initial parameter array
        /// </exception>
        public async Task <FitResult> FitEquivalentCircuit(string cdc, double[] initialParameters = null, FitOptionsCircuit fitOptions = null, FitProgress fitProgress = null)
        {
            if (!IsFinished)
            {
                throw new Exception("Wait untill SimpleCurve is finished before fitting equivalent circuits");
            }
            if (_simpleMeasurement.Measurement.nEISdata == 0)
            {
                throw new Exception("No impedimetric readings available in parent SimpleMeasurement");
            }
            if (string.IsNullOrEmpty(cdc))
            {
                throw new ArgumentNullException("The circuit descriptor code (cdc) must be specified");
            }

            CircuitModel circuitModel = new CircuitModel();

            circuitModel.SetEISdata(_simpleMeasurement.Measurement.EISdata[0]); //Sets reference to measured data
            try
            {
                circuitModel.SetCircuit(cdc); //Sets the circuit defined in the CDC code string, in this case a Randles circuit
            }
            catch
            {
                throw new ArgumentException("Invalid circuit descriptor code (cdc)");
            }

            if (initialParameters != null)
            {
                if (circuitModel.InitialParameters.Count != initialParameters.Length)
                {
                    throw new ArgumentException("The amount of parameters in the model does not match the number of parameters specified in the initial parameter array");
                }
                circuitModel.SetInitialParameters(initialParameters);
            }

            return(await FitEquivalentCircuit(circuitModel, fitOptions, fitProgress));
        }
Example #11
0
        public ActionResult Details(string id)
        {
            if (id == null || id == "")
            {
                throw new HttpException(404, "The track " + id + " requested is not in the database.");
            }

            circuits r = db.circuits.Where(x => x.circuitRef == id).FirstOrDefault();

            if (r == null)
            {
                throw new HttpException(404, "The track " + id + " requested is not in the database.");
            }

            ViewBag.Title = r.name;

            CircuitModel model = new CircuitModel()
            {
                Circuit     = r,
                TrackRecord = Queries.GetTrackRecordCircuit(r.circuitId, db)
            };

            return(View(model));
        }
Example #12
0
        private TResult CallInternal <TResult>(MethodInfo methodInfo, Delegate method, params object[] args)
        {
            string methodKey = methodInfo.DeclaringType.FullName + "." + methodInfo.Name.Split('.').Last();

            var result = default(TResult);

            if (!Convert.ToBoolean(ConfigHelper.GetConfigValue <string>("MaintenanceMode")))
            {
                DateTime attemptStartedDateTime = DateTime.Now;
                var      model = GetCachedCircuit(methodKey);
                if (model == null)
                {
                    model = new CircuitModel(methodKey, methodInfo);
                    SetCachedCircuit(model);
                }

                switch (model.BreakStatus)
                {
                case CircuitModel.BreakStatusEnum.Closed:
                case CircuitModel.BreakStatusEnum.HalfOpen:
                    Stopwatch sw = Stopwatch.StartNew();

                    try
                    {
                        result = (TResult)method.DynamicInvoke(args);
                        sw.Stop();

                        if (sw.ElapsedMilliseconds > (model.Timeout * 1000))
                        {
                            //timeout

                            //get latest fresh model data from cache
                            model = GetCachedCircuit(methodKey) ?? new CircuitModel(methodKey, methodInfo);

                            UpdateCircuit(model, CircuitModel.FailureReasonEnum.Timeout, sw, attemptStartedDateTime);
                            if (model.LogLevel >= CircuitModel.LogLevelEnum.Timeouts)
                            {
                                LogCallDetails(method, args, model, default(TResult), sw);
                            }
                            SetCachedCircuit(model);
                        }
                        else
                        {
                            //everything went ok

                            //get latest fresh model data from cache
                            model = GetCachedCircuit(methodKey) ?? new CircuitModel(methodKey, methodInfo);

                            UpdateCircuit(model, CircuitModel.FailureReasonEnum.None, sw, attemptStartedDateTime);
                            if (model.LogLevel >= CircuitModel.LogLevelEnum.SuccessfulCalls)
                            {
                                LogCallDetails(method, args, model, result, sw);
                            }
                            SetCachedCircuit(model);
                        }
                    }
                    catch (Exception exception)
                    {
                        //exception thrown

                        //get latest fresh model data from cache
                        model = GetCachedCircuit(methodKey) ?? new CircuitModel(methodKey, methodInfo);

                        if (exception is TargetInvocationException)
                        {
                            if (exception.InnerException != null)
                            {
                                exception = exception.InnerException;
                            }
                        }

                        UpdateCircuit(model, CircuitModel.FailureReasonEnum.Exception, sw, attemptStartedDateTime);
                        if (model.LogLevel >= CircuitModel.LogLevelEnum.Errors)
                        {
                            LogExceptionDetails <TResult>(method, args, model, exception, sw);
                        }
                        SetCachedCircuit(model);

                        throw exception;
                    }

                    break;

                case CircuitModel.BreakStatusEnum.Open:
                    //open circuit

                    //get latest fresh model data from cache
                    model = GetCachedCircuit(methodKey) ?? new CircuitModel(methodKey, methodInfo);

                    UpdateCircuit(model, CircuitModel.FailureReasonEnum.OpenCircuit, Stopwatch.StartNew(), attemptStartedDateTime);

                    SetCachedCircuit(model);

                    if (model.BreakStatus != CircuitModel.BreakStatusEnum.Open)
                    {
                        result = CallInternal <TResult>(methodInfo, method, args);

                        if (model.BreakStatus != CircuitModel.BreakStatusEnum.Open)
                        {
                            model.ErrorCount++;
                        }
                        SetCachedCircuit(model);
                    }
                    else
                    {
                        if (model.LogLevel >= CircuitModel.LogLevelEnum.OpenCircuitFailures)
                        {
                            LogCallDetails(method, args, model, default(TResult));
                        }
                    }

                    break;

                default:
                    break;
                }
            }

            return(result);
        }
Example #13
0
 public void ClearCircuit(CircuitModel circuit)
 {
     ClearCircuit(circuit.MethodKey);
 }