/// <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)); }
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 } }
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--; } } } }
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; }
public void SetCachedCircuit(CircuitModel model) { if (model != null) { _cachingHelper.AddCacheItem(_circuitConfigElement, model, model.MethodKey); AppendToCircuitStatusHashTable(model.MethodKey); } }
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)); }
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); }
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)); }
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); }
/// <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)); }
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)); }
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); }
public void ClearCircuit(CircuitModel circuit) { ClearCircuit(circuit.MethodKey); }