Issue Details (XML | Word | Printable)

Key: DIRMINA-92
Type: New Feature New Feature
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Trustin Lee
Reporter: Trustin Lee
Votes: 3
Watchers: 5
Operations

If you were logged in you would be able to see more operations.
MINA

Utility classes for asynchronous request-response protocols.

Created: 22/Sep/05 12:30 PM   Updated: 26/May/09 02:47 PM
Return to search
Component/s: None
Affects Version/s: 0.7.0
Fix Version/s: 2.0.0-M1

Time Tracking:
Not Specified

File Attachments:
  Size
Zip Archive Licensed for inclusion in ASF works Protocol.zip 2005-09-22 12:31 PM Trustin Lee 113 kB
Zip Archive Licensed for inclusion in ASF works queryreply.zip 2006-08-16 08:29 AM Julien Vermillard 2 kB
Zip Archive Licensed for inclusion in ASF works requestResponse.zip 2005-12-28 03:42 AM Johannes Zillmann 5 kB

Resolution Date: 12/Apr/07 09:15 AM


 Description  « Hide
There are so many existing asynchronous protocols whose messages have request-response structure. A request message usually has a message ID, and the corresponding response message, which makes a pair, contains the message ID in the request message.

It would be great if we can provide a common interface and classes to help users implement this type of protocols easily.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Trustin Lee added a comment - 22/Sep/05 12:31 PM
This attachment (Protocol.zip) is the contribution from Thomas Muller. We have to review it and create our one.

Trustin Lee made changes - 22/Sep/05 12:31 PM
Field Original Value New Value
Attachment Protocol.zip [ 12314492 ]
Trustin Lee added a comment - 17/Oct/05 07:00 PM
His implementation is very impressive and provides a lot of features, but it seems like it is designed to be very specific to a specific protocol and management environment IMHO.

Here's my implementation plan:
* RequestMessage which has a method 'getMessageId()' which returns an Object. The messageId type will have to implement equals and hashCode methods properly.
* ResponseMessage which has a method 'getRequestMessageId()' which returns an Object. The constraint is same with that of RequestMessage.
* RequestResponseProtocolFilter that remembers sent RequestMessages and fires an 'exceptionCaught' event with an appropriate 'RequestTimeoutException' to ProtocolHandler if the ResponseMessage is not arriving for certain specified time.

WDYT?



Trustin Lee made changes - 17/Oct/05 07:09 PM
Status Open [ 1 ] In Progress [ 3 ]
Trustin Lee made changes - 18/Oct/05 12:27 AM
Fix Version/s 0.8 [ 11068 ]
Fix Version/s 0.9.1 [ 12310371 ]
Johannes Zillmann added a comment - 28/Dec/05 03:42 AM
I have attached a zip with some classes for a 'synchronious' request-response model. May out of topic, may it help...
The solution only wokrs with object serialization i guess.

Johannes Zillmann made changes - 28/Dec/05 03:42 AM
Attachment requestResponse.zip [ 12321570 ]
Trustin Lee made changes - 23/Jan/06 12:14 PM
Fix Version/s 0.9.1 [ 12310371 ]
Julien Vermillard added a comment - 16/Aug/06 08:29 AM
attached queryreply.zip, the filter based on trustin ideas I use in my apps. WDYT ? I whould like to have comments before finishing it and integrate it in MINA.

Julien

Julien Vermillard made changes - 16/Aug/06 08:29 AM
Attachment queryreply.zip [ 12338944 ]
Julien Vermillard added a comment - 17/Aug/06 03:40 PM
a good idea whould be to add a "request without reply" counter, for detect dead connection.


Klaus Stake added a comment - 09/Nov/06 07:32 AM
Hi Julien,

I tried to use the stuff in queryreply.zip. How should I use the classes? I did the following:
- ... chain.addFirst( "queryReply", new RequestResponseFilter(new BasicRequestFactory(10000))); //timeout == 10 secs

