1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.query;
21
22 import java.util.Map;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.Executors;
25 import java.util.concurrent.ScheduledExecutorService;
26 import java.util.concurrent.TimeUnit;
27
28 import org.apache.mina.api.AbstractIoFilter;
29 import org.apache.mina.api.IoFuture;
30 import org.apache.mina.api.IoSession;
31 import org.apache.mina.filterchain.ReadFilterChainController;
32 import org.apache.mina.session.AttributeKey;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class RequestFilter<REQUEST extends Request, RESPONSE extends Response> extends AbstractIoFilter {
61
62
63
64
65
66
67
68
69
70
71 @SuppressWarnings({ "rawtypes", "unchecked" })
72 public IoFuture<RESPONSE> request(IoSession session, REQUEST request, long timeoutInMs) {
73 Map inFlight = session.getAttribute(IN_FLIGHT_REQUESTS);
74 RequestFuture<REQUEST, RESPONSE> future = new RequestFuture<REQUEST, RESPONSE>(session, request.requestId());
75
76
77 future.setTimeoutFuture(schedExec.schedule(future.timeout, timeoutInMs, TimeUnit.MILLISECONDS));
78
79
80 inFlight.put(request.requestId(), future);
81 session.write(request);
82 return future;
83 }
84
85 @SuppressWarnings("rawtypes")
86 static final AttributeKey<Map> IN_FLIGHT_REQUESTS = new AttributeKey<Map>(Map.class, "request.in.flight");
87
88 private ScheduledExecutorService schedExec = Executors.newScheduledThreadPool(1);
89
90 @SuppressWarnings("rawtypes")
91 @Override
92 public void sessionOpened(IoSession session) {
93 session.setAttribute(IN_FLIGHT_REQUESTS, new ConcurrentHashMap());
94 }
95
96 @SuppressWarnings("unchecked")
97 @Override
98 public void messageReceived(IoSession session, Object message, ReadFilterChainController controller) {
99 if (message instanceof Response) {
100 Object id = ((Response) message).requestId();
101 if (id != null) {
102
103 Map<?, ?> inFlight = session.getAttribute(IN_FLIGHT_REQUESTS);
104 RequestFuture<REQUEST, RESPONSE> future = (RequestFuture<REQUEST, RESPONSE>) inFlight.remove(id);
105 if (future != null) {
106 future.complete((RESPONSE) message);
107 }
108 }
109 }
110
111 super.messageReceived(session, message, controller);
112 }
113
114
115
116
117 @Override
118 public void sessionClosed(IoSession session) {
119 Map<?, ?> inFlight = session.getAttribute(IN_FLIGHT_REQUESTS);
120 for (Object v : inFlight.values()) {
121 ((RequestFuture<?, ?>) v).cancel(true);
122 }
123 }
124 }