Results 1 to 8 of 8

Thread: Callback for multi-reply messages

  1. #1
    Join Date
    Jan 2012
    Posts
    6

    Default Callback for multi-reply messages

    hi,

    is there anyway to allow a message to generate multiple reply messages on the outbound channel? Basically something akin to a splitter, but that does not require the entire collection to be available for input to the splitter.

    simplistic example would be eg specifying a RowCallbackHandler instead of a RowMapper for returning results from eg a select query. The RowCallbackHandler would generate a reply message for each row, on the assumption that my result set is to big to keep in memory.

    possibly i'm missing a much easier way of handling this.

  2. #2

    Default

    I need to do something like this as well that involves "splitting" an InputStream. I need the "splitter" to continue to send replies until the stream is complete, and I don't know the full size of the stream upfront.

    While I haven't tried this yet, my thought was to inject the destination MessageChannel into my "splitter" service, and have my "splitter" send each "reply" as a new Message to that channel.

  3. #3
    Join Date
    Jan 2012
    Posts
    6

    Default

    yeah, looks like that can be done. i'm hoping to avoid writing my own implementation of a message handler if there is a more standard implementation/approach.

  4. #4
    Join Date
    Jan 2009
    Location
    Ukraine, Kharkov
    Posts
    644

    Default

    Hello, guys

    How about try to use Spring Batch ?

    Described by you scenarios beyond the scope of Spring Integration, because the last one is based on EIP.
    But it allows you to easily connect any other frameworks to develop any complex solution.

    Cheers,
    Artem Bilan

  5. #5

    Default

    @Artem -- the thing is the gap is very small and adding a whole new project like Spring Batch seems like overkill to solve the problem.

  6. #6
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,036

    Default

    The InputStream use case is easy.

    Simply use an <inbound-channel-adapter/>, set the poller to an unlimited messages-per-poll; the poller will keep calling the method and you can pull individual messages from the stream; when the stream is consumed, return null and the poller will sleep until the next trigger.

    For the original use case (one message becomes multiple messages), as long as you can use asynchronous threads, have the service activator invoke a method that has a void return and put the message in a BlockingQueue. Then, on the producer side, use an <inbound-channel-adapter/> to poll another method that reads from the queue; just like the InputStream case; the method invoked by the poller can return whatever you want.

    If you need it all to run on the same thread, it would be a little more difficult because, by definition (according to your requirements), you don't have all the data when you enter the service, but you could still do it by staging the data, return null until all the data is available and then send a collection of messages that can be split later.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  7. #7
    Join Date
    Jan 2012
    Posts
    6

    Default

    ok...the main goal is to avoid having the entire data set in memory all at once. typically it wouldn't be a problem, but there may be some edge cases where it is. if i want it all in one thread, will the suggestion of sending a message for each element to a channel (eg using a message template) work well, or are there some additional complexities i'm missing?

  8. #8
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,036

    Default

    Yes, that will work too.

    As @rgupta said, just inject the outbound MessageChannel object into your service and send() your messages to that. You only need to go to a MessagingTemplate if you want to use some of its more advanced features, such as message conversion etc.

    However, whenever possible, it is best practice to avoid adding any SI dependencies to your code; I would suggest using a <gateway/> instead, and inject the gateway into your service.

    Code:
    public interface MySender {
         void send(MyType type);
    }
    
    ...
    
    <int:gateway id="gw" service-interface="foo.MySender" default-request-channel="outChan" />
    Inject gw into your service and call gw.send() as many times as you want, for each message arriving at the service. Of course, if you need to copy headers from the input message to the output messages, you have no choice but to expose some SI dependencies in your class.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

Posting Permissions

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