public virtual void Publish(IExperimentResult <TPublish> results) { if (Publisher != null) { Publisher.Publish(results); } }
public void Publish <T>(IExperimentResult <T> results) { // How can we Unit Test this? Could do integration test but would be overkill using (var udp = new StatsdUDP(hostName, port)) { var statsd = new Statsd(udp, prefix); AddObservationStats(results.Name, results.Control, statsd); foreach (var kvp in results.Candidates) { AddObservationStats(results.Name, kvp.Value, statsd); } statsd.Send(); } }
public virtual void Publish <T>(IExperimentResult <T> results) { Console.WriteLine("*************** Experiment '{0}' Results ***************", results.Name); PublishObservation(results.Control); foreach (var obs in results.Candidates) { PublishObservation(obs.Value); } Console.WriteLine(messages.ToString()); var stars = new StringBuilder(); for (int i = 0; i < results.Name.Length; i++) { stars.Append('*'); } Console.WriteLine("*****************************************************" + stars.ToString()); messages.Clear(); }
private void TryPublish(IExperimentResult <TPublish> results) { CurrentState.CurrentStep = Operations.Publish; TryOp(() => { Publish(results); return(0); }); }
private T RunControl(IExperimentResult <TPublish> results, out Exception controlException) { controlException = null; CurrentState.Name = ControlName; CurrentState.CurrentStep = Operations.Control; if (Steps.Control == null) { // Can there be valid experiments with no Control?? Dunno but seems restrictive to enfore it // if so, return default(T) instead of Exception return(default(T)); // Throw exception if we want to enforce having a Control //throw new InvalidOperationException( // "The Control was never set for this Experiment! Can't run an Experiment without a Control!"); } IExperimentError stepError = null; object context = null; T result = default(T); TPublish value = default(TPublish); try { context = TrySetContext(); CurrentState.Context = context; } catch (StepFailedException sfe) { stepError = sfe.ExperimentError; TryOnError(stepError); } try { TrySetup(); } catch (StepFailedException sfe) { stepError = sfe.ExperimentError; TryOnError(stepError); } var timer = new Stopwatch(); CurrentState.CurrentStep = Operations.Control; try { timer.Start(); result = Steps.Control(); timer.Stop(); } catch (Exception e) { timer.Stop(); controlException = e; //need to throw this at the end var error = new ExperimentError { LastException = e, LastStep = Operations.Control, ErrorMessage = "An Exception was thrown running the Control! Exception message: " + e.Message, ExperimentName = ControlName }; TryOnError(error);//TODO: Should we run OnError on Control?? results.Control = new Observation <TPublish> { ExperimentError = error, ElapsedMilliseconds = timer.ElapsedMilliseconds, Context = context, Name = ControlName, IsMismatched = false, ExceptionThrown = true }; return(result); } try { value = TryPrepare(result); } catch (StepFailedException sfe) { stepError = sfe.ExperimentError; TryOnError(stepError); //We must continue on because we've already gotten a result } try { TryTeardown(); } catch (StepFailedException sfe) { stepError = sfe.ExperimentError; TryOnError(stepError); } results.Control = new Observation <TPublish> { ElapsedMilliseconds = timer.ElapsedMilliseconds, Context = context, Name = ControlName, IsMismatched = false, //Control can't be mismatched ExceptionThrown = stepError != null, ExperimentError = stepError, Value = value }; return(result); }
private bool RunCandidates(IExperimentResult <TPublish> results, T controlResult, Exception controlException) { bool ran = false; var candidates = Steps.GetCandidates(); if (candidates != null) { var timer = new Stopwatch(); foreach (var candidate in candidates) { T candResult = default(T); TPublish candValue = default(TPublish); bool mismatched = false; try { //Should this be a State machine? CurrentState.Name = candidate.Key; if (TryPreCondition() && candidate.Value != null) { ran = true; var context = TrySetContext(); CurrentState.Context = context; TrySetup(); timer.Restart(); candResult = TryCandidate(candidate.Value); timer.Stop(); if (!TryIgnore(controlResult, candResult) && (controlException != null || !TryAreEqual(controlResult, candResult))) { mismatched = true; TryOnMismatch(controlResult, candResult, controlException, null); } candValue = TryPrepare(candResult); TryTeardown(); if (!results.Candidates.ContainsKey(candidate.Key)) { results.Candidates.Add(candidate.Key, new Observation <TPublish> { Value = candValue, ElapsedMilliseconds = timer.ElapsedMilliseconds, ElapsedTime = timer.Elapsed, Context = context, IsMismatched = mismatched, ExceptionThrown = false, Name = candidate.Key }); } else { //Duplicate keys... should not be possible } } } catch (StepFailedException sfe) { timer.Stop(); //it's possible for this to throw, which would result in an internal exception TryOnError(sfe.ExperimentError); if (!exceptionComparer.Equals(sfe.ExperimentError.LastException, controlException)) { //It's a mismatch if the exceptions don't match mismatched = true; TryOnMismatch(controlResult, candResult, controlException, sfe.ExperimentError.LastException); //potential throw } var errResult = new Observation <TPublish> { ExperimentError = sfe.ExperimentError, Value = candValue, ElapsedMilliseconds = timer.ElapsedMilliseconds, ExceptionThrown = true, Name = candidate.Key, IsMismatched = mismatched }; if (results.Candidates.ContainsKey(results.LastState.Name)) { results.Candidates[results.LastState.Name] = errResult; } else { results.Candidates.Add(results.LastState.Name, errResult); } } } } return(ran); }