예제 #1
0
        public async Task <T> Run()
        {
            // Determine if experiments should be run.
            if (!await ShouldExperimentRun())
            {
                // Run the control behavior.
                return(await Behaviors[0].Behavior());
            }

            if (BeforeRun != null)
            {
                await BeforeRun();
            }

            // Randomize ordering...
            NamedBehavior[] orderedBehaviors;
            lock (_random)
            {
                orderedBehaviors = Behaviors.OrderBy(b => _random.Next()).ToArray();
            }

            var observations = new List <Observation <T> >();

            foreach (var behavior in orderedBehaviors)
            {
                observations.Add(await Observation <T> .New(behavior.Name, behavior.Behavior, Comparator, Thrown));
            }

            var controlObservation = observations.FirstOrDefault(o => o.Name == ControlExperimentName);

            var result = new Result <T>(this, observations, controlObservation, Contexts);

            try
            {
                // TODO: Make this Fire and forget so we don't have to wait for this
                // to complete before we return a result
                await Scientist.ResultPublisher.Publish(result);
            }
            catch (Exception ex)
            {
                Thrown(Operation.Publish, ex);
            }

            if (ThrowOnMismatches && result.Mismatched)
            {
                throw new MismatchException <T>(Name, result);
            }

            if (controlObservation.Thrown)
            {
                throw controlObservation.Exception;
            }
            return(controlObservation.Value);
        }
예제 #2
0
        public async Task <T> Run()
        {
            // Determine if experiments should be run.
            if (!await ShouldExperimentRun())
            {
                // Run the control behavior.
                return(await Behaviors[0].Behavior());
            }

            if (BeforeRun != null)
            {
                await BeforeRun();
            }

            // Randomize ordering...
            NamedBehavior[] orderedBehaviors;
            lock (_random)
            {
                orderedBehaviors = Behaviors.OrderBy(b => _random.Next()).ToArray();
            }

            // Break tasks into batches of "ConcurrentTasks" size
            var observations = new List <Observation <T, TClean> >();

            foreach (var behaviors in orderedBehaviors.Chunk(ConcurrentTasks))
            {
                // Run batch of behaviors simultaneously
                var tasks = behaviors.Select(b =>
                {
                    return(Observation <T, TClean> .New(
                               b.Name,
                               b.Behavior,
                               Comparator,
                               Thrown,
                               Cleaner));
                });

                // Collect the observations
                observations.AddRange(await Task.WhenAll(tasks));
            }

            var controlObservation = observations.FirstOrDefault(o => o.Name == ControlExperimentName);

            var result = new Result <T, TClean>(this, observations, controlObservation, Contexts);

            try
            {
                await Scientist.ResultPublisher.Publish(result);
            }
            catch (Exception ex)
            {
                Thrown(Operation.Publish, ex);
            }

            if (ThrowOnMismatches && result.Mismatched)
            {
                throw new MismatchException <T, TClean>(Name, result);
            }

            if (controlObservation.Thrown)
            {
                throw controlObservation.Exception;
            }
            return(controlObservation.Value);
        }