public void Start(TimeSpan lockExpiry, CancellationToken cancellationToken) { if (_pipeInfos != null) { throw new ApplicationException("Reader instance already started"); } _pipeInfos = new BlockingCollection <PipeInfo>(); _taskFunnel.ListenForPipeEvents(/*_taskExecutors.Keys, */ _pipeInfos); ExecuteExisting(lockExpiry); Parallel.ForEach(_pipeInfos.GetConsumingPartitioner(cancellationToken), new ParallelOptions() { MaxDegreeOfParallelism = _maxThreads, CancellationToken = cancellationToken }, pipeInfo => { var taskExecutor = _taskExecutors[pipeInfo.ParentPipeName]; var messageBatch = _taskFunnel.TryReadMessageBatch(true, pipeInfo, lockExpiry, 2); ExecuteBatch(taskExecutor, pipeInfo, messageBatch); }); }
private static void SendReadAndRelease(IRedisTaskFunnel redisTaskFunnel, string parentPipeName, string childPipeName) { //send a message var messageBody = "body"; var sent = redisTaskFunnel.TrySendMessage(parentPipeName, childPipeName, messageBody, Int32.MaxValue, TimeSpan.FromMinutes(1)); sent.sent.Should().BeTrue(); //sent.clients.Should().BeFalse(); //read the batch var read = redisTaskFunnel.TryReadMessageBatch(true, PipeInfo.Create(parentPipeName, childPipeName), TimeSpan.FromSeconds(1), 1); read.Should().NotBeNull(); read.HoldingList.Should().NotBeNull(); read.RedisValues.Should().NotBeEmpty(); read.RedisValues.First().HasValue.Should().BeTrue(); var actualRedisPipeValue = read.RedisPipeValues.First(); actualRedisPipeValue.ValueString.Should().Be(messageBody); //try to release the lock without the wrong holdingListName var redisPipeValue = new RedisPipeValue(PipeInfo.Create(parentPipeName, childPipeName), "body", Guid.NewGuid().ToString(), true); var badExtend = redisTaskFunnel.RetainHoldingList(redisPipeValue, TimeSpan.FromSeconds(1)); badExtend.Should().BeFalse(); redisTaskFunnel.AfterExecute(redisPipeValue, true); //retain with the correct name var extended = redisTaskFunnel.RetainHoldingList(read, TimeSpan.FromSeconds(1)); extended.Should().BeTrue(); //complete the message and the batch redisTaskFunnel.AfterExecute(actualRedisPipeValue, true); redisTaskFunnel.AfterExecuteBatch(read); //now check the holding list doesn't exist any more. extended = redisTaskFunnel.RetainHoldingList(read, TimeSpan.FromSeconds(1)); extended.Should().BeFalse(); }