...
|
...
|
@@ -15,6 +15,8 @@ |
15
|
15
|
*/
|
16
|
16
|
package org.thingsboard.server.service.queue;
|
17
|
17
|
|
|
18
|
+import lombok.Getter;
|
|
19
|
+import lombok.Setter;
|
18
|
20
|
import lombok.extern.slf4j.Slf4j;
|
19
|
21
|
import org.springframework.beans.factory.annotation.Value;
|
20
|
22
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
...
|
...
|
@@ -76,6 +78,7 @@ import java.util.concurrent.ConcurrentMap; |
76
|
78
|
import java.util.concurrent.CountDownLatch;
|
77
|
79
|
import java.util.concurrent.ExecutorService;
|
78
|
80
|
import java.util.concurrent.Executors;
|
|
81
|
+import java.util.concurrent.Future;
|
79
|
82
|
import java.util.concurrent.TimeUnit;
|
80
|
83
|
import java.util.function.Function;
|
81
|
84
|
import java.util.stream.Collectors;
|
...
|
...
|
@@ -175,39 +178,48 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore |
175
|
178
|
CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
|
176
|
179
|
TbPackProcessingContext<TbProtoQueueMsg<ToCoreMsg>> ctx = new TbPackProcessingContext<>(
|
177
|
180
|
processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>());
|
178
|
|
- pendingMap.forEach((id, msg) -> {
|
179
|
|
- log.trace("[{}] Creating main callback for message: {}", id, msg.getValue());
|
180
|
|
- TbCallback callback = new TbPackCallback<>(id, ctx);
|
181
|
|
- try {
|
182
|
|
- ToCoreMsg toCoreMsg = msg.getValue();
|
183
|
|
- if (toCoreMsg.hasToSubscriptionMgrMsg()) {
|
184
|
|
- log.trace("[{}] Forwarding message to subscription manager service {}", id, toCoreMsg.getToSubscriptionMgrMsg());
|
185
|
|
- forwardToSubMgrService(toCoreMsg.getToSubscriptionMgrMsg(), callback);
|
186
|
|
- } else if (toCoreMsg.hasToDeviceActorMsg()) {
|
187
|
|
- log.trace("[{}] Forwarding message to device actor {}", id, toCoreMsg.getToDeviceActorMsg());
|
188
|
|
- forwardToDeviceActor(toCoreMsg.getToDeviceActorMsg(), callback);
|
189
|
|
- } else if (toCoreMsg.hasDeviceStateServiceMsg()) {
|
190
|
|
- log.trace("[{}] Forwarding message to state service {}", id, toCoreMsg.getDeviceStateServiceMsg());
|
191
|
|
- forwardToStateService(toCoreMsg.getDeviceStateServiceMsg(), callback);
|
192
|
|
- } else if (toCoreMsg.getToDeviceActorNotificationMsg() != null && !toCoreMsg.getToDeviceActorNotificationMsg().isEmpty()) {
|
193
|
|
- Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreMsg.getToDeviceActorNotificationMsg().toByteArray());
|
194
|
|
- if (actorMsg.isPresent()) {
|
195
|
|
- TbActorMsg tbActorMsg = actorMsg.get();
|
196
|
|
- if (tbActorMsg.getMsgType().equals(MsgType.DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG)) {
|
197
|
|
- tbCoreDeviceRpcService.forwardRpcRequestToDeviceActor((ToDeviceRpcRequestActorMsg) tbActorMsg);
|
198
|
|
- } else {
|
199
|
|
- log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
|
200
|
|
- actorContext.tell(actorMsg.get());
|
|
181
|
+ PendingMsgHolder pendingMsgHolder = new PendingMsgHolder();
|
|
182
|
+ Future<?> packSubmitFuture = consumersExecutor.submit(() -> {
|
|
183
|
+ pendingMap.forEach((id, msg) -> {
|
|
184
|
+ log.trace("[{}] Creating main callback for message: {}", id, msg.getValue());
|
|
185
|
+ TbCallback callback = new TbPackCallback<>(id, ctx);
|
|
186
|
+ try {
|
|
187
|
+ ToCoreMsg toCoreMsg = msg.getValue();
|
|
188
|
+ pendingMsgHolder.setToCoreMsg(toCoreMsg);
|
|
189
|
+ if (toCoreMsg.hasToSubscriptionMgrMsg()) {
|
|
190
|
+ log.trace("[{}] Forwarding message to subscription manager service {}", id, toCoreMsg.getToSubscriptionMgrMsg());
|
|
191
|
+ forwardToSubMgrService(toCoreMsg.getToSubscriptionMgrMsg(), callback);
|
|
192
|
+ } else if (toCoreMsg.hasToDeviceActorMsg()) {
|
|
193
|
+ log.trace("[{}] Forwarding message to device actor {}", id, toCoreMsg.getToDeviceActorMsg());
|
|
194
|
+ forwardToDeviceActor(toCoreMsg.getToDeviceActorMsg(), callback);
|
|
195
|
+ } else if (toCoreMsg.hasDeviceStateServiceMsg()) {
|
|
196
|
+ log.trace("[{}] Forwarding message to state service {}", id, toCoreMsg.getDeviceStateServiceMsg());
|
|
197
|
+ forwardToStateService(toCoreMsg.getDeviceStateServiceMsg(), callback);
|
|
198
|
+ } else if (toCoreMsg.getToDeviceActorNotificationMsg() != null && !toCoreMsg.getToDeviceActorNotificationMsg().isEmpty()) {
|
|
199
|
+ Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreMsg.getToDeviceActorNotificationMsg().toByteArray());
|
|
200
|
+ if (actorMsg.isPresent()) {
|
|
201
|
+ TbActorMsg tbActorMsg = actorMsg.get();
|
|
202
|
+ if (tbActorMsg.getMsgType().equals(MsgType.DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG)) {
|
|
203
|
+ tbCoreDeviceRpcService.forwardRpcRequestToDeviceActor((ToDeviceRpcRequestActorMsg) tbActorMsg);
|
|
204
|
+ } else {
|
|
205
|
+ log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
|
|
206
|
+ actorContext.tell(actorMsg.get());
|
|
207
|
+ }
|
201
|
208
|
}
|
|
209
|
+ callback.onSuccess();
|
202
|
210
|
}
|
203
|
|
- callback.onSuccess();
|
|
211
|
+ } catch (Throwable e) {
|
|
212
|
+ log.warn("[{}] Failed to process message: {}", id, msg, e);
|
|
213
|
+ callback.onFailure(e);
|
204
|
214
|
}
|
205
|
|
- } catch (Throwable e) {
|
206
|
|
- log.warn("[{}] Failed to process message: {}", id, msg, e);
|
207
|
|
- callback.onFailure(e);
|
208
|
|
- }
|
|
215
|
+ });
|
209
|
216
|
});
|
210
|
217
|
if (!processingTimeoutLatch.await(packProcessingTimeout, TimeUnit.MILLISECONDS)) {
|
|
218
|
+ if (!packSubmitFuture.isDone()) {
|
|
219
|
+ packSubmitFuture.cancel(true);
|
|
220
|
+ ToCoreMsg lastSubmitMsg = pendingMsgHolder.getToCoreMsg();
|
|
221
|
+ log.info("Timeout to process message: {}", lastSubmitMsg);
|
|
222
|
+ }
|
211
|
223
|
ctx.getAckMap().forEach((id, msg) -> log.debug("[{}] Timeout to process message: {}", id, msg.getValue()));
|
212
|
224
|
ctx.getFailedMap().forEach((id, msg) -> log.warn("[{}] Failed to process message: {}", id, msg.getValue()));
|
213
|
225
|
}
|
...
|
...
|
@@ -227,6 +239,12 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore |
227
|
239
|
});
|
228
|
240
|
}
|
229
|
241
|
|
|
242
|
+ private static class PendingMsgHolder {
|
|
243
|
+ @Getter
|
|
244
|
+ @Setter
|
|
245
|
+ private volatile ToCoreMsg toCoreMsg;
|
|
246
|
+ }
|
|
247
|
+
|
230
|
248
|
@Override
|
231
|
249
|
protected ServiceType getServiceType() {
|
232
|
250
|
return ServiceType.TB_CORE;
|
...
|
...
|
|