خرید بک لینک

Vote count: 0

I'm attempting to implement a moderately complex TPL Dataflow pipeline with Railway Programming, where messages can get sent down the "happy path" if they succeed in the current block, or go to the failure block if they don't succeed. The problem I'm having is, completion keeps getting propagated unexpectedly. I don't have issues ruing locally, but ruing this on a VM causes issues.

Once the matcherBuffer is filled, I send a Completion to the matcher.

    private void CreatePipeline()
    {
        int blockCapacity;
        if(!Int32.TryParse(ConfigurationManager.AppSettings["TPLBlockCapacity"], out blockCapacity)){
            logger.WriteInformation("TPLBlockCapacity app.config value could not be properly parsed.  TPLBlockCapacity will default to 1000.");
            blockCapacity=1000;
        }
        var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
        var blockOptions = new ExecutionDataflowBlockOptions { BoundedCapacity = blockCapacity };
        matcher = new Matcher(secondarySource, logger);
        comparer = new Comparer(logger, report, fileSystem, dateTime);
        confirmer = new Confirmer(confirmationSource, logger, dateTime, report, fileSystem);
        changer = new Changer(logger, rioEmployeeEditor);
        unconfirmedWriter = new UnconfirmedWriter(logger, rioEmployeeEditor);
        failer = new Failer(logger, report, fileSystem, dateTime);
        finalizer = new Finalizer(logger, fileSystem, archiveFactory);


        var matchBuffer = new BufferBlock<IResult>(blockOptions);
        var matcherBlock = new TransformBlock<IResult, IResult>(result => matcher.Process(result));
        var failureBlock = new TransformBlock<IResult, IResult>(result => failer.Process(result));
        var comparerBlock = new TransformBlock<IResult, IResult>(result => comparer.Process(result));
        var confirmerBlock = new TransformBlock<IResult, IResult>(result => confirmer.Process(result));
        var confirmBroadcaster = new BroadcastBlock<IResult>(x => x.Clone());
        var unconfirmedBlock = new ActionBlock<IResult>(result => unconfirmedWriter.Process(result));
        var changerBlock = new TransformBlock<IResult, IResult>(result => changer.Process(result));
        var finalizerBlock = new ActionBlock<IResult>(result => finalizer.Process(result));
        //Message buffer from Selector links
        matchBuffer.LinkTo(matcherBlock, linkOptions, result => result.Success);
        //Matcher links
        matcherBlock.LinkTo(comparerBlock, linkOptions, result => result.Success);
        matcherBlock.LinkTo(failureBlock, result => !result.Success);
        //Comparer links

        comparerBlock.LinkTo(confirmerBlock, linkOptions, result => result.Success);
        comparerBlock.LinkTo(failureBlock, result => !result.Success);
        //Confirmer links

        confirmerBlock.LinkTo(confirmBroadcaster, linkOptions, result => result.Success);
        confirmerBlock.LinkTo(failureBlock, result => !result.Success);
        //ConfirmBroadcaster links
        confirmBroadcaster.LinkTo(changerBlock, result => result.Success);
        confirmBroadcaster.LinkTo(unconfirmedBlock, linkOptions, result => result.Success);

        changerBlock.LinkTo(finalizerBlock, linkOptions);
        failureBlock.LinkTo(finalizerBlock);

        unconfirmedBlock.Completion.ContinueWith(_ =>
        {
            Console.WriteLine("Unconfirmed Block Complete.");
            failureBlock.Complete();

        });
        failureBlock.Completion.ContinueWith(_ =>
        {
            Console.WriteLine("Failure Block Complete.");
            changerBlock.Complete();

        });
        Head = matchBuffer;
        Tail = finalizerBlock;
        ErrorBlock = failureBlock;
    }

Every scenario I can think of works fine locally, all blocks are able to make it through to finalizer and I get my expected results, but when I push to our VM, I get completely different behavior. The application ends prematurely and the finalizer doesn't even begin to execute. All of these blocks can take any amount of time to finish, but that doesn't seem to be an issue locally. I can put a Thread.Sleep in any of these blocks and it still performs as expected, but I still a premature closure on the VM.

asked 3 mins ago

برچسب: نویسنده: استخدام کار تاريخ: پنجشنبه 20 خرداد 1395 ساعت: 8:03

صفحه بندی