
| Key: |
BATCH-378
|
| Type: |
Improvement
|
| Status: |
Closed
|
| Resolution: |
Fixed
|
| Priority: |
Major
|
| Assignee: |
Dave Syer
|
| Reporter: |
Lucas Ward
|
| Votes: |
0
|
| Watchers: |
0
|
|
If you were logged in you would be able to see more operations.
|
|
|
|
Time Tracking:
|
|
Original Estimate:
|
1d
|
|
|
Remaining Estimate:
|
1d
|
|
|
Time Spent:
|
Not Specified
|
|
|
|
|
Currently, the ItemOrientedStep can only be intercepted by using AOP (which can be applied around Step.execute, PlatformTransactionManager, and the reader and writer) or using RepeatListeners around one of the two RepeatTemplates in the step. I have two issues with this: 1) RepeatListener is too generic and 2) It causes confusion.
I don't mean to say that they're bad in general. If you look at the RepeatTemplates by themselves, they make a lot of sense, and are extremely useful. However, when they're used as the mechanism for intercepting the step execution, they cause issues. The problem is really because of how they're applied. Just for clarity, the interface is repeated below:
void before(RepeatContext context);
void after(RepeatContext context, ExitStatus result);
void open(RepeatContext context);
void onError(RepeatContext context, Throwable e);
void close(RepeatContext context);
My central problem is this: applying a RepeatListener at either the StepOperations has a completely different meaning from applying it at a ChunkOperations, which is confusing. For example, before and after on a RepeatListener in the stepOperations is exactly the same same as open and close on a RepeatListener on the chunkOperations, it all depends upon where you apply it. Furthermore, it has absolutely no domain meaning. If I was going to create a 'StepListener' interface that solved this problem it would have an interface like the one below:
void beforeChunk(RepeatContext context);
void afterChunk(RepeatContext context, ExitStatus result);
void beforeItem(RepeatContext context);
void afterItem(RepeatContext context, ExitStatus result);
void onError(RepeatContext context, Throwable e);
void close(RepeatContext context);
void open(RepeatContext context);
void onError(RepeatContext context, Throwable e);
//Returning ExitStatus would allow for modifying the status that's returned.
ExitStatus close(RepeatContext context);
You could potentially break this up into two interfaces if you want to (StepListener and ChunkListener), however, the effect would be the same regardless. it would have domain meaning (i.e. before chunk, after chunk) and there would be only one place to apply it, the step. I think this would go a long way towards making it easier to understand, while also solving a couple of other issues.
|
|
Description
|
Currently, the ItemOrientedStep can only be intercepted by using AOP (which can be applied around Step.execute, PlatformTransactionManager, and the reader and writer) or using RepeatListeners around one of the two RepeatTemplates in the step. I have two issues with this: 1) RepeatListener is too generic and 2) It causes confusion.
I don't mean to say that they're bad in general. If you look at the RepeatTemplates by themselves, they make a lot of sense, and are extremely useful. However, when they're used as the mechanism for intercepting the step execution, they cause issues. The problem is really because of how they're applied. Just for clarity, the interface is repeated below:
void before(RepeatContext context);
void after(RepeatContext context, ExitStatus result);
void open(RepeatContext context);
void onError(RepeatContext context, Throwable e);
void close(RepeatContext context);
My central problem is this: applying a RepeatListener at either the StepOperations has a completely different meaning from applying it at a ChunkOperations, which is confusing. For example, before and after on a RepeatListener in the stepOperations is exactly the same same as open and close on a RepeatListener on the chunkOperations, it all depends upon where you apply it. Furthermore, it has absolutely no domain meaning. If I was going to create a 'StepListener' interface that solved this problem it would have an interface like the one below:
void beforeChunk(RepeatContext context);
void afterChunk(RepeatContext context, ExitStatus result);
void beforeItem(RepeatContext context);
void afterItem(RepeatContext context, ExitStatus result);
void onError(RepeatContext context, Throwable e);
void close(RepeatContext context);
void open(RepeatContext context);
void onError(RepeatContext context, Throwable e);
//Returning ExitStatus would allow for modifying the status that's returned.
ExitStatus close(RepeatContext context);
You could potentially break this up into two interfaces if you want to (StepListener and ChunkListener), however, the effect would be the same regardless. it would have domain meaning (i.e. before chunk, after chunk) and there would be only one place to apply it, the step. I think this would go a long way towards making it easier to understand, while also solving a couple of other issues. |
Show » |
|
To that end, I say leave the listeners intact and add the two mentioned interfaces (the StepListener and ChunkListener) and potentially a third one that's item-related (e.g. ItemListener). For symmetry, I would also offer an AOP interceptor version (ala RepeatOperationsInterceptor) as an alternative which makes the behavior much more configurable and less programmatic, which is very Spring-y.