Results 1 to 8 of 8

Thread: Synchronous Error Handling

  1. #1
    Join Date
    Jul 2011
    Posts
    15

    Default Synchronous Error Handling

    I hava a doubt about synchronous - asynchronous messaging and error handling.

    I have a service that send a message to a channel that is connected to an SFTP Outbound Adapter. I have a try-catch around send call. In asynchronous mode the service always returns true after sending the message. In synchronous mode it waits until SFTP is ok or an exception is thrown and returns false in that case.

    I'd like to have the possibility to switch fast between synchronous messaging to asynchronous messaging so I have two channels and a bridge, a queue channel 1, a pub-sub channel 2 and a bridge between them. If I want synchronous messaging I send to the channel 2 directly. If I want asyncronous messaging I send to the channel 1.

    In the errorChannel I receive all errors and perform some logging and process. The problem is that in asynchronous mode, the exception in the SFTP call is sent to the errorChannel, but in synchronous mode, the exception flows directly to the caller and I need to repeat the logging an process logic in the catch block. If I remove the try-catch arount the send call, in synchronous mode the exception is then sent to the errorChannel but the caller never returns and I can't return a false in the service.

    I'd like to pass all errors to the error channel but also return to the caller after, in case of synchronous call to return a false in my service. żIs it possible to do this? I'd like my service to be transparent regarding sync or async, only configuration changes.

    Thank you for your help in advance.

  2. #2
    Join Date
    Jun 2011
    Posts
    25

    Default

    Any chance you could put up the config and the code for the service activator to give us a head start in recreating?
    Thanks

  3. #3
    Join Date
    Jul 2011
    Posts
    15

    Default

    Thats a summarize of the code

    The spring integration config regarding this case

    Code:
    [...]
    <channel id="channel1">
    	<queue capacity="1000"/>
    </channel>
    <publish-subscribe-channel id="channel2" />
    						   
    <bridge input-channel="channel1"
      	   output-channel="channel2">	
    	<poller max-messages-per-poll="16" fixed-rate="10000"/>		
    </bridge>	
    
    <sftp:outbound-channel-adapter channel="channel2" 
    	session-factory="sftpSessionFactory" 
    	remote-directory="${sftp.dir}"
    	temporary-file-suffix="uploading"/>
    
    <service-activator input-channel="errorChannel"
    		          output-channel="nullChannel" 
    			   ref="myServiceActivator" 
    		           method="handleError"/>
    [...]
    MyService

    Code:
    public class MyServiceImpl {
    
       @Autowired
       @Qualifier("channel1") // or "channel2"
        private MessageChannel sftpChannel;
    
        public boolean uploadFile(String filename) {
    		try {
    			sftpChannel.send(MessageBuilder.withPayload(filename)).build());	
    			return true;
    		} catch (Exception e) {
    			return false;
    		}
        }
    }
    MyServiceActivator

    Code:
    public class MyServiceActivator {
    
        public void handleError(MessagingException e) {
                // Logging and process
    
        }
    }
    Thanks

  4. #4
    Join Date
    Jan 2008
    Location
    Mohnton, PA USA (that's near Philadelphia)
    Posts
    2,148

    Default

    In all cases the exception always goes back to the caller. The real question is who is the caller? When a user invokes synchronous operation he/she is the caller, but in the async case the newly allocated thread is the caller. The initial call from the user was returned right away after it was delegated to this new thread (new caller). So in other words in the sync case you have complete control of the invocation and as you pointed out you can surround it with a try/catch block. However in the async case the try/catch block is meaningless (as you said), so the errorChannel is just a way to plug your catch block if you need too.
    That said, you can easily accomplish all you want by fronting your flow with MessagingGateway which has an error-channel attribute.
    Code:
    <int:gateway . . . error-channel="myErrorChannel"/>
    For more on gateways please read this http://static.springsource.org/sprin...ingle/#gateway

  5. #5
    Join Date
    Jun 2011
    Posts
    25

    Default

    The xsd specifies that the session-factory should be of type org.springframework.integration.sftp.session.SftpS essionFactory.
    I can only see an implementation called org.springframework.integration.sftp.session.Defau ltSftpSessionFactory
    Looking in the history it was interfaced and renamed as such.

  6. #6
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,853

    Default

    @dnlegge the XSD should specify this interface: org.springframework.integration.file.remote.sessio n.SessionFactory
    That is what DefaultSftpSessionFactory implements (after some refactoring). Could you please open a JIRA issue for that change?

    Thanks,
    Mark

  7. #7
    Join Date
    Jun 2011
    Posts
    25

    Default

    @occus3 out of interest, what version of SI are you using? I have had a couple of problems with your config snippet in the latest (2.0.5)

  8. #8
    Join Date
    Jul 2011
    Posts
    15

    Default

    Hi,

    I'm using 2.0.4, I really didn't know there was a new release.

    Thank you all for your help. I think the gateway will be the best solution. As oleg said, in synchronous mode the exception always flow to the caller. I didn't realize that my service (uploadFile) is called from a service activator that is called from a pollable channel, so if I remove the try/catch, the exception will go to the errorChannel because nobody handle this exception until it reaches the "asynchronous" flow with the pollable channel.

    Thanks.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •