I have a sftp:inbound-channel-adapter
which synchronises files from a remote folder to a local folder. When it spots a file with a .xml extension it creates a Message<File>
and a new transaction and sends it to the routerChannel
channel.
The approverRouter
looks inside the xml and determines if the process may proceed. If all is good then the message is send to "okChannel" and off down to the database for saving. However if things are not ok then the message is send to int:delayer
for 10 seconds and resubmitted to the approverRouter
.
The sftpCommittedChannel
and sftpRolledBackChannel
just move the downloaded files to completed/failed folders if the transaction was successful or failed.
Here is some xml to describe this:
<int-sftp:inbound-channel-adapter id="..." channel="routerChannel" local-filter="localOnlyXmlFilter" ... >
<int:poller fixed-rate="10000" max-messages-per-poll="-1">
<int:transactional transaction-manager="transactionManager" synchronization-factory="syncFactory" />
</int:poller>
</int-sftp:inbound-channel-adapter>
<!-- Takes Message<Map> makes sure all files exist and are valid MD5 checked -->
<int:router input-channel="routerChannel" ref="approverRouter" method="resolveRoute"/>
<bean id="approverRouter" class="com.example.app.readers.ApproverRouter">
<property name="errorChannel" value="errorChannel"/>
<property name="retryChannel" value="myRetry"/>
<property name="okChannel" value="transformHashesToList"/>
<property name="timeout" value="${timout}"/>
</bean>
<int:delayer id="delayer" input-channel="myRetry" output-channel="routerChannel" default-delay="10000"/>
<int:transaction-synchronization-factory id="syncFactory">
<int:after-commit channel="sftpCommittedChannel"/>
<int:after-rollback channel="sftpRolledBackChannel"/>
</int:transaction-synchronization-factory>
My problem is that when the message is sent to the delayer the transaction created in the poller completes successfully. I think this is because when the message arrives at int:delayer
(via the retryChannel) it is no longer in the same original thread.
I suppose what I need is a synchronised delayer which adds a delay but keeps the message inside its original transaction. This feels like my design isn't right.
What do normal people do in order to create a retry delay and still tidy up the sftp folder on success or failure.
You can add a stateless request handler retry advice; the thread can be suspended based on the backoff settings.
See the documentation and spring-retry.