public void SingleTaskWithActionsShouldWorksWell() { // GIVEN mLogs.Logs.Clear(); var injectionProvider = new IoCContainer(); injectionProvider.Register <TestMultiplicatorStep>(); Contracts.Dependencies.Injection.RegisterInjectionProvider(injectionProvider, false); PipelineBlueprint blueprint = PipelineBlueprint.CreateBlueprint(typeof(int), "SingleApply"); PipelineBlueprint blueprintOther = PipelineBlueprint.CreateBlueprint(typeof(int), "DoubleApply"); // WHEN TransferingContext tctx = new TransferingContext(new Headers { { "factor", 10 } }.Dict); new Pipeline(blueprint .Apply <TestMultiplicatorStep>("multiplyby2") .Apply <TestMultiplicatorStep>("sync_mbf")) .Process(tctx, 1).Wait(); TransferingContext otherTctx = new TransferingContext(new Headers { { "factor", 10 } }.Dict); new Pipeline(blueprintOther .Apply <TestMultiplicatorStep>("sync_mbf") .Apply <TestMultiplicatorStep>("multiplyby2") .Apply <TestMultiplicatorStep>("sync_mbf")) .Process(otherTctx, 1).Wait(); // THAN tctx.GetResult <int>().Should().Be(20); otherTctx.GetResult <int>().Should().Be(200); }
public void SplitShouldWorksWell() { // GIVEN mLogs.Logs.Clear(); var intSource = new List <int> { 2, 4, 6 }; var injectionProvider = new IoCContainer(); injectionProvider.RegisterSingle(intSource); JustConveyor.Contracts.Dependencies.Injection.RegisterInjectionProvider(injectionProvider); var blueprint = PipelineBlueprint.CreateBlueprint(typeof(int), "IntMultiplicatorBlueprint") .Split <TestIntSource>() .Apply <TestMultiplicatorStep>("multiplybyfactor") .Collect() .Apply((List <UnitContext> unit) => unit.Select(el => el.GetUnit <int>()).ToList()); // WHEN Pipeline pipeline = new Pipeline(blueprint); TransferingContext tctx = new TransferingContext(new Headers { { "factor", 10 } }.Dict); pipeline.Process(tctx, 1).Wait(); List <int> result = tctx.GetResult <List <int> >(); // THAN result.ShouldBeEquivalentTo(new List <int> { 20, 40, 60 }); }
public void ExceptionShouldBeProcessedWithErrorProcessor() { // GIVEN var injectionProvider = new IoCContainer(); var step = new TestIntSource(new List <int> { 101 }); injectionProvider.RegisterSingle(step); JustConveyor.Contracts.Dependencies.Injection.RegisterInjectionProvider(injectionProvider, false); // WHEN TransferingContext tctx = new TransferingContext(); new Pipeline(PipelineBlueprint.CreateBlueprint <int>("WithExceptionBlueprint") .Split <TestIntSource>() .Collect()) .Process(tctx, 1).Wait(); //// THAN tctx.Exception.Should().NotBeNull(); step.ExceptionMessage.Should().Be("More than 100."); tctx.FinalUnitContext.Should().BeNull(); }
private static List <object> PrepareParameters(ProcessingElement current, UnitContext octx, TransferingContext tctx) { List <object> parameters = new List <object>(); if (current.Method != null) { // TODO memoize me // TODO inject headers foreach (var parameterInfo in current.Method.GetParameters()) { if (parameterInfo.ParameterType.IsAssignableFrom(octx.GetUnitType())) { parameters.Add(octx.Unit); } else if (parameterInfo.ParameterType == typeof(TransferingContext)) { parameters.Add(tctx); } else if (parameterInfo.ParameterType == typeof(UnitContext)) { parameters.Add(octx); } else { throw new ParameterTypeMissmatchException(current.Carrier, current.Method.Name, octx.GetUnitType(), parameterInfo.ParameterType); } } } return(parameters); }
public void Finalization(Package package, TransferingContext context) { if (FinalizationPredicate(package, context)) { mSyncEvent.Set(); try { mThen?.Invoke(); } catch (Exception e) { Injection.InjectionProvider?.Get <ILogger>()?.Error($"Error during finalization: {e}"); } } }
public async Task Process(TransferingContext tctx, object seed, string unitId = "", string operationId = "", Headers headers = null) { tctx.Set("pipelineid", Id); try { var octx = new UnitContext(string.IsNullOrEmpty(operationId) ? Guid.NewGuid().ToString("n") : operationId, unitId, seed, headers?.Dict); await mAction(tctx, octx); } catch (Exception e) { tctx.Exception = e; } }
public void SingleTaskShouldWorksWell() { // GIVEN mLogs.Logs.Clear(); var injectionProvider = new IoCContainer(); injectionProvider.Register <TestMultiplicatorStep>(); Contracts.Dependencies.Injection.RegisterInjectionProvider(injectionProvider, false); PipelineBlueprint blueprint = PipelineBlueprint.CreateBlueprint(typeof(int), "SingleApply"); // WHEN TransferingContext tctx = new TransferingContext(); new Pipeline(blueprint.Apply <TestMultiplicatorStep>("multiplyby2")) .Process(tctx, 1).Wait(); // THAN tctx.GetResult <int>().Should().Be(2); }
public void OnIncorrectParameterTypeExceptionShouldReturns() { // GIVEN mLogs.Logs.Clear(); var injectionProvider = new IoCContainer(); injectionProvider.Register <TestMultiplicatorStep>(); Contracts.Dependencies.Injection.RegisterInjectionProvider(injectionProvider, false); PipelineBlueprint blueprint = PipelineBlueprint.CreateBlueprint(typeof(int), "SingleApply"); // WHEN TransferingContext tctx = new TransferingContext(); new Pipeline(blueprint .Apply((string str) => str)) .Process(tctx, 1).Wait(); // THAN tctx.Exception.Should().NotBeNull(); tctx.Exception.InnerException.Should().NotBeNull(); tctx.Exception.InnerException.GetType().Should().Be(typeof(ParameterTypeMissmatchException)); }
private static Exception ProcessException(ProcessingElement current, TransferingContext tctx, Exception exception, UnitContext octx, object obj, bool exceptionAllowed = false) { if (current?.ErrorProcessorMethod == null) { return(exception); } octx.Exception = exception; var errParams = new List <object>(); foreach (var param in current.ErrorProcessorMethod.GetParameters()) { if (param.ParameterType == typeof(Exception)) { errParams.Add(exception); } if (param.ParameterType == typeof(UnitContext)) { errParams.Add(octx); } if (param.ParameterType == typeof(TransferingContext)) { errParams.Add(tctx); } } try { var result = (bool)current.ErrorProcessorMethod.Invoke(obj, errParams.ToArray()) && exceptionAllowed; return(!result ? exception : null); } catch (Exception errorProcessingException) { var exceptions = new AggregateException(exception, errorProcessingException); tctx.Exception = exceptions; return(exceptions); } }
public void SyncSpitCollectShouldWorksWell() { // GIVEN mLogs.Logs.Clear(); var ints = new List <int> { 1, 2, 3 }; var injectionProvider = new IoCContainer(); injectionProvider.RegisterSingle(ints); injectionProvider.Register <TestIntSource>(); injectionProvider.Register <TestMultiplicatorStep>(); Contracts.Dependencies.Injection.RegisterInjectionProvider(injectionProvider, false); PipelineBlueprint blueprint = PipelineBlueprint.CreateBlueprint(typeof(int), "SyncSplitCollect"); // WHEN var result = blueprint .Split <TestIntSource>() .Apply((int el) => el * 10) .Collect() .Apply((IList <UnitContext> octx) => octx.Select(el => el.GetUnit <int>())); TransferingContext tctx = new TransferingContext(); new Pipeline(result) .Process(tctx, 1) .Wait(); // THAN tctx.Exception.Should().BeNull(); tctx.GetResult <IEnumerable <int> >().ShouldBeEquivalentTo(new List <int> { 10, 20, 30 }); }
public int Process(TransferingContext tctx, int number) { return(number * tctx.Get <int>("factor")); }
public async Task <int> ProcessAsync(TransferingContext tctx, int number) { await Task.Yield(); return(number * tctx.Get <int>("factor")); }
private async Task RunPipeline(PipelineInstance instance) { await Task.Yield(); RunningPipelines.Add(instance); mLogger?.Trace($"Processing line id:{instance.Id} started for blueprint '{instance.Name}'"); instance.State = "Initialized"; Package package = await instance.Blueprint.QueueProvider.ReceiveNextMessageAsync(); while (package != null) { if (package == Package.Fake) { mLogger?.Trace($"line:{instance.Id} | Cool down before next attempt to get next package."); await mWaitEvent.WaitAsync(); } else { package.Profile.Dequeued = DateTime.Now; instance.Blueprint.Counters.IncrementIn(); mLogger?.Trace($"line:{instance.Id} | Incomming package with id:{package.Id}."); instance.State = "Processing"; var transferingContext = new TransferingContext { Id = $"{package.Id}:{instance.Id}:{Guid.NewGuid().ToString("n")}", ProcessingStart = DateTime.Now }; transferingContext.Meta.Add("ID", transferingContext.Id); transferingContext.Meta.Add("Package label", package.Label); transferingContext.Meta.Add("Package ID", package.Id); try { if (!RunningContextes.TryAdd(transferingContext.Id, transferingContext)) { mLogger?.Warn($"Unable to register transfering context with id:{transferingContext.Id}"); } await instance.Blueprint.Pipeline.Process(transferingContext, package.Load, package.Id, Guid.NewGuid().ToString("n"), new Headers(package.Headers)); if (transferingContext.Exception != null) { instance.Blueprint.Counters.Errors++; mLogger?.Error( $"Exception occured during processing on line id:{instance.Id}. Exception: {transferingContext.Exception}"); } if (package.ExternalDeliverBoxId != null) { mWaitBoxes[package.ExternalDeliverBoxId.Value].SetValue( transferingContext.FinalUnitContext.Unit, transferingContext.Exception); } } catch (Exception e) { instance.Blueprint.Counters.Errors++; if (package.ExternalDeliverBoxId != null) { mWaitBoxes[package.ExternalDeliverBoxId.Value].SetValue(null, e); } } finally { ProcessingInfo info = new ProcessingInfo { StepName = "FINALIZATION", Started = DateTime.Now }; transferingContext.ProcessingHistory.Push(info); foreach (var finalizer in instance.Blueprint.Finalizers) { try { finalizer(package, transferingContext); } catch (Exception ex) { mLogger?.Error( $"Error occured during finalizing package with id:{package.Id}. Exception: {ex}"); } } info.Finished = DateTime.Now; if (!RunningContextes.TryRemove(transferingContext.Id, out transferingContext)) { mLogger?.Warn($"Unable to unregister transfering context with id:{transferingContext.Id}"); } instance.Blueprint.Counters.IncrementOut(); package.Profile.ProcessFinished = DateTime.Now; instance.PackagesProfiles.Push(package.Profile); package.Profile = null; } } instance.State = "WaitForMessage"; mLogger?.Trace($"line:{instance.Id} | Wait for package."); package = await instance.Blueprint.QueueProvider.ReceiveNextMessageAsync(); } instance.State = "Finished"; mLogger?.Trace($"Processing line id:{instance.Id} finished for blueprint '{instance.Name}'"); }
public void AsyncSpitCollectShouldWorksWell() { // GIVEN mLogs.Logs.Clear(); var ints = new List <int> { 1, 2, 3 }; var injectionProvider = new IoCContainer(); injectionProvider.RegisterSingle(ints); injectionProvider.Register <TestIntSource>(); injectionProvider.Register <TestMultiplicatorStep>(); Contracts.Dependencies.Injection.RegisterInjectionProvider(injectionProvider, false); PipelineBlueprint blueprint = PipelineBlueprint.CreateBlueprint(typeof(int), "AsyncSplitCollect"); PipelineBlueprint blueprintOther = PipelineBlueprint.CreateBlueprint(typeof(int), "OtherAsyncSplitCollect"); PipelineBlueprint blueprintOneOther = PipelineBlueprint.CreateBlueprint(typeof(int), "OneOtherAsyncSplitCollect"); // WHEN TransferingContext tctx = new TransferingContext(new Headers { { "factor", 10 } }.Dict); new Pipeline(blueprint .Split <TestIntSource>() .Apply <TestMultiplicatorStep>("multiplybyfactor") .Collect() .Apply((IList <UnitContext> octx) => octx.Select(el => el.GetUnit <int>()).ToList())) .Process(tctx, 1) .Wait(); TransferingContext otherTctx = new TransferingContext(new Headers { { "factor", 10 } }.Dict); new Pipeline(blueprintOther .Split <TestIntSource>() .Apply <TestMultiplicatorStep>("multiplybyfactor") .Collect() .Apply <TestMultiplicatorStep>("strip")) .Process(otherTctx, 1) .Wait(); TransferingContext oneAnotherTctx = new TransferingContext(new Headers { { "factor", 10 } }.Dict); new Pipeline(blueprintOneOther .Apply <TestMultiplicatorStep>("multiplybyfactor") .Split <TestIntSource>() .Apply <TestMultiplicatorStep>("multiplybyfactor") .Collect() .Apply <TestMultiplicatorStep>("strip")) .Process(oneAnotherTctx, 1) .Wait(); // THAN tctx.Exception?.InnerException.Should().BeNull(); tctx.GetResult <List <int> >().ShouldBeEquivalentTo(new List <int> { 10, 20, 30 }); otherTctx.Exception?.InnerException.Should().BeNull(); otherTctx.GetResult <List <int> >().ShouldBeEquivalentTo(new List <int> { 10, 20, 30 }); oneAnotherTctx.Exception?.InnerException.Should().BeNull(); oneAnotherTctx.GetResult <List <int> >().ShouldBeEquivalentTo(new List <int> { 10, 20, 30 }); }