... and then what to do? I guess that I must call the RequestResponseFilter's query() method somewhere. I did that in my customized IoHandler for sending a message. The problem is that the query method blocks the application because of the following line in the query method:
...
                try {
                    lastRequest.wait(lastRequest.getResponseTimeout());
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
...

Mina does not send the message after the set response timeout. I set the response timeout to 10000 (10 secs) and the application blocks for 10 seconds

Do you have a test case for your RequestResponseFilter? Did I do something wrong?

Another comment on RequestImpl's getReplyMessage(): it should be renamed to getResponseMessage according to the method setResponseMessage()

Klaus

Repository Revision Date User Message
ASF #527836 Thu Apr 12 08:40:51 UTC 2007 trustin Resolved issue: DIRMINA-92 (Utility classes for asynchronous request-response protocols.)
* Added org.apache.mina.filter.reqres package
* Fixed a trivial bug in StreamWriteFilterTest
Files Changed
ADD /mina/trunk/core/src/main/java/org/apache/mina/filter/reqres/ResponseInspector.java
ADD /mina/trunk/core/src/test/java/org/apache/mina/filter/reqres
MODIFY /mina/trunk/core/src/test/java/org/apache/mina/filter/StreamWriteFilterTest.java
ADD /mina/trunk/core/src/test/java/org/apache/mina/filter/reqres/RequestResponseFilterTest.java
ADD /mina/trunk/core/src/main/java/org/apache/mina/filter/reqres/Request.java
ADD /mina/trunk/core/src/main/java/org/apache/mina/filter/reqres/RequestTimeoutException.java
ADD /mina/trunk/core/src/main/java/org/apache/mina/filter/reqres/Response.java
ADD /mina/trunk/core/src/main/java/org/apache/mina/filter/reqres
ADD /mina/trunk/core/src/main/java/org/apache/mina/filter/reqres/RequestResponseFilter.java
ADD /mina/trunk/core/src/main/java/org/apache/mina/filter/reqres/ResponseType.java

Trustin Lee added a comment - 12/Apr/07 09:15 AM
This feature has been implemented finally. Please refer to the following ViewVC page to browse the source code.

http://tinyurl.com/3ahxg6

I didn't write the JavaDoc and the tutorial yet (I will do soon). Meanwhile, the following step-by-step example will help you understand how to use the RequestResponseFilter.

0) Scenario: A client sends a MyRequest message with a certain ID, then the server will respond with MyResponse message with the same ID, to identify that the response message related to the request message with the same ID.

1) Implement ResponseInspector.

    public class MyResponseInspector implements ResponseInspector {
        public Object getRequestId(Object message) {
            if (!(message instanceof MyResponse)) {
                 return null;
            }

            MyResponse response = (MyResponse) message;
            return response.getId();
        }

        public ResponseType getResponseType(Object message) {
            // You can return PARTIAL or PARTIAL_LAST if the protocol has multiple responses per request.
            return ResponseType.WHOLE;
        }
    }

2) Insert the RequestResponseFilter.

    connector.getFilterChain().addLast(
            "reqres", new RequestResponseFilter(new MyResponseInspector()));

3) Implement IoHandler.

    import org.apache.mina.filter.reqres.Request;
    import org.apache.mina.filter.reqres.Response;

    public class MyHandler extends IoHandlerAdapter {
        public void sessionOpened(IoSession session) throws Exception {
            MyRequest req = ...;
            // Send the request with 5 seconds timeout.
            session.write(new Request(req.getId(), req, 5, TimeUnit.SECONDS));
        }

        public void messageReceived(IoSession session, Object message) throws Exception {
            Response res = (Response) message;
            MyRequest req = res.getRequest().getMessage();
            MyResponse res = res.getMessage();
            // Do something with the messages.
            ......
        }

        public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
            if (cause instanceof RequestTimeoutException) {
                RequestTimeoutException rte = (RequestTimeoutException) cause;
                rte.getRequest();
                // Do something with the failed request.
                // RequestTimeoutException is thrown also when
                // a connection is closed but the related response is not received yet.
                ......
            }
        }
    }

Please give me feedback if the API doesn't make sense or needs improvement.

Trustin Lee made changes - 12/Apr/07 09:15 AM
Resolution Fixed [ 1 ]
Fix Version/s 2.0.0-M1 [ 12312171 ]
Status In Progress [ 3 ] Resolved [ 5 ]
Trustin Lee added a comment - 13/Apr/07 08:54 AM
Alternatively, you can use awaitResponse() method:

    Request req = ...;
    session.write(req);

    try {
        Response res = req.awaitResponse();
        // Do something the the response.
        ......
    } catch (RequestTimeoutException e) {
        ......
    }

Emmanuel Lecharny made changes - 26/May/09 02:47 PM
Status Resolved [ 5 ] Closed [ 6 ]