/// <summary> /// Manage the StepContext lifecycle. Business processing should be /// delegated to <see cref="DoInChunkContext"/>. This /// is to ensure that the current thread has a reference to the context, even /// if the callback is executed in a pooled thread. Handles the registration /// and unregistration of the step context, so clients should not duplicate /// those calls. /// </summary> /// <param name="stepExecution"></param> /// <param name="doInChunkContext"></param> /// <returns></returns> public static RepeatCallback GetRepeatCallback(StepExecution stepExecution, DoInChunkContext doInChunkContext) { BlockingCollection <ChunkContext> attributeQueue = new BlockingCollection <ChunkContext>(); return(context => { // The StepContext has to be the same for all chunks, // otherwise step-scoped beans will be re-initialised for each chunk. StepContext stepContext = StepSynchronizationManager.Register(stepExecution); if (Logger.IsDebugEnabled) { Logger.Debug("Preparing chunk execution for StepContext: {0}", ObjectUtils.IdentityToString(stepContext)); } ChunkContext chunkContext; attributeQueue.TryTake(out chunkContext); if (chunkContext == null) { chunkContext = new ChunkContext(stepContext); } try { Logger.Debug("Chunk execution starting: queue size= {0}", attributeQueue.Count); return doInChunkContext(context, chunkContext); //Delegation } finally { // Still some stuff to do with the data in this chunk, // pass it back. if (!chunkContext.Complete) { attributeQueue.Add(chunkContext); } StepSynchronizationManager.Close(); } }); }
/// <summary> /// Manage the StepContext lifecycle. Business processing should be /// delegated to #DoInChunkContext(RepeatContext, ChunkContext). This /// is to ensure that the current thread has a reference to the context, even /// if the callback is executed in a pooled thread. Handles the registration /// and unregistration of the step context, so clients should not duplicate /// those calls. /// </summary> /// <param name="stepExecution"></param> /// <param name="doInChunkContext"></param> /// <returns></returns> public static RepeatCallback GetRepeatCallback(StepExecution stepExecution, DoInChunkContext doInChunkContext) { BlockingCollection<ChunkContext> attributeQueue = new BlockingCollection<ChunkContext>(); return context => { // The StepContext has to be the same for all chunks, // otherwise step-scoped beans will be re-initialised for each chunk. StepContext stepContext = StepSynchronizationManager.Register(stepExecution); if (Logger.IsDebugEnabled) { Logger.Debug("Preparing chunk execution for StepContext: {0}", ObjectUtils.IdentityToString(stepContext)); } ChunkContext chunkContext; attributeQueue.TryTake(out chunkContext); if (chunkContext == null) { chunkContext = new ChunkContext(stepContext); } try { Logger.Debug("Chunk execution starting: queue size= {0}", attributeQueue.Count); return doInChunkContext(context, chunkContext); //Delegation } finally { // Still some stuff to do with the data in this chunk, // pass it back. if (!chunkContext.Complete) { attributeQueue.Add(chunkContext); } StepSynchronizationManager.Close(); } }; }