Showing
48 changed files
with
796 additions
and
683 deletions
@@ -59,6 +59,10 @@ | @@ -59,6 +59,10 @@ | ||
59 | </dependency> | 59 | </dependency> |
60 | <dependency> | 60 | <dependency> |
61 | <groupId>org.thingsboard.common</groupId> | 61 | <groupId>org.thingsboard.common</groupId> |
62 | + <artifactId>actor</artifactId> | ||
63 | + </dependency> | ||
64 | + <dependency> | ||
65 | + <groupId>org.thingsboard.common</groupId> | ||
62 | <artifactId>util</artifactId> | 66 | <artifactId>util</artifactId> |
63 | </dependency> | 67 | </dependency> |
64 | <dependency> | 68 | <dependency> |
@@ -174,14 +178,6 @@ | @@ -174,14 +178,6 @@ | ||
174 | <artifactId>spring-context-support</artifactId> | 178 | <artifactId>spring-context-support</artifactId> |
175 | </dependency> | 179 | </dependency> |
176 | <dependency> | 180 | <dependency> |
177 | - <groupId>com.typesafe.akka</groupId> | ||
178 | - <artifactId>akka-actor_${scala.version}</artifactId> | ||
179 | - </dependency> | ||
180 | - <dependency> | ||
181 | - <groupId>com.typesafe.akka</groupId> | ||
182 | - <artifactId>akka-slf4j_${scala.version}</artifactId> | ||
183 | - </dependency> | ||
184 | - <dependency> | ||
185 | <groupId>org.slf4j</groupId> | 181 | <groupId>org.slf4j</groupId> |
186 | <artifactId>slf4j-api</artifactId> | 182 | <artifactId>slf4j-api</artifactId> |
187 | </dependency> | 183 | </dependency> |
@@ -15,9 +15,6 @@ | @@ -15,9 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors; | 16 | package org.thingsboard.server.actors; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | -import akka.actor.ActorSystem; | ||
20 | -import akka.actor.Scheduler; | ||
21 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
22 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
23 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
@@ -25,8 +22,6 @@ import com.google.common.util.concurrent.FutureCallback; | @@ -25,8 +22,6 @@ import com.google.common.util.concurrent.FutureCallback; | ||
25 | import com.google.common.util.concurrent.Futures; | 22 | import com.google.common.util.concurrent.Futures; |
26 | import com.google.common.util.concurrent.ListenableFuture; | 23 | import com.google.common.util.concurrent.ListenableFuture; |
27 | import com.google.common.util.concurrent.MoreExecutors; | 24 | import com.google.common.util.concurrent.MoreExecutors; |
28 | -import com.typesafe.config.Config; | ||
29 | -import com.typesafe.config.ConfigFactory; | ||
30 | import lombok.Getter; | 25 | import lombok.Getter; |
31 | import lombok.Setter; | 26 | import lombok.Setter; |
32 | import lombok.extern.slf4j.Slf4j; | 27 | import lombok.extern.slf4j.Slf4j; |
@@ -91,12 +86,13 @@ import java.io.StringWriter; | @@ -91,12 +86,13 @@ import java.io.StringWriter; | ||
91 | import java.util.Optional; | 86 | import java.util.Optional; |
92 | import java.util.concurrent.ConcurrentHashMap; | 87 | import java.util.concurrent.ConcurrentHashMap; |
93 | import java.util.concurrent.ConcurrentMap; | 88 | import java.util.concurrent.ConcurrentMap; |
89 | +import java.util.concurrent.ScheduledExecutorService; | ||
90 | +import java.util.concurrent.TimeUnit; | ||
94 | import java.util.concurrent.atomic.AtomicInteger; | 91 | import java.util.concurrent.atomic.AtomicInteger; |
95 | 92 | ||
96 | @Slf4j | 93 | @Slf4j |
97 | @Component | 94 | @Component |
98 | public class ActorSystemContext { | 95 | public class ActorSystemContext { |
99 | - private static final String AKKA_CONF_FILE_NAME = "actor-system.conf"; | ||
100 | 96 | ||
101 | protected final ObjectMapper mapper = new ObjectMapper(); | 97 | protected final ObjectMapper mapper = new ObjectMapper(); |
102 | 98 | ||
@@ -260,14 +256,6 @@ public class ActorSystemContext { | @@ -260,14 +256,6 @@ public class ActorSystemContext { | ||
260 | @Getter | 256 | @Getter |
261 | private long syncSessionTimeout; | 257 | private long syncSessionTimeout; |
262 | 258 | ||
263 | - @Value("${actors.queue.enabled}") | ||
264 | - @Getter | ||
265 | - private boolean queuePersistenceEnabled; | ||
266 | - | ||
267 | - @Value("${actors.queue.timeout}") | ||
268 | - @Getter | ||
269 | - private long queuePersistenceTimeout; | ||
270 | - | ||
271 | @Value("${actors.rule.chain.error_persist_frequency}") | 259 | @Value("${actors.rule.chain.error_persist_frequency}") |
272 | @Getter | 260 | @Getter |
273 | private long ruleChainErrorPersistFrequency; | 261 | private long ruleChainErrorPersistFrequency; |
@@ -327,17 +315,14 @@ public class ActorSystemContext { | @@ -327,17 +315,14 @@ public class ActorSystemContext { | ||
327 | 315 | ||
328 | @Getter | 316 | @Getter |
329 | @Setter | 317 | @Setter |
330 | - private ActorSystem actorSystem; | 318 | + private TbActorSystem actorSystem; |
331 | 319 | ||
332 | @Setter | 320 | @Setter |
333 | - private ActorRef appActor; | 321 | + private TbActorRef appActor; |
334 | 322 | ||
335 | @Getter | 323 | @Getter |
336 | @Setter | 324 | @Setter |
337 | - private ActorRef statsActor; | ||
338 | - | ||
339 | - @Getter | ||
340 | - private final Config config; | 325 | + private TbActorRef statsActor; |
341 | 326 | ||
342 | @Autowired(required = false) | 327 | @Autowired(required = false) |
343 | @Getter | 328 | @Getter |
@@ -351,14 +336,8 @@ public class ActorSystemContext { | @@ -351,14 +336,8 @@ public class ActorSystemContext { | ||
351 | @Getter | 336 | @Getter |
352 | private RedisTemplate<String, Object> redisTemplate; | 337 | private RedisTemplate<String, Object> redisTemplate; |
353 | 338 | ||
354 | - public ActorSystemContext() { | ||
355 | - config = ConfigFactory.parseResources(AKKA_CONF_FILE_NAME).withFallback(ConfigFactory.load()); | ||
356 | - } | ||
357 | - | ||
358 | - | ||
359 | - | ||
360 | - public Scheduler getScheduler() { | ||
361 | - return actorSystem.scheduler(); | 339 | + public ScheduledExecutorService getScheduler() { |
340 | + return actorSystem.getScheduler(); | ||
362 | } | 341 | } |
363 | 342 | ||
364 | public void persistError(TenantId tenantId, EntityId entityId, String method, Exception e) { | 343 | public void persistError(TenantId tenantId, EntityId entityId, String method, Exception e) { |
@@ -531,7 +510,18 @@ public class ActorSystemContext { | @@ -531,7 +510,18 @@ public class ActorSystemContext { | ||
531 | return Exception.class.isInstance(error) ? (Exception) error : new Exception(error); | 510 | return Exception.class.isInstance(error) ? (Exception) error : new Exception(error); |
532 | } | 511 | } |
533 | 512 | ||
534 | - public void tell(TbActorMsg tbActorMsg, ActorRef sender) { | ||
535 | - appActor.tell(tbActorMsg, sender); | 513 | + public void tell(TbActorMsg tbActorMsg) { |
514 | + appActor.tell(tbActorMsg); | ||
515 | + } | ||
516 | + | ||
517 | + | ||
518 | + public void schedulePeriodicMsgWithDelay(TbActorRef ctx, TbActorMsg msg, long delayInMs, long periodInMs) { | ||
519 | + log.debug("Scheduling periodic msg {} every {} ms with delay {} ms", msg, periodInMs, delayInMs); | ||
520 | + getScheduler().scheduleWithFixedDelay(() -> ctx.tell(msg), delayInMs, periodInMs, TimeUnit.MILLISECONDS); | ||
521 | + } | ||
522 | + | ||
523 | + public void scheduleMsgWithDelay(TbActorRef ctx, TbActorMsg msg, long delayInMs) { | ||
524 | + log.debug("Scheduling msg {} with delay {} ms", msg, delayInMs); | ||
525 | + getScheduler().schedule(() -> ctx.tell(msg), delayInMs, TimeUnit.MILLISECONDS); | ||
536 | } | 526 | } |
537 | } | 527 | } |
application/src/main/java/org/thingsboard/server/actors/TbEntityTypeActorIdPredicate.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.actors; | ||
17 | + | ||
18 | +import lombok.RequiredArgsConstructor; | ||
19 | +import org.thingsboard.server.common.data.EntityType; | ||
20 | +import org.thingsboard.server.common.data.id.EntityId; | ||
21 | + | ||
22 | +import java.util.function.Predicate; | ||
23 | + | ||
24 | +@RequiredArgsConstructor | ||
25 | +public class TbEntityTypeActorIdPredicate implements Predicate<TbActorId> { | ||
26 | + | ||
27 | + private final EntityType entityType; | ||
28 | + | ||
29 | + @Override | ||
30 | + public boolean test(TbActorId actorId) { | ||
31 | + return actorId instanceof TbEntityActorId && testEntityId(((TbEntityActorId) actorId).getEntityId()); | ||
32 | + } | ||
33 | + | ||
34 | + protected boolean testEntityId(EntityId entityId) { | ||
35 | + return entityId.getEntityType().equals(entityType); | ||
36 | + } | ||
37 | +} |
@@ -15,21 +15,19 @@ | @@ -15,21 +15,19 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.app; | 16 | package org.thingsboard.server.actors.app; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | -import akka.actor.LocalActorRef; | ||
20 | -import akka.actor.OneForOneStrategy; | ||
21 | -import akka.actor.Props; | ||
22 | -import akka.actor.SupervisorStrategy; | ||
23 | -import akka.actor.Terminated; | ||
24 | -import com.google.common.collect.BiMap; | ||
25 | -import com.google.common.collect.HashBiMap; | 18 | +import lombok.extern.slf4j.Slf4j; |
26 | import org.thingsboard.server.actors.ActorSystemContext; | 19 | import org.thingsboard.server.actors.ActorSystemContext; |
20 | +import org.thingsboard.server.actors.TbActor; | ||
21 | +import org.thingsboard.server.actors.TbActorId; | ||
22 | +import org.thingsboard.server.actors.TbActorRef; | ||
23 | +import org.thingsboard.server.actors.TbEntityActorId; | ||
27 | import org.thingsboard.server.actors.service.ContextAwareActor; | 24 | import org.thingsboard.server.actors.service.ContextAwareActor; |
28 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 25 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
29 | import org.thingsboard.server.actors.service.DefaultActorService; | 26 | import org.thingsboard.server.actors.service.DefaultActorService; |
30 | import org.thingsboard.server.actors.tenant.TenantActor; | 27 | import org.thingsboard.server.actors.tenant.TenantActor; |
31 | import org.thingsboard.server.common.data.EntityType; | 28 | import org.thingsboard.server.common.data.EntityType; |
32 | import org.thingsboard.server.common.data.Tenant; | 29 | import org.thingsboard.server.common.data.Tenant; |
30 | +import org.thingsboard.server.common.data.id.EntityId; | ||
33 | import org.thingsboard.server.common.data.id.TenantId; | 31 | import org.thingsboard.server.common.data.id.TenantId; |
34 | import org.thingsboard.server.common.data.page.PageDataIterable; | 32 | import org.thingsboard.server.common.data.page.PageDataIterable; |
35 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | 33 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; |
@@ -43,38 +41,27 @@ import org.thingsboard.server.common.msg.queue.ServiceType; | @@ -43,38 +41,27 @@ import org.thingsboard.server.common.msg.queue.ServiceType; | ||
43 | import org.thingsboard.server.dao.model.ModelConstants; | 41 | import org.thingsboard.server.dao.model.ModelConstants; |
44 | import org.thingsboard.server.dao.tenant.TenantService; | 42 | import org.thingsboard.server.dao.tenant.TenantService; |
45 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; | 43 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; |
46 | -import scala.concurrent.duration.Duration; | ||
47 | 44 | ||
48 | import java.util.HashSet; | 45 | import java.util.HashSet; |
49 | import java.util.Optional; | 46 | import java.util.Optional; |
50 | import java.util.Set; | 47 | import java.util.Set; |
51 | 48 | ||
49 | +@Slf4j | ||
52 | public class AppActor extends ContextAwareActor { | 50 | public class AppActor extends ContextAwareActor { |
53 | 51 | ||
54 | private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); | 52 | private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); |
55 | private final TenantService tenantService; | 53 | private final TenantService tenantService; |
56 | - private final BiMap<TenantId, ActorRef> tenantActors; | ||
57 | private final Set<TenantId> deletedTenants; | 54 | private final Set<TenantId> deletedTenants; |
58 | private boolean ruleChainsInitialized; | 55 | private boolean ruleChainsInitialized; |
59 | 56 | ||
60 | private AppActor(ActorSystemContext systemContext) { | 57 | private AppActor(ActorSystemContext systemContext) { |
61 | super(systemContext); | 58 | super(systemContext); |
62 | this.tenantService = systemContext.getTenantService(); | 59 | this.tenantService = systemContext.getTenantService(); |
63 | - this.tenantActors = HashBiMap.create(); | ||
64 | this.deletedTenants = new HashSet<>(); | 60 | this.deletedTenants = new HashSet<>(); |
65 | } | 61 | } |
66 | 62 | ||
67 | @Override | 63 | @Override |
68 | - public SupervisorStrategy supervisorStrategy() { | ||
69 | - return strategy; | ||
70 | - } | ||
71 | - | ||
72 | - @Override | ||
73 | - public void preStart() { | ||
74 | - } | ||
75 | - | ||
76 | - @Override | ||
77 | - protected boolean process(TbActorMsg msg) { | 64 | + protected boolean doProcess(TbActorMsg msg) { |
78 | if (!ruleChainsInitialized) { | 65 | if (!ruleChainsInitialized) { |
79 | initTenantActors(); | 66 | initTenantActors(); |
80 | ruleChainsInitialized = true; | 67 | ruleChainsInitialized = true; |
@@ -86,7 +73,7 @@ public class AppActor extends ContextAwareActor { | @@ -86,7 +73,7 @@ public class AppActor extends ContextAwareActor { | ||
86 | case APP_INIT_MSG: | 73 | case APP_INIT_MSG: |
87 | break; | 74 | break; |
88 | case PARTITION_CHANGE_MSG: | 75 | case PARTITION_CHANGE_MSG: |
89 | - broadcast(msg); | 76 | + ctx.broadcastToChildren(msg); |
90 | break; | 77 | break; |
91 | case COMPONENT_LIFE_CYCLE_MSG: | 78 | case COMPONENT_LIFE_CYCLE_MSG: |
92 | onComponentLifecycleMsg((ComponentLifecycleMsg) msg); | 79 | onComponentLifecycleMsg((ComponentLifecycleMsg) msg); |
@@ -145,19 +132,15 @@ public class AppActor extends ContextAwareActor { | @@ -145,19 +132,15 @@ public class AppActor extends ContextAwareActor { | ||
145 | msg.getTbMsg().getCallback().onFailure(new RuleEngineException("Message has system tenant id!")); | 132 | msg.getTbMsg().getCallback().onFailure(new RuleEngineException("Message has system tenant id!")); |
146 | } else { | 133 | } else { |
147 | if (!deletedTenants.contains(msg.getTenantId())) { | 134 | if (!deletedTenants.contains(msg.getTenantId())) { |
148 | - getOrCreateTenantActor(msg.getTenantId()).tell(msg, self()); | 135 | + getOrCreateTenantActor(msg.getTenantId()).tell(msg); |
149 | } else { | 136 | } else { |
150 | msg.getTbMsg().getCallback().onSuccess(); | 137 | msg.getTbMsg().getCallback().onSuccess(); |
151 | } | 138 | } |
152 | } | 139 | } |
153 | } | 140 | } |
154 | 141 | ||
155 | - protected void broadcast(Object msg) { | ||
156 | - tenantActors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender())); | ||
157 | - } | ||
158 | - | ||
159 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { | 142 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { |
160 | - ActorRef target = null; | 143 | + TbActorRef target = null; |
161 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { | 144 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { |
162 | log.warn("Message has system tenant id: {}", msg); | 145 | log.warn("Message has system tenant id: {}", msg); |
163 | } else { | 146 | } else { |
@@ -166,17 +149,13 @@ public class AppActor extends ContextAwareActor { | @@ -166,17 +149,13 @@ public class AppActor extends ContextAwareActor { | ||
166 | log.info("[{}] Handling tenant deleted notification: {}", msg.getTenantId(), msg); | 149 | log.info("[{}] Handling tenant deleted notification: {}", msg.getTenantId(), msg); |
167 | TenantId tenantId = new TenantId(msg.getEntityId().getId()); | 150 | TenantId tenantId = new TenantId(msg.getEntityId().getId()); |
168 | deletedTenants.add(tenantId); | 151 | deletedTenants.add(tenantId); |
169 | - ActorRef tenantActor = tenantActors.get(tenantId); | ||
170 | - if (tenantActor != null) { | ||
171 | - log.debug("[{}] Deleting tenant actor: {}", msg.getTenantId(), tenantActor); | ||
172 | - context().stop(tenantActor); | ||
173 | - } | 152 | + ctx.stop(new TbEntityActorId(tenantId)); |
174 | } else { | 153 | } else { |
175 | target = getOrCreateTenantActor(msg.getTenantId()); | 154 | target = getOrCreateTenantActor(msg.getTenantId()); |
176 | } | 155 | } |
177 | } | 156 | } |
178 | if (target != null) { | 157 | if (target != null) { |
179 | - target.tell(msg, ActorRef.noSender()); | 158 | + target.tell(msg); |
180 | } else { | 159 | } else { |
181 | log.debug("[{}] Invalid component lifecycle msg: {}", msg.getTenantId(), msg); | 160 | log.debug("[{}] Invalid component lifecycle msg: {}", msg.getTenantId(), msg); |
182 | } | 161 | } |
@@ -184,7 +163,7 @@ public class AppActor extends ContextAwareActor { | @@ -184,7 +163,7 @@ public class AppActor extends ContextAwareActor { | ||
184 | 163 | ||
185 | private void onToDeviceActorMsg(TenantAwareMsg msg) { | 164 | private void onToDeviceActorMsg(TenantAwareMsg msg) { |
186 | if (!deletedTenants.contains(msg.getTenantId())) { | 165 | if (!deletedTenants.contains(msg.getTenantId())) { |
187 | - getOrCreateTenantActor(msg.getTenantId()).tell(msg, ActorRef.noSender()); | 166 | + getOrCreateTenantActor(msg.getTenantId()).tell(msg); |
188 | } else { | 167 | } else { |
189 | if (msg instanceof TransportToDeviceActorMsgWrapper) { | 168 | if (msg instanceof TransportToDeviceActorMsgWrapper) { |
190 | ((TransportToDeviceActorMsgWrapper) msg).getCallback().onSuccess(); | 169 | ((TransportToDeviceActorMsgWrapper) msg).getCallback().onSuccess(); |
@@ -192,49 +171,27 @@ public class AppActor extends ContextAwareActor { | @@ -192,49 +171,27 @@ public class AppActor extends ContextAwareActor { | ||
192 | } | 171 | } |
193 | } | 172 | } |
194 | 173 | ||
195 | - private ActorRef getOrCreateTenantActor(TenantId tenantId) { | ||
196 | - return tenantActors.computeIfAbsent(tenantId, k -> { | ||
197 | - log.info("[{}] Creating tenant actor.", tenantId); | ||
198 | - ActorRef tenantActor = context().actorOf(Props.create(new TenantActor.ActorCreator(systemContext, tenantId)) | ||
199 | - .withDispatcher(DefaultActorService.CORE_DISPATCHER_NAME), tenantId.toString()); | ||
200 | - context().watch(tenantActor); | ||
201 | - log.info("[{}] Created tenant actor: {}.", tenantId, tenantActor); | ||
202 | - return tenantActor; | ||
203 | - }); | ||
204 | - } | ||
205 | - | ||
206 | - @Override | ||
207 | - protected void processTermination(Terminated message) { | ||
208 | - ActorRef terminated = message.actor(); | ||
209 | - if (terminated instanceof LocalActorRef) { | ||
210 | - boolean removed = tenantActors.inverse().remove(terminated) != null; | ||
211 | - if (removed) { | ||
212 | - log.debug("[{}] Removed actor:", terminated); | ||
213 | - } | ||
214 | - } else { | ||
215 | - throw new IllegalStateException("Remote actors are not supported!"); | ||
216 | - } | 174 | + private TbActorRef getOrCreateTenantActor(TenantId tenantId) { |
175 | + return ctx.getOrCreateChildActor(new TbEntityActorId(tenantId), | ||
176 | + () -> DefaultActorService.TENANT_DISPATCHER_NAME, | ||
177 | + () -> new TenantActor.ActorCreator(systemContext, tenantId)); | ||
217 | } | 178 | } |
218 | 179 | ||
219 | - public static class ActorCreator extends ContextBasedCreator<AppActor> { | ||
220 | - private static final long serialVersionUID = 1L; | 180 | + public static class ActorCreator extends ContextBasedCreator { |
221 | 181 | ||
222 | public ActorCreator(ActorSystemContext context) { | 182 | public ActorCreator(ActorSystemContext context) { |
223 | super(context); | 183 | super(context); |
224 | } | 184 | } |
225 | 185 | ||
226 | @Override | 186 | @Override |
227 | - public AppActor create() { | 187 | + public TbActorId createActorId() { |
188 | + return new TbEntityActorId(new TenantId(EntityId.NULL_UUID)); | ||
189 | + } | ||
190 | + | ||
191 | + @Override | ||
192 | + public TbActor createActor() { | ||
228 | return new AppActor(context); | 193 | return new AppActor(context); |
229 | } | 194 | } |
230 | } | 195 | } |
231 | 196 | ||
232 | - private final SupervisorStrategy strategy = new OneForOneStrategy(3, Duration.create("1 minute"), t -> { | ||
233 | - log.warn("Unknown failure", t); | ||
234 | - if (t instanceof RuntimeException) { | ||
235 | - return SupervisorStrategy.restart(); | ||
236 | - } else { | ||
237 | - return SupervisorStrategy.stop(); | ||
238 | - } | ||
239 | - }); | ||
240 | } | 197 | } |
@@ -15,9 +15,11 @@ | @@ -15,9 +15,11 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.device; | 16 | package org.thingsboard.server.actors.device; |
17 | 17 | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
18 | import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; | 19 | import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; |
19 | import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; | 20 | import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; |
20 | import org.thingsboard.server.actors.ActorSystemContext; | 21 | import org.thingsboard.server.actors.ActorSystemContext; |
22 | +import org.thingsboard.server.actors.TbActorCtx; | ||
21 | import org.thingsboard.server.actors.service.ContextAwareActor; | 23 | import org.thingsboard.server.actors.service.ContextAwareActor; |
22 | import org.thingsboard.server.common.data.id.DeviceId; | 24 | import org.thingsboard.server.common.data.id.DeviceId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 25 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -26,6 +28,7 @@ import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeout | @@ -26,6 +28,7 @@ import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeout | ||
26 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; | 28 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; |
27 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; | 29 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; |
28 | 30 | ||
31 | +@Slf4j | ||
29 | public class DeviceActor extends ContextAwareActor { | 32 | public class DeviceActor extends ContextAwareActor { |
30 | 33 | ||
31 | private final DeviceActorMessageProcessor processor; | 34 | private final DeviceActorMessageProcessor processor; |
@@ -36,10 +39,11 @@ public class DeviceActor extends ContextAwareActor { | @@ -36,10 +39,11 @@ public class DeviceActor extends ContextAwareActor { | ||
36 | } | 39 | } |
37 | 40 | ||
38 | @Override | 41 | @Override |
39 | - public void preStart() { | 42 | + public void init(TbActorCtx ctx) { |
43 | + super.init(ctx); | ||
40 | log.debug("[{}][{}] Starting device actor.", processor.tenantId, processor.deviceId); | 44 | log.debug("[{}][{}] Starting device actor.", processor.tenantId, processor.deviceId); |
41 | try { | 45 | try { |
42 | - processor.initSessionTimeout(context()); | 46 | + processor.initSessionTimeout(ctx); |
43 | log.debug("[{}][{}] Device actor started.", processor.tenantId, processor.deviceId); | 47 | log.debug("[{}][{}] Device actor started.", processor.tenantId, processor.deviceId); |
44 | } catch (Exception e) { | 48 | } catch (Exception e) { |
45 | log.warn("[{}][{}] Unknown failure", processor.tenantId, processor.deviceId, e); | 49 | log.warn("[{}][{}] Unknown failure", processor.tenantId, processor.deviceId, e); |
@@ -47,18 +51,13 @@ public class DeviceActor extends ContextAwareActor { | @@ -47,18 +51,13 @@ public class DeviceActor extends ContextAwareActor { | ||
47 | } | 51 | } |
48 | 52 | ||
49 | @Override | 53 | @Override |
50 | - public void postStop() { | ||
51 | - | ||
52 | - } | ||
53 | - | ||
54 | - @Override | ||
55 | - protected boolean process(TbActorMsg msg) { | 54 | + protected boolean doProcess(TbActorMsg msg) { |
56 | switch (msg.getMsgType()) { | 55 | switch (msg.getMsgType()) { |
57 | case TRANSPORT_TO_DEVICE_ACTOR_MSG: | 56 | case TRANSPORT_TO_DEVICE_ACTOR_MSG: |
58 | - processor.process(context(), (TransportToDeviceActorMsgWrapper) msg); | 57 | + processor.process(ctx, (TransportToDeviceActorMsgWrapper) msg); |
59 | break; | 58 | break; |
60 | case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG: | 59 | case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG: |
61 | - processor.processAttributesUpdate(context(), (DeviceAttributesEventNotificationMsg) msg); | 60 | + processor.processAttributesUpdate(ctx, (DeviceAttributesEventNotificationMsg) msg); |
62 | break; | 61 | break; |
63 | case DEVICE_CREDENTIALS_UPDATE_TO_DEVICE_ACTOR_MSG: | 62 | case DEVICE_CREDENTIALS_UPDATE_TO_DEVICE_ACTOR_MSG: |
64 | processor.processCredentialsUpdate(); | 63 | processor.processCredentialsUpdate(); |
@@ -67,10 +66,10 @@ public class DeviceActor extends ContextAwareActor { | @@ -67,10 +66,10 @@ public class DeviceActor extends ContextAwareActor { | ||
67 | processor.processNameOrTypeUpdate((DeviceNameOrTypeUpdateMsg) msg); | 66 | processor.processNameOrTypeUpdate((DeviceNameOrTypeUpdateMsg) msg); |
68 | break; | 67 | break; |
69 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: | 68 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: |
70 | - processor.processRpcRequest(context(), (ToDeviceRpcRequestActorMsg) msg); | 69 | + processor.processRpcRequest(ctx, (ToDeviceRpcRequestActorMsg) msg); |
71 | break; | 70 | break; |
72 | case DEVICE_ACTOR_SERVER_SIDE_RPC_TIMEOUT_MSG: | 71 | case DEVICE_ACTOR_SERVER_SIDE_RPC_TIMEOUT_MSG: |
73 | - processor.processServerSideRpcTimeout(context(), (DeviceActorServerSideRpcTimeoutMsg) msg); | 72 | + processor.processServerSideRpcTimeout(ctx, (DeviceActorServerSideRpcTimeoutMsg) msg); |
74 | break; | 73 | break; |
75 | case SESSION_TIMEOUT_MSG: | 74 | case SESSION_TIMEOUT_MSG: |
76 | processor.checkSessionsTimeout(); | 75 | processor.checkSessionsTimeout(); |
@@ -16,12 +16,14 @@ | @@ -16,12 +16,14 @@ | ||
16 | package org.thingsboard.server.actors.device; | 16 | package org.thingsboard.server.actors.device; |
17 | 17 | ||
18 | import org.thingsboard.server.actors.ActorSystemContext; | 18 | import org.thingsboard.server.actors.ActorSystemContext; |
19 | +import org.thingsboard.server.actors.TbActor; | ||
20 | +import org.thingsboard.server.actors.TbActorId; | ||
21 | +import org.thingsboard.server.actors.TbEntityActorId; | ||
19 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 22 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
20 | import org.thingsboard.server.common.data.id.DeviceId; | 23 | import org.thingsboard.server.common.data.id.DeviceId; |
21 | import org.thingsboard.server.common.data.id.TenantId; | 24 | import org.thingsboard.server.common.data.id.TenantId; |
22 | 25 | ||
23 | -public class DeviceActorCreator extends ContextBasedCreator<DeviceActor> { | ||
24 | - private static final long serialVersionUID = 1L; | 26 | +public class DeviceActorCreator extends ContextBasedCreator { |
25 | 27 | ||
26 | private final TenantId tenantId; | 28 | private final TenantId tenantId; |
27 | private final DeviceId deviceId; | 29 | private final DeviceId deviceId; |
@@ -33,7 +35,13 @@ public class DeviceActorCreator extends ContextBasedCreator<DeviceActor> { | @@ -33,7 +35,13 @@ public class DeviceActorCreator extends ContextBasedCreator<DeviceActor> { | ||
33 | } | 35 | } |
34 | 36 | ||
35 | @Override | 37 | @Override |
36 | - public DeviceActor create() { | 38 | + public TbActorId createActorId() { |
39 | + return new TbEntityActorId(deviceId); | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public TbActor createActor() { | ||
37 | return new DeviceActor(context, tenantId, deviceId); | 44 | return new DeviceActor(context, tenantId, deviceId); |
38 | } | 45 | } |
46 | + | ||
39 | } | 47 | } |
@@ -15,7 +15,6 @@ | @@ -15,7 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.device; | 16 | package org.thingsboard.server.actors.device; |
17 | 17 | ||
18 | -import akka.actor.ActorContext; | ||
19 | import com.google.common.util.concurrent.FutureCallback; | 18 | import com.google.common.util.concurrent.FutureCallback; |
20 | import com.google.common.util.concurrent.Futures; | 19 | import com.google.common.util.concurrent.Futures; |
21 | import com.google.common.util.concurrent.ListenableFuture; | 20 | import com.google.common.util.concurrent.ListenableFuture; |
@@ -27,6 +26,7 @@ import org.thingsboard.rule.engine.api.RpcError; | @@ -27,6 +26,7 @@ import org.thingsboard.rule.engine.api.RpcError; | ||
27 | import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; | 26 | import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; |
28 | import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; | 27 | import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; |
29 | import org.thingsboard.server.actors.ActorSystemContext; | 28 | import org.thingsboard.server.actors.ActorSystemContext; |
29 | +import org.thingsboard.server.actors.TbActorCtx; | ||
30 | import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; | 30 | import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; |
31 | import org.thingsboard.server.common.data.Device; | 31 | import org.thingsboard.server.common.data.Device; |
32 | import org.thingsboard.server.common.data.id.DeviceId; | 32 | import org.thingsboard.server.common.data.id.DeviceId; |
@@ -127,7 +127,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -127,7 +127,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
127 | } | 127 | } |
128 | } | 128 | } |
129 | 129 | ||
130 | - void processRpcRequest(ActorContext context, ToDeviceRpcRequestActorMsg msg) { | 130 | + void processRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg) { |
131 | ToDeviceRpcRequest request = msg.getMsg(); | 131 | ToDeviceRpcRequest request = msg.getMsg(); |
132 | ToDeviceRpcRequestBody body = request.getBody(); | 132 | ToDeviceRpcRequestBody body = request.getBody(); |
133 | ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder().setRequestId( | 133 | ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder().setRequestId( |
@@ -162,13 +162,13 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -162,13 +162,13 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
162 | } | 162 | } |
163 | } | 163 | } |
164 | 164 | ||
165 | - private void registerPendingRpcRequest(ActorContext context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) { | 165 | + private void registerPendingRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) { |
166 | toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent)); | 166 | toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent)); |
167 | DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout); | 167 | DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout); |
168 | scheduleMsgWithDelay(context, timeoutMsg, timeoutMsg.getTimeout()); | 168 | scheduleMsgWithDelay(context, timeoutMsg, timeoutMsg.getTimeout()); |
169 | } | 169 | } |
170 | 170 | ||
171 | - void processServerSideRpcTimeout(ActorContext context, DeviceActorServerSideRpcTimeoutMsg msg) { | 171 | + void processServerSideRpcTimeout(TbActorCtx context, DeviceActorServerSideRpcTimeoutMsg msg) { |
172 | ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(msg.getId()); | 172 | ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(msg.getId()); |
173 | if (requestMd != null) { | 173 | if (requestMd != null) { |
174 | log.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId()); | 174 | log.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId()); |
@@ -177,7 +177,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -177,7 +177,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | - private void sendPendingRequests(ActorContext context, UUID sessionId, SessionInfoProto sessionInfo) { | 180 | + private void sendPendingRequests(TbActorCtx context, UUID sessionId, SessionInfoProto sessionInfo) { |
181 | SessionType sessionType = getSessionType(sessionId); | 181 | SessionType sessionType = getSessionType(sessionId); |
182 | if (!toDeviceRpcPendingMap.isEmpty()) { | 182 | if (!toDeviceRpcPendingMap.isEmpty()) { |
183 | log.debug("[{}] Pushing {} pending RPC messages to new async session [{}]", deviceId, toDeviceRpcPendingMap.size(), sessionId); | 183 | log.debug("[{}] Pushing {} pending RPC messages to new async session [{}]", deviceId, toDeviceRpcPendingMap.size(), sessionId); |
@@ -198,7 +198,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -198,7 +198,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
198 | sentOneWayIds.forEach(toDeviceRpcPendingMap::remove); | 198 | sentOneWayIds.forEach(toDeviceRpcPendingMap::remove); |
199 | } | 199 | } |
200 | 200 | ||
201 | - private Consumer<Map.Entry<Integer, ToDeviceRpcRequestMetadata>> processPendingRpc(ActorContext context, UUID sessionId, String nodeId, Set<Integer> sentOneWayIds) { | 201 | + private Consumer<Map.Entry<Integer, ToDeviceRpcRequestMetadata>> processPendingRpc(TbActorCtx context, UUID sessionId, String nodeId, Set<Integer> sentOneWayIds) { |
202 | return entry -> { | 202 | return entry -> { |
203 | ToDeviceRpcRequest request = entry.getValue().getMsg().getMsg(); | 203 | ToDeviceRpcRequest request = entry.getValue().getMsg().getMsg(); |
204 | ToDeviceRpcRequestBody body = request.getBody(); | 204 | ToDeviceRpcRequestBody body = request.getBody(); |
@@ -212,7 +212,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -212,7 +212,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
212 | }; | 212 | }; |
213 | } | 213 | } |
214 | 214 | ||
215 | - void process(ActorContext context, TransportToDeviceActorMsgWrapper wrapper) { | 215 | + void process(TbActorCtx context, TransportToDeviceActorMsgWrapper wrapper) { |
216 | TransportToDeviceActorMsg msg = wrapper.getMsg(); | 216 | TransportToDeviceActorMsg msg = wrapper.getMsg(); |
217 | TbCallback callback = wrapper.getCallback(); | 217 | TbCallback callback = wrapper.getCallback(); |
218 | if (msg.hasSessionEvent()) { | 218 | if (msg.hasSessionEvent()) { |
@@ -239,7 +239,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -239,7 +239,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
239 | callback.onSuccess(); | 239 | callback.onSuccess(); |
240 | } | 240 | } |
241 | 241 | ||
242 | - private void handleClaimDeviceMsg(ActorContext context, SessionInfoProto sessionInfo, TransportProtos.ClaimDeviceMsg msg) { | 242 | + private void handleClaimDeviceMsg(TbActorCtx context, SessionInfoProto sessionInfo, TransportProtos.ClaimDeviceMsg msg) { |
243 | DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB())); | 243 | DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB())); |
244 | systemContext.getClaimDevicesService().registerClaimingInfo(tenantId, deviceId, msg.getSecretKey(), msg.getDurationMs()); | 244 | systemContext.getClaimDevicesService().registerClaimingInfo(tenantId, deviceId, msg.getSecretKey(), msg.getDurationMs()); |
245 | } | 245 | } |
@@ -252,7 +252,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -252,7 +252,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
252 | systemContext.getDeviceStateService().onDeviceDisconnect(deviceId); | 252 | systemContext.getDeviceStateService().onDeviceDisconnect(deviceId); |
253 | } | 253 | } |
254 | 254 | ||
255 | - private void handleGetAttributesRequest(ActorContext context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { | 255 | + private void handleGetAttributesRequest(TbActorCtx context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { |
256 | int requestId = request.getRequestId(); | 256 | int requestId = request.getRequestId(); |
257 | Futures.addCallback(getAttributesKvEntries(request), new FutureCallback<List<List<AttributeKvEntry>>>() { | 257 | Futures.addCallback(getAttributesKvEntries(request), new FutureCallback<List<List<AttributeKvEntry>>>() { |
258 | @Override | 258 | @Override |
@@ -310,7 +310,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -310,7 +310,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
310 | return sessions.containsKey(sessionId) ? SessionType.ASYNC : SessionType.SYNC; | 310 | return sessions.containsKey(sessionId) ? SessionType.ASYNC : SessionType.SYNC; |
311 | } | 311 | } |
312 | 312 | ||
313 | - void processAttributesUpdate(ActorContext context, DeviceAttributesEventNotificationMsg msg) { | 313 | + void processAttributesUpdate(TbActorCtx context, DeviceAttributesEventNotificationMsg msg) { |
314 | if (attributeSubscriptions.size() > 0) { | 314 | if (attributeSubscriptions.size() > 0) { |
315 | boolean hasNotificationData = false; | 315 | boolean hasNotificationData = false; |
316 | AttributeUpdateNotificationMsg.Builder notification = AttributeUpdateNotificationMsg.newBuilder(); | 316 | AttributeUpdateNotificationMsg.Builder notification = AttributeUpdateNotificationMsg.newBuilder(); |
@@ -349,7 +349,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -349,7 +349,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
349 | } | 349 | } |
350 | } | 350 | } |
351 | 351 | ||
352 | - private void processRpcResponses(ActorContext context, SessionInfoProto sessionInfo, ToDeviceRpcResponseMsg responseMsg) { | 352 | + private void processRpcResponses(TbActorCtx context, SessionInfoProto sessionInfo, ToDeviceRpcResponseMsg responseMsg) { |
353 | UUID sessionId = getSessionId(sessionInfo); | 353 | UUID sessionId = getSessionId(sessionInfo); |
354 | log.debug("[{}] Processing rpc command response [{}]", deviceId, sessionId); | 354 | log.debug("[{}] Processing rpc command response [{}]", deviceId, sessionId); |
355 | ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); | 355 | ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); |
@@ -362,7 +362,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -362,7 +362,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
362 | } | 362 | } |
363 | } | 363 | } |
364 | 364 | ||
365 | - private void processSubscriptionCommands(ActorContext context, SessionInfoProto sessionInfo, SubscribeToAttributeUpdatesMsg subscribeCmd) { | 365 | + private void processSubscriptionCommands(TbActorCtx context, SessionInfoProto sessionInfo, SubscribeToAttributeUpdatesMsg subscribeCmd) { |
366 | UUID sessionId = getSessionId(sessionInfo); | 366 | UUID sessionId = getSessionId(sessionInfo); |
367 | if (subscribeCmd.getUnsubscribe()) { | 367 | if (subscribeCmd.getUnsubscribe()) { |
368 | log.debug("[{}] Canceling attributes subscription for session [{}]", deviceId, sessionId); | 368 | log.debug("[{}] Canceling attributes subscription for session [{}]", deviceId, sessionId); |
@@ -383,7 +383,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -383,7 +383,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
383 | return new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()); | 383 | return new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()); |
384 | } | 384 | } |
385 | 385 | ||
386 | - private void processSubscriptionCommands(ActorContext context, SessionInfoProto sessionInfo, SubscribeToRPCMsg subscribeCmd) { | 386 | + private void processSubscriptionCommands(TbActorCtx context, SessionInfoProto sessionInfo, SubscribeToRPCMsg subscribeCmd) { |
387 | UUID sessionId = getSessionId(sessionInfo); | 387 | UUID sessionId = getSessionId(sessionInfo); |
388 | if (subscribeCmd.getUnsubscribe()) { | 388 | if (subscribeCmd.getUnsubscribe()) { |
389 | log.debug("[{}] Canceling rpc subscription for session [{}]", deviceId, sessionId); | 389 | log.debug("[{}] Canceling rpc subscription for session [{}]", deviceId, sessionId); |
@@ -433,7 +433,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -433,7 +433,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
433 | } | 433 | } |
434 | } | 434 | } |
435 | 435 | ||
436 | - private void handleSessionActivity(ActorContext context, SessionInfoProto sessionInfoProto, SubscriptionInfoProto subscriptionInfo) { | 436 | + private void handleSessionActivity(TbActorCtx context, SessionInfoProto sessionInfoProto, SubscriptionInfoProto subscriptionInfo) { |
437 | UUID sessionId = getSessionId(sessionInfoProto); | 437 | UUID sessionId = getSessionId(sessionInfoProto); |
438 | SessionInfoMetaData sessionMD = sessions.computeIfAbsent(sessionId, | 438 | SessionInfoMetaData sessionMD = sessions.computeIfAbsent(sessionId, |
439 | id -> new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfoProto.getNodeId()), 0L)); | 439 | id -> new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfoProto.getNodeId()), 0L)); |
@@ -612,8 +612,8 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -612,8 +612,8 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
612 | .addAllSessions(sessionsList).build().toByteArray()); | 612 | .addAllSessions(sessionsList).build().toByteArray()); |
613 | } | 613 | } |
614 | 614 | ||
615 | - void initSessionTimeout(ActorContext context) { | ||
616 | - schedulePeriodicMsgWithDelay(context, SessionTimeoutCheckMsg.instance(), systemContext.getSessionInactivityTimeout(), systemContext.getSessionInactivityTimeout()); | 615 | + void initSessionTimeout(TbActorCtx ctx) { |
616 | + schedulePeriodicMsgWithDelay(ctx, SessionTimeoutCheckMsg.instance(), systemContext.getSessionInactivityTimeout(), systemContext.getSessionInactivityTimeout()); | ||
617 | } | 617 | } |
618 | 618 | ||
619 | void checkSessionsTimeout() { | 619 | void checkSessionsTimeout() { |
@@ -15,7 +15,6 @@ | @@ -15,7 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.ruleChain; | 16 | package org.thingsboard.server.actors.ruleChain; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | import com.datastax.driver.core.ResultSetFuture; | 18 | import com.datastax.driver.core.ResultSetFuture; |
20 | import com.fasterxml.jackson.core.JsonProcessingException; | 19 | import com.fasterxml.jackson.core.JsonProcessingException; |
21 | import com.fasterxml.jackson.databind.ObjectMapper; | 20 | import com.fasterxml.jackson.databind.ObjectMapper; |
@@ -30,6 +29,7 @@ import org.thingsboard.rule.engine.api.ScriptEngine; | @@ -30,6 +29,7 @@ import org.thingsboard.rule.engine.api.ScriptEngine; | ||
30 | import org.thingsboard.rule.engine.api.TbContext; | 29 | import org.thingsboard.rule.engine.api.TbContext; |
31 | import org.thingsboard.rule.engine.api.TbRelationTypes; | 30 | import org.thingsboard.rule.engine.api.TbRelationTypes; |
32 | import org.thingsboard.server.actors.ActorSystemContext; | 31 | import org.thingsboard.server.actors.ActorSystemContext; |
32 | +import org.thingsboard.server.actors.TbActorRef; | ||
33 | import org.thingsboard.server.common.data.Customer; | 33 | import org.thingsboard.server.common.data.Customer; |
34 | import org.thingsboard.server.common.data.DataConstants; | 34 | import org.thingsboard.server.common.data.DataConstants; |
35 | import org.thingsboard.server.common.data.Device; | 35 | import org.thingsboard.server.common.data.Device; |
@@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; | @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; | ||
40 | import org.thingsboard.server.common.data.id.RuleNodeId; | 40 | import org.thingsboard.server.common.data.id.RuleNodeId; |
41 | import org.thingsboard.server.common.data.id.TenantId; | 41 | import org.thingsboard.server.common.data.id.TenantId; |
42 | import org.thingsboard.server.common.data.rule.RuleNode; | 42 | import org.thingsboard.server.common.data.rule.RuleNode; |
43 | +import org.thingsboard.server.common.msg.TbActorMsg; | ||
43 | import org.thingsboard.server.common.msg.TbMsg; | 44 | import org.thingsboard.server.common.msg.TbMsg; |
44 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 45 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
45 | import org.thingsboard.server.common.msg.queue.ServiceType; | 46 | import org.thingsboard.server.common.msg.queue.ServiceType; |
@@ -62,7 +63,6 @@ import org.thingsboard.server.gen.transport.TransportProtos; | @@ -62,7 +63,6 @@ import org.thingsboard.server.gen.transport.TransportProtos; | ||
62 | import org.thingsboard.server.queue.TbQueueCallback; | 63 | import org.thingsboard.server.queue.TbQueueCallback; |
63 | import org.thingsboard.server.queue.TbQueueMsgMetadata; | 64 | import org.thingsboard.server.queue.TbQueueMsgMetadata; |
64 | import org.thingsboard.server.service.script.RuleNodeJsScriptEngine; | 65 | import org.thingsboard.server.service.script.RuleNodeJsScriptEngine; |
65 | -import scala.concurrent.duration.Duration; | ||
66 | 66 | ||
67 | import java.util.Collections; | 67 | import java.util.Collections; |
68 | import java.util.Set; | 68 | import java.util.Set; |
@@ -104,7 +104,7 @@ class DefaultTbContext implements TbContext { | @@ -104,7 +104,7 @@ class DefaultTbContext implements TbContext { | ||
104 | if (nodeCtx.getSelf().isDebugMode()) { | 104 | if (nodeCtx.getSelf().isDebugMode()) { |
105 | relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, relationType, th)); | 105 | relationTypes.forEach(relationType -> mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, relationType, th)); |
106 | } | 106 | } |
107 | - nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), relationTypes, msg, th != null ? th.getMessage() : null), nodeCtx.getSelfActor()); | 107 | + nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), relationTypes, msg, th != null ? th.getMessage() : null)); |
108 | } | 108 | } |
109 | 109 | ||
110 | @Override | 110 | @Override |
@@ -130,7 +130,7 @@ class DefaultTbContext implements TbContext { | @@ -130,7 +130,7 @@ class DefaultTbContext implements TbContext { | ||
130 | .setTenantIdMSB(getTenantId().getId().getMostSignificantBits()) | 130 | .setTenantIdMSB(getTenantId().getId().getMostSignificantBits()) |
131 | .setTenantIdLSB(getTenantId().getId().getLeastSignificantBits()) | 131 | .setTenantIdLSB(getTenantId().getId().getLeastSignificantBits()) |
132 | .setTbMsg(TbMsg.toByteString(tbMsg)).build(); | 132 | .setTbMsg(TbMsg.toByteString(tbMsg)).build(); |
133 | - mainCtx.getClusterService().pushMsgToRuleEngine(tpi, tbMsg.getId(), msg, new SimpleTbQueueCallback(onSuccess, onFailure)); | 133 | + mainCtx.getClusterService().pushMsgToRuleEngine(tpi, tbMsg.getId(), msg, new SimpleTbQueueCallback(onSuccess, onFailure)); |
134 | } | 134 | } |
135 | 135 | ||
136 | @Override | 136 | @Override |
@@ -187,7 +187,7 @@ class DefaultTbContext implements TbContext { | @@ -187,7 +187,7 @@ class DefaultTbContext implements TbContext { | ||
187 | if (failureMessage != null) { | 187 | if (failureMessage != null) { |
188 | msg.setFailureMessage(failureMessage); | 188 | msg.setFailureMessage(failureMessage); |
189 | } | 189 | } |
190 | - mainCtx.getClusterService().pushMsgToRuleEngine(tpi, tbMsg.getId(), msg.build(), new SimpleTbQueueCallback(onSuccess, onFailure)); | 190 | + mainCtx.getClusterService().pushMsgToRuleEngine(tpi, tbMsg.getId(), msg.build(), new SimpleTbQueueCallback(onSuccess, onFailure)); |
191 | } | 191 | } |
192 | 192 | ||
193 | @Override | 193 | @Override |
@@ -203,8 +203,8 @@ class DefaultTbContext implements TbContext { | @@ -203,8 +203,8 @@ class DefaultTbContext implements TbContext { | ||
203 | return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), entityId).isMyPartition(); | 203 | return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), entityId).isMyPartition(); |
204 | } | 204 | } |
205 | 205 | ||
206 | - private void scheduleMsgWithDelay(Object msg, long delayInMs, ActorRef target) { | ||
207 | - mainCtx.getScheduler().scheduleOnce(Duration.create(delayInMs, TimeUnit.MILLISECONDS), target, msg, mainCtx.getActorSystem().dispatcher(), nodeCtx.getSelfActor()); | 206 | + private void scheduleMsgWithDelay(TbActorMsg msg, long delayInMs, TbActorRef target) { |
207 | + mainCtx.scheduleMsgWithDelay(target, msg, delayInMs); | ||
208 | } | 208 | } |
209 | 209 | ||
210 | @Override | 210 | @Override |
@@ -213,7 +213,7 @@ class DefaultTbContext implements TbContext { | @@ -213,7 +213,7 @@ class DefaultTbContext implements TbContext { | ||
213 | mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, TbRelationTypes.FAILURE, th); | 213 | mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, TbRelationTypes.FAILURE, th); |
214 | } | 214 | } |
215 | nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), Collections.singleton(TbRelationTypes.FAILURE), | 215 | nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getId(), Collections.singleton(TbRelationTypes.FAILURE), |
216 | - msg, th != null ? th.getMessage() : null), nodeCtx.getSelfActor()); | 216 | + msg, th != null ? th.getMessage() : null)); |
217 | } | 217 | } |
218 | 218 | ||
219 | public void updateSelf(RuleNode self) { | 219 | public void updateSelf(RuleNode self) { |
@@ -15,9 +15,11 @@ | @@ -15,9 +15,11 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.ruleChain; | 16 | package org.thingsboard.server.actors.ruleChain; |
17 | 17 | ||
18 | -import akka.actor.OneForOneStrategy; | ||
19 | -import akka.actor.SupervisorStrategy; | ||
20 | import org.thingsboard.server.actors.ActorSystemContext; | 18 | import org.thingsboard.server.actors.ActorSystemContext; |
19 | +import org.thingsboard.server.actors.TbActor; | ||
20 | +import org.thingsboard.server.actors.TbActorCtx; | ||
21 | +import org.thingsboard.server.actors.TbActorId; | ||
22 | +import org.thingsboard.server.actors.TbEntityActorId; | ||
21 | import org.thingsboard.server.actors.service.ComponentActor; | 23 | import org.thingsboard.server.actors.service.ComponentActor; |
22 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 24 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
23 | import org.thingsboard.server.common.data.id.RuleChainId; | 25 | import org.thingsboard.server.common.data.id.RuleChainId; |
@@ -27,18 +29,24 @@ import org.thingsboard.server.common.msg.TbActorMsg; | @@ -27,18 +29,24 @@ import org.thingsboard.server.common.msg.TbActorMsg; | ||
27 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; | 29 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
28 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | 30 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; |
29 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | 31 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
30 | -import scala.concurrent.duration.Duration; | ||
31 | 32 | ||
32 | public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMessageProcessor> { | 33 | public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMessageProcessor> { |
33 | 34 | ||
35 | + private final RuleChain ruleChain; | ||
36 | + | ||
34 | private RuleChainActor(ActorSystemContext systemContext, TenantId tenantId, RuleChain ruleChain) { | 37 | private RuleChainActor(ActorSystemContext systemContext, TenantId tenantId, RuleChain ruleChain) { |
35 | super(systemContext, tenantId, ruleChain.getId()); | 38 | super(systemContext, tenantId, ruleChain.getId()); |
36 | - setProcessor(new RuleChainActorMessageProcessor(tenantId, ruleChain, systemContext, | ||
37 | - context().parent(), context().self())); | 39 | + this.ruleChain = ruleChain; |
38 | } | 40 | } |
39 | 41 | ||
40 | @Override | 42 | @Override |
41 | - protected boolean process(TbActorMsg msg) { | 43 | + protected RuleChainActorMessageProcessor createProcessor(TbActorCtx ctx) { |
44 | + return new RuleChainActorMessageProcessor(tenantId, ruleChain, systemContext, | ||
45 | + ctx.getParentRef(), ctx); | ||
46 | + } | ||
47 | + | ||
48 | + @Override | ||
49 | + protected boolean doProcess(TbActorMsg msg) { | ||
42 | switch (msg.getMsgType()) { | 50 | switch (msg.getMsgType()) { |
43 | case COMPONENT_LIFE_CYCLE_MSG: | 51 | case COMPONENT_LIFE_CYCLE_MSG: |
44 | onComponentLifecycleMsg((ComponentLifecycleMsg) msg); | 52 | onComponentLifecycleMsg((ComponentLifecycleMsg) msg); |
@@ -64,7 +72,7 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | @@ -64,7 +72,7 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | ||
64 | return true; | 72 | return true; |
65 | } | 73 | } |
66 | 74 | ||
67 | - public static class ActorCreator extends ContextBasedCreator<RuleChainActor> { | 75 | + public static class ActorCreator extends ContextBasedCreator { |
68 | private static final long serialVersionUID = 1L; | 76 | private static final long serialVersionUID = 1L; |
69 | 77 | ||
70 | private final TenantId tenantId; | 78 | private final TenantId tenantId; |
@@ -77,7 +85,12 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | @@ -77,7 +85,12 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | ||
77 | } | 85 | } |
78 | 86 | ||
79 | @Override | 87 | @Override |
80 | - public RuleChainActor create() { | 88 | + public TbActorId createActorId() { |
89 | + return new TbEntityActorId(ruleChain.getId()); | ||
90 | + } | ||
91 | + | ||
92 | + @Override | ||
93 | + public TbActor createActor() { | ||
81 | return new RuleChainActor(context, tenantId, ruleChain); | 94 | return new RuleChainActor(context, tenantId, ruleChain); |
82 | } | 95 | } |
83 | } | 96 | } |
@@ -87,13 +100,4 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | @@ -87,13 +100,4 @@ public class RuleChainActor extends ComponentActor<RuleChainId, RuleChainActorMe | ||
87 | return systemContext.getRuleChainErrorPersistFrequency(); | 100 | return systemContext.getRuleChainErrorPersistFrequency(); |
88 | } | 101 | } |
89 | 102 | ||
90 | - @Override | ||
91 | - public SupervisorStrategy supervisorStrategy() { | ||
92 | - return strategy; | ||
93 | - } | ||
94 | - | ||
95 | - private final SupervisorStrategy strategy = new OneForOneStrategy(3, Duration.create("1 minute"), t -> { | ||
96 | - logAndPersist("Unknown Failure", ActorSystemContext.toException(t)); | ||
97 | - return SupervisorStrategy.resume(); | ||
98 | - }); | ||
99 | } | 103 | } |
@@ -15,12 +15,12 @@ | @@ -15,12 +15,12 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.ruleChain; | 16 | package org.thingsboard.server.actors.ruleChain; |
17 | 17 | ||
18 | -import akka.actor.ActorContext; | ||
19 | -import akka.actor.ActorRef; | ||
20 | -import akka.actor.Props; | ||
21 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
22 | import org.thingsboard.rule.engine.api.TbRelationTypes; | 19 | import org.thingsboard.rule.engine.api.TbRelationTypes; |
23 | import org.thingsboard.server.actors.ActorSystemContext; | 20 | import org.thingsboard.server.actors.ActorSystemContext; |
21 | +import org.thingsboard.server.actors.TbActorCtx; | ||
22 | +import org.thingsboard.server.actors.TbActorRef; | ||
23 | +import org.thingsboard.server.actors.TbEntityActorId; | ||
24 | import org.thingsboard.server.actors.service.DefaultActorService; | 24 | import org.thingsboard.server.actors.service.DefaultActorService; |
25 | import org.thingsboard.server.actors.shared.ComponentMsgProcessor; | 25 | import org.thingsboard.server.actors.shared.ComponentMsgProcessor; |
26 | import org.thingsboard.server.common.data.EntityType; | 26 | import org.thingsboard.server.common.data.EntityType; |
@@ -62,8 +62,8 @@ import java.util.stream.Collectors; | @@ -62,8 +62,8 @@ import java.util.stream.Collectors; | ||
62 | @Slf4j | 62 | @Slf4j |
63 | public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleChainId> { | 63 | public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleChainId> { |
64 | 64 | ||
65 | - private final ActorRef parent; | ||
66 | - private final ActorRef self; | 65 | + private final TbActorRef parent; |
66 | + private final TbActorRef self; | ||
67 | private final Map<RuleNodeId, RuleNodeCtx> nodeActors; | 67 | private final Map<RuleNodeId, RuleNodeCtx> nodeActors; |
68 | private final Map<RuleNodeId, List<RuleNodeRelation>> nodeRoutes; | 68 | private final Map<RuleNodeId, List<RuleNodeRelation>> nodeRoutes; |
69 | private final RuleChainService service; | 69 | private final RuleChainService service; |
@@ -75,7 +75,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -75,7 +75,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
75 | private boolean started; | 75 | private boolean started; |
76 | 76 | ||
77 | RuleChainActorMessageProcessor(TenantId tenantId, RuleChain ruleChain, ActorSystemContext systemContext | 77 | RuleChainActorMessageProcessor(TenantId tenantId, RuleChain ruleChain, ActorSystemContext systemContext |
78 | - , ActorRef parent, ActorRef self) { | 78 | + , TbActorRef parent, TbActorRef self) { |
79 | super(systemContext, tenantId, ruleChain.getId()); | 79 | super(systemContext, tenantId, ruleChain.getId()); |
80 | this.ruleChainName = ruleChain.getName(); | 80 | this.ruleChainName = ruleChain.getName(); |
81 | this.parent = parent; | 81 | this.parent = parent; |
@@ -92,7 +92,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -92,7 +92,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
92 | } | 92 | } |
93 | 93 | ||
94 | @Override | 94 | @Override |
95 | - public void start(ActorContext context) { | 95 | + public void start(TbActorCtx context) { |
96 | if (!started) { | 96 | if (!started) { |
97 | RuleChain ruleChain = service.findRuleChainById(tenantId, entityId); | 97 | RuleChain ruleChain = service.findRuleChainById(tenantId, entityId); |
98 | if (ruleChain != null) { | 98 | if (ruleChain != null) { |
@@ -101,7 +101,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -101,7 +101,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
101 | // Creating and starting the actors; | 101 | // Creating and starting the actors; |
102 | for (RuleNode ruleNode : ruleNodeList) { | 102 | for (RuleNode ruleNode : ruleNodeList) { |
103 | log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); | 103 | log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); |
104 | - ActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); | 104 | + TbActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); |
105 | nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); | 105 | nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); |
106 | } | 106 | } |
107 | initRoutes(ruleChain, ruleNodeList); | 107 | initRoutes(ruleChain, ruleNodeList); |
@@ -113,7 +113,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -113,7 +113,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
113 | } | 113 | } |
114 | 114 | ||
115 | @Override | 115 | @Override |
116 | - public void onUpdate(ActorContext context) { | 116 | + public void onUpdate(TbActorCtx context) { |
117 | RuleChain ruleChain = service.findRuleChainById(tenantId, entityId); | 117 | RuleChain ruleChain = service.findRuleChainById(tenantId, entityId); |
118 | if (ruleChain != null) { | 118 | if (ruleChain != null) { |
119 | ruleChainName = ruleChain.getName(); | 119 | ruleChainName = ruleChain.getName(); |
@@ -123,12 +123,12 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -123,12 +123,12 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
123 | RuleNodeCtx existing = nodeActors.get(ruleNode.getId()); | 123 | RuleNodeCtx existing = nodeActors.get(ruleNode.getId()); |
124 | if (existing == null) { | 124 | if (existing == null) { |
125 | log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); | 125 | log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); |
126 | - ActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); | 126 | + TbActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); |
127 | nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); | 127 | nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); |
128 | } else { | 128 | } else { |
129 | log.trace("[{}][{}] Updating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); | 129 | log.trace("[{}][{}] Updating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); |
130 | existing.setSelf(ruleNode); | 130 | existing.setSelf(ruleNode); |
131 | - existing.getSelfActor().tell(new ComponentLifecycleMsg(tenantId, existing.getSelf().getId(), ComponentLifecycleEvent.UPDATED), self); | 131 | + existing.getSelfActor().tell(new ComponentLifecycleMsg(tenantId, existing.getSelf().getId(), ComponentLifecycleEvent.UPDATED)); |
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
@@ -137,7 +137,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -137,7 +137,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
137 | removedRules.forEach(ruleNodeId -> { | 137 | removedRules.forEach(ruleNodeId -> { |
138 | log.trace("[{}][{}] Removing rule node [{}]", tenantId, entityId, ruleNodeId); | 138 | log.trace("[{}][{}] Removing rule node [{}]", tenantId, entityId, ruleNodeId); |
139 | RuleNodeCtx removed = nodeActors.remove(ruleNodeId); | 139 | RuleNodeCtx removed = nodeActors.remove(ruleNodeId); |
140 | - removed.getSelfActor().tell(new ComponentLifecycleMsg(tenantId, removed.getSelf().getId(), ComponentLifecycleEvent.DELETED), self); | 140 | + removed.getSelfActor().tell(new ComponentLifecycleMsg(tenantId, removed.getSelf().getId(), ComponentLifecycleEvent.DELETED)); |
141 | }); | 141 | }); |
142 | 142 | ||
143 | initRoutes(ruleChain, ruleNodeList); | 143 | initRoutes(ruleChain, ruleNodeList); |
@@ -145,26 +145,23 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -145,26 +145,23 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
145 | } | 145 | } |
146 | 146 | ||
147 | @Override | 147 | @Override |
148 | - public void stop(ActorContext context) { | 148 | + public void stop(TbActorCtx ctx) { |
149 | log.trace("[{}][{}] Stopping rule chain with {} nodes", tenantId, entityId, nodeActors.size()); | 149 | log.trace("[{}][{}] Stopping rule chain with {} nodes", tenantId, entityId, nodeActors.size()); |
150 | - nodeActors.values().stream().map(RuleNodeCtx::getSelfActor).forEach(context::stop); | 150 | + nodeActors.values().stream().map(RuleNodeCtx::getSelfActor).map(TbActorRef::getActorId).forEach(ctx::stop); |
151 | nodeActors.clear(); | 151 | nodeActors.clear(); |
152 | nodeRoutes.clear(); | 152 | nodeRoutes.clear(); |
153 | - context.stop(self); | ||
154 | started = false; | 153 | started = false; |
155 | } | 154 | } |
156 | 155 | ||
157 | @Override | 156 | @Override |
158 | public void onPartitionChangeMsg(PartitionChangeMsg msg) { | 157 | public void onPartitionChangeMsg(PartitionChangeMsg msg) { |
159 | - nodeActors.values().stream().map(RuleNodeCtx::getSelfActor).forEach(actorRef -> actorRef.tell(msg, self)); | 158 | + nodeActors.values().stream().map(RuleNodeCtx::getSelfActor).forEach(actorRef -> actorRef.tell(msg)); |
160 | } | 159 | } |
161 | 160 | ||
162 | - private ActorRef createRuleNodeActor(ActorContext context, RuleNode ruleNode) { | ||
163 | - String dispatcherName = tenantId.getId().equals(EntityId.NULL_UUID) ? | ||
164 | - DefaultActorService.SYSTEM_RULE_DISPATCHER_NAME : DefaultActorService.TENANT_RULE_DISPATCHER_NAME; | ||
165 | - return context.actorOf( | ||
166 | - Props.create(new RuleNodeActor.ActorCreator(systemContext, tenantId, entityId, ruleNode.getName(), ruleNode.getId())) | ||
167 | - .withDispatcher(dispatcherName), ruleNode.getId().toString()); | 161 | + private TbActorRef createRuleNodeActor(TbActorCtx ctx, RuleNode ruleNode) { |
162 | + return ctx.getOrCreateChildActor(new TbEntityActorId(ruleNode.getId()), | ||
163 | + () -> DefaultActorService.RULE_DISPATCHER_NAME, | ||
164 | + () -> new RuleNodeActor.ActorCreator(systemContext, tenantId, entityId, ruleNode.getName(), ruleNode.getId())); | ||
168 | } | 165 | } |
169 | 166 | ||
170 | private void initRoutes(RuleChain ruleChain, List<RuleNode> ruleNodeList) { | 167 | private void initRoutes(RuleChain ruleChain, List<RuleNode> ruleNodeList) { |
@@ -303,7 +300,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -303,7 +300,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
303 | pushMsgToNode(nodeActors.get(new RuleNodeId(target.getId())), msg, fromRelationType); | 300 | pushMsgToNode(nodeActors.get(new RuleNodeId(target.getId())), msg, fromRelationType); |
304 | break; | 301 | break; |
305 | case RULE_CHAIN: | 302 | case RULE_CHAIN: |
306 | - parent.tell(new RuleChainToRuleChainMsg(new RuleChainId(target.getId()), entityId, msg, fromRelationType), self); | 303 | + parent.tell(new RuleChainToRuleChainMsg(new RuleChainId(target.getId()), entityId, msg, fromRelationType)); |
307 | break; | 304 | break; |
308 | } | 305 | } |
309 | } else { | 306 | } else { |
@@ -334,7 +331,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | @@ -334,7 +331,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh | ||
334 | 331 | ||
335 | private void pushMsgToNode(RuleNodeCtx nodeCtx, TbMsg msg, String fromRelationType) { | 332 | private void pushMsgToNode(RuleNodeCtx nodeCtx, TbMsg msg, String fromRelationType) { |
336 | if (nodeCtx != null) { | 333 | if (nodeCtx != null) { |
337 | - nodeCtx.getSelfActor().tell(new RuleChainToRuleNodeMsg(new DefaultTbContext(systemContext, nodeCtx), msg, fromRelationType), self); | 334 | + nodeCtx.getSelfActor().tell(new RuleChainToRuleNodeMsg(new DefaultTbContext(systemContext, nodeCtx), msg, fromRelationType)); |
338 | } else { | 335 | } else { |
339 | log.error("[{}][{}] RuleNodeCtx is empty", entityId, ruleChainName); | 336 | log.error("[{}][{}] RuleNodeCtx is empty", entityId, ruleChainName); |
340 | msg.getCallback().onFailure(new RuleEngineException("Rule Node CTX is empty")); | 337 | msg.getCallback().onFailure(new RuleEngineException("Rule Node CTX is empty")); |
@@ -15,21 +15,22 @@ | @@ -15,21 +15,22 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.ruleChain; | 16 | package org.thingsboard.server.actors.ruleChain; |
17 | 17 | ||
18 | -import akka.actor.ActorContext; | ||
19 | -import akka.actor.ActorRef; | ||
20 | -import akka.actor.Props; | ||
21 | -import com.google.common.collect.BiMap; | ||
22 | -import com.google.common.collect.HashBiMap; | ||
23 | import lombok.Getter; | 18 | import lombok.Getter; |
19 | +import lombok.extern.slf4j.Slf4j; | ||
24 | import org.thingsboard.server.actors.ActorSystemContext; | 20 | import org.thingsboard.server.actors.ActorSystemContext; |
21 | +import org.thingsboard.server.actors.TbActorRef; | ||
22 | +import org.thingsboard.server.actors.TbEntityActorId; | ||
23 | +import org.thingsboard.server.actors.TbEntityTypeActorIdPredicate; | ||
25 | import org.thingsboard.server.actors.service.ContextAwareActor; | 24 | import org.thingsboard.server.actors.service.ContextAwareActor; |
26 | import org.thingsboard.server.actors.service.DefaultActorService; | 25 | import org.thingsboard.server.actors.service.DefaultActorService; |
26 | +import org.thingsboard.server.actors.tenant.TenantActor; | ||
27 | import org.thingsboard.server.common.data.EntityType; | 27 | import org.thingsboard.server.common.data.EntityType; |
28 | import org.thingsboard.server.common.data.id.EntityId; | 28 | import org.thingsboard.server.common.data.id.EntityId; |
29 | import org.thingsboard.server.common.data.id.RuleChainId; | 29 | import org.thingsboard.server.common.data.id.RuleChainId; |
30 | import org.thingsboard.server.common.data.id.TenantId; | 30 | import org.thingsboard.server.common.data.id.TenantId; |
31 | import org.thingsboard.server.common.data.page.PageDataIterable; | 31 | import org.thingsboard.server.common.data.page.PageDataIterable; |
32 | import org.thingsboard.server.common.data.rule.RuleChain; | 32 | import org.thingsboard.server.common.data.rule.RuleChain; |
33 | +import org.thingsboard.server.common.msg.TbActorMsg; | ||
33 | import org.thingsboard.server.dao.rule.RuleChainService; | 34 | import org.thingsboard.server.dao.rule.RuleChainService; |
34 | 35 | ||
35 | import java.util.function.Function; | 36 | import java.util.function.Function; |
@@ -37,20 +38,19 @@ import java.util.function.Function; | @@ -37,20 +38,19 @@ import java.util.function.Function; | ||
37 | /** | 38 | /** |
38 | * Created by ashvayka on 15.03.18. | 39 | * Created by ashvayka on 15.03.18. |
39 | */ | 40 | */ |
41 | +@Slf4j | ||
40 | public abstract class RuleChainManagerActor extends ContextAwareActor { | 42 | public abstract class RuleChainManagerActor extends ContextAwareActor { |
41 | 43 | ||
42 | protected final TenantId tenantId; | 44 | protected final TenantId tenantId; |
43 | private final RuleChainService ruleChainService; | 45 | private final RuleChainService ruleChainService; |
44 | - private final BiMap<RuleChainId, ActorRef> actors; | ||
45 | @Getter | 46 | @Getter |
46 | protected RuleChain rootChain; | 47 | protected RuleChain rootChain; |
47 | @Getter | 48 | @Getter |
48 | - protected ActorRef rootChainActor; | 49 | + protected TbActorRef rootChainActor; |
49 | 50 | ||
50 | public RuleChainManagerActor(ActorSystemContext systemContext, TenantId tenantId) { | 51 | public RuleChainManagerActor(ActorSystemContext systemContext, TenantId tenantId) { |
51 | super(systemContext); | 52 | super(systemContext); |
52 | this.tenantId = tenantId; | 53 | this.tenantId = tenantId; |
53 | - this.actors = HashBiMap.create(); | ||
54 | this.ruleChainService = systemContext.getRuleChainService(); | 54 | this.ruleChainService = systemContext.getRuleChainService(); |
55 | } | 55 | } |
56 | 56 | ||
@@ -58,46 +58,41 @@ public abstract class RuleChainManagerActor extends ContextAwareActor { | @@ -58,46 +58,41 @@ public abstract class RuleChainManagerActor extends ContextAwareActor { | ||
58 | for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChains(tenantId, link), ContextAwareActor.ENTITY_PACK_LIMIT)) { | 58 | for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChains(tenantId, link), ContextAwareActor.ENTITY_PACK_LIMIT)) { |
59 | RuleChainId ruleChainId = ruleChain.getId(); | 59 | RuleChainId ruleChainId = ruleChain.getId(); |
60 | log.debug("[{}|{}] Creating rule chain actor", ruleChainId.getEntityType(), ruleChain.getId()); | 60 | log.debug("[{}|{}] Creating rule chain actor", ruleChainId.getEntityType(), ruleChain.getId()); |
61 | - //TODO: remove this cast making UUIDBased subclass of EntityId an interface and vice versa. | ||
62 | - ActorRef actorRef = getOrCreateActor(this.context(), ruleChainId, id -> ruleChain); | 61 | + TbActorRef actorRef = getOrCreateActor(ruleChainId, id -> ruleChain); |
63 | visit(ruleChain, actorRef); | 62 | visit(ruleChain, actorRef); |
64 | log.debug("[{}|{}] Rule Chain actor created.", ruleChainId.getEntityType(), ruleChainId.getId()); | 63 | log.debug("[{}|{}] Rule Chain actor created.", ruleChainId.getEntityType(), ruleChainId.getId()); |
65 | } | 64 | } |
66 | } | 65 | } |
67 | 66 | ||
68 | - protected void visit(RuleChain entity, ActorRef actorRef) { | 67 | + protected void visit(RuleChain entity, TbActorRef actorRef) { |
69 | if (entity != null && entity.isRoot()) { | 68 | if (entity != null && entity.isRoot()) { |
70 | rootChain = entity; | 69 | rootChain = entity; |
71 | rootChainActor = actorRef; | 70 | rootChainActor = actorRef; |
72 | } | 71 | } |
73 | } | 72 | } |
74 | 73 | ||
75 | - public ActorRef getOrCreateActor(akka.actor.ActorContext context, RuleChainId ruleChainId) { | ||
76 | - return getOrCreateActor(context, ruleChainId, eId -> ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, eId)); | 74 | + protected TbActorRef getOrCreateActor(RuleChainId ruleChainId) { |
75 | + return getOrCreateActor(ruleChainId, eId -> ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, eId)); | ||
77 | } | 76 | } |
78 | 77 | ||
79 | - public ActorRef getOrCreateActor(akka.actor.ActorContext context, RuleChainId ruleChainId, Function<RuleChainId, RuleChain> provider) { | ||
80 | - return actors.computeIfAbsent(ruleChainId, eId -> { | ||
81 | - RuleChain ruleChain = provider.apply(eId); | ||
82 | - return context.actorOf(Props.create(new RuleChainActor.ActorCreator(systemContext, tenantId, ruleChain)) | ||
83 | - .withDispatcher(DefaultActorService.TENANT_RULE_DISPATCHER_NAME), eId.toString()); | ||
84 | - }); | 78 | + protected TbActorRef getOrCreateActor(RuleChainId ruleChainId, Function<RuleChainId, RuleChain> provider) { |
79 | + return ctx.getOrCreateChildActor(new TbEntityActorId(ruleChainId), | ||
80 | + () -> DefaultActorService.RULE_DISPATCHER_NAME, | ||
81 | + () -> { | ||
82 | + RuleChain ruleChain = provider.apply(ruleChainId); | ||
83 | + return new RuleChainActor.ActorCreator(systemContext, tenantId, ruleChain); | ||
84 | + }); | ||
85 | } | 85 | } |
86 | 86 | ||
87 | - protected ActorRef getEntityActorRef(EntityId entityId) { | ||
88 | - ActorRef target = null; | 87 | + protected TbActorRef getEntityActorRef(EntityId entityId) { |
88 | + TbActorRef target = null; | ||
89 | if (entityId.getEntityType() == EntityType.RULE_CHAIN) { | 89 | if (entityId.getEntityType() == EntityType.RULE_CHAIN) { |
90 | - target = getOrCreateActor(this.context(), (RuleChainId) entityId); | 90 | + target = getOrCreateActor((RuleChainId) entityId); |
91 | } | 91 | } |
92 | return target; | 92 | return target; |
93 | } | 93 | } |
94 | 94 | ||
95 | - protected void broadcast(Object msg) { | ||
96 | - actors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender())); | 95 | + protected void broadcast(TbActorMsg msg) { |
96 | + ctx.broadcastToChildren(msg, new TbEntityTypeActorIdPredicate(EntityType.RULE_CHAIN)); | ||
97 | } | 97 | } |
98 | - | ||
99 | - public ActorRef get(RuleChainId id) { | ||
100 | - return actors.get(id); | ||
101 | - } | ||
102 | - | ||
103 | } | 98 | } |
@@ -15,31 +15,43 @@ | @@ -15,31 +15,43 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.ruleChain; | 16 | package org.thingsboard.server.actors.ruleChain; |
17 | 17 | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
18 | import org.thingsboard.server.actors.ActorSystemContext; | 19 | import org.thingsboard.server.actors.ActorSystemContext; |
20 | +import org.thingsboard.server.actors.TbActor; | ||
21 | +import org.thingsboard.server.actors.TbActorCtx; | ||
22 | +import org.thingsboard.server.actors.TbActorId; | ||
23 | +import org.thingsboard.server.actors.TbEntityActorId; | ||
19 | import org.thingsboard.server.actors.service.ComponentActor; | 24 | import org.thingsboard.server.actors.service.ComponentActor; |
20 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 25 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
21 | import org.thingsboard.server.common.data.id.RuleChainId; | 26 | import org.thingsboard.server.common.data.id.RuleChainId; |
22 | import org.thingsboard.server.common.data.id.RuleNodeId; | 27 | import org.thingsboard.server.common.data.id.RuleNodeId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 28 | import org.thingsboard.server.common.data.id.TenantId; |
29 | +import org.thingsboard.server.common.data.rule.RuleChain; | ||
24 | import org.thingsboard.server.common.msg.TbActorMsg; | 30 | import org.thingsboard.server.common.msg.TbActorMsg; |
25 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; | 31 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
26 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | 32 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; |
27 | 33 | ||
34 | +@Slf4j | ||
28 | public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessageProcessor> { | 35 | public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessageProcessor> { |
29 | 36 | ||
30 | private final String ruleChainName; | 37 | private final String ruleChainName; |
31 | private final RuleChainId ruleChainId; | 38 | private final RuleChainId ruleChainId; |
39 | + private final RuleNodeId ruleNodeId; | ||
32 | 40 | ||
33 | private RuleNodeActor(ActorSystemContext systemContext, TenantId tenantId, RuleChainId ruleChainId, String ruleChainName, RuleNodeId ruleNodeId) { | 41 | private RuleNodeActor(ActorSystemContext systemContext, TenantId tenantId, RuleChainId ruleChainId, String ruleChainName, RuleNodeId ruleNodeId) { |
34 | super(systemContext, tenantId, ruleNodeId); | 42 | super(systemContext, tenantId, ruleNodeId); |
35 | this.ruleChainName = ruleChainName; | 43 | this.ruleChainName = ruleChainName; |
36 | this.ruleChainId = ruleChainId; | 44 | this.ruleChainId = ruleChainId; |
37 | - setProcessor(new RuleNodeActorMessageProcessor(tenantId, this.ruleChainName, ruleNodeId, systemContext, | ||
38 | - context().parent(), context().self())); | 45 | + this.ruleNodeId = ruleNodeId; |
39 | } | 46 | } |
40 | 47 | ||
41 | @Override | 48 | @Override |
42 | - protected boolean process(TbActorMsg msg) { | 49 | + protected RuleNodeActorMessageProcessor createProcessor(TbActorCtx ctx) { |
50 | + return new RuleNodeActorMessageProcessor(tenantId, this.ruleChainName, ruleNodeId, systemContext, ctx.getParentRef(), ctx); | ||
51 | + } | ||
52 | + | ||
53 | + @Override | ||
54 | + protected boolean doProcess(TbActorMsg msg) { | ||
43 | switch (msg.getMsgType()) { | 55 | switch (msg.getMsgType()) { |
44 | case COMPONENT_LIFE_CYCLE_MSG: | 56 | case COMPONENT_LIFE_CYCLE_MSG: |
45 | onComponentLifecycleMsg((ComponentLifecycleMsg) msg); | 57 | onComponentLifecycleMsg((ComponentLifecycleMsg) msg); |
@@ -93,8 +105,7 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa | @@ -93,8 +105,7 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa | ||
93 | logAndPersist("onRuleMsg", ActorSystemContext.toException(msg.getError())); | 105 | logAndPersist("onRuleMsg", ActorSystemContext.toException(msg.getError())); |
94 | } | 106 | } |
95 | 107 | ||
96 | - public static class ActorCreator extends ContextBasedCreator<RuleNodeActor> { | ||
97 | - private static final long serialVersionUID = 1L; | 108 | + public static class ActorCreator extends ContextBasedCreator { |
98 | 109 | ||
99 | private final TenantId tenantId; | 110 | private final TenantId tenantId; |
100 | private final RuleChainId ruleChainId; | 111 | private final RuleChainId ruleChainId; |
@@ -111,7 +122,12 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa | @@ -111,7 +122,12 @@ public class RuleNodeActor extends ComponentActor<RuleNodeId, RuleNodeActorMessa | ||
111 | } | 122 | } |
112 | 123 | ||
113 | @Override | 124 | @Override |
114 | - public RuleNodeActor create() throws Exception { | 125 | + public TbActorId createActorId() { |
126 | + return new TbEntityActorId(ruleNodeId); | ||
127 | + } | ||
128 | + | ||
129 | + @Override | ||
130 | + public TbActor createActor() { | ||
115 | return new RuleNodeActor(context, tenantId, ruleChainId, ruleChainName, ruleNodeId); | 131 | return new RuleNodeActor(context, tenantId, ruleChainId, ruleChainName, ruleNodeId); |
116 | } | 132 | } |
117 | } | 133 | } |
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
@@ -15,11 +15,11 @@ | @@ -15,11 +15,11 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.ruleChain; | 16 | package org.thingsboard.server.actors.ruleChain; |
17 | 17 | ||
18 | -import akka.actor.ActorContext; | ||
19 | -import akka.actor.ActorRef; | ||
20 | import org.thingsboard.rule.engine.api.TbNode; | 18 | import org.thingsboard.rule.engine.api.TbNode; |
21 | import org.thingsboard.rule.engine.api.TbNodeConfiguration; | 19 | import org.thingsboard.rule.engine.api.TbNodeConfiguration; |
22 | import org.thingsboard.server.actors.ActorSystemContext; | 20 | import org.thingsboard.server.actors.ActorSystemContext; |
21 | +import org.thingsboard.server.actors.TbActorCtx; | ||
22 | +import org.thingsboard.server.actors.TbActorRef; | ||
23 | import org.thingsboard.server.actors.shared.ComponentMsgProcessor; | 23 | import org.thingsboard.server.actors.shared.ComponentMsgProcessor; |
24 | import org.thingsboard.server.common.data.id.RuleNodeId; | 24 | import org.thingsboard.server.common.data.id.RuleNodeId; |
25 | import org.thingsboard.server.common.data.id.TenantId; | 25 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -34,13 +34,13 @@ import org.thingsboard.server.common.msg.queue.RuleNodeException; | @@ -34,13 +34,13 @@ import org.thingsboard.server.common.msg.queue.RuleNodeException; | ||
34 | public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNodeId> { | 34 | public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNodeId> { |
35 | 35 | ||
36 | private final String ruleChainName; | 36 | private final String ruleChainName; |
37 | - private final ActorRef self; | 37 | + private final TbActorRef self; |
38 | private RuleNode ruleNode; | 38 | private RuleNode ruleNode; |
39 | private TbNode tbNode; | 39 | private TbNode tbNode; |
40 | private DefaultTbContext defaultCtx; | 40 | private DefaultTbContext defaultCtx; |
41 | 41 | ||
42 | RuleNodeActorMessageProcessor(TenantId tenantId, String ruleChainName, RuleNodeId ruleNodeId, ActorSystemContext systemContext | 42 | RuleNodeActorMessageProcessor(TenantId tenantId, String ruleChainName, RuleNodeId ruleNodeId, ActorSystemContext systemContext |
43 | - , ActorRef parent, ActorRef self) { | 43 | + , TbActorRef parent, TbActorRef self) { |
44 | super(systemContext, tenantId, ruleNodeId); | 44 | super(systemContext, tenantId, ruleNodeId); |
45 | this.ruleChainName = ruleChainName; | 45 | this.ruleChainName = ruleChainName; |
46 | this.self = self; | 46 | this.self = self; |
@@ -49,7 +49,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod | @@ -49,7 +49,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod | ||
49 | } | 49 | } |
50 | 50 | ||
51 | @Override | 51 | @Override |
52 | - public void start(ActorContext context) throws Exception { | 52 | + public void start(TbActorCtx context) throws Exception { |
53 | tbNode = initComponent(ruleNode); | 53 | tbNode = initComponent(ruleNode); |
54 | if (tbNode != null) { | 54 | if (tbNode != null) { |
55 | state = ComponentLifecycleState.ACTIVE; | 55 | state = ComponentLifecycleState.ACTIVE; |
@@ -57,7 +57,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod | @@ -57,7 +57,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod | ||
57 | } | 57 | } |
58 | 58 | ||
59 | @Override | 59 | @Override |
60 | - public void onUpdate(ActorContext context) throws Exception { | 60 | + public void onUpdate(TbActorCtx context) throws Exception { |
61 | RuleNode newRuleNode = systemContext.getRuleChainService().findRuleNodeById(tenantId, entityId); | 61 | RuleNode newRuleNode = systemContext.getRuleChainService().findRuleNodeById(tenantId, entityId); |
62 | boolean restartRequired = state != ComponentLifecycleState.ACTIVE || | 62 | boolean restartRequired = state != ComponentLifecycleState.ACTIVE || |
63 | !(ruleNode.getType().equals(newRuleNode.getType()) && ruleNode.getConfiguration().equals(newRuleNode.getConfiguration())); | 63 | !(ruleNode.getType().equals(newRuleNode.getType()) && ruleNode.getConfiguration().equals(newRuleNode.getConfiguration())); |
@@ -72,11 +72,11 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod | @@ -72,11 +72,11 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod | ||
72 | } | 72 | } |
73 | 73 | ||
74 | @Override | 74 | @Override |
75 | - public void stop(ActorContext context) { | 75 | + public void stop(TbActorCtx context) { |
76 | if (tbNode != null) { | 76 | if (tbNode != null) { |
77 | tbNode.destroy(); | 77 | tbNode.destroy(); |
78 | + state = ComponentLifecycleState.SUSPENDED; | ||
78 | } | 79 | } |
79 | - context.stop(self); | ||
80 | } | 80 | } |
81 | 81 | ||
82 | @Override | 82 | @Override |
@@ -15,9 +15,9 @@ | @@ -15,9 +15,9 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.ruleChain; | 16 | package org.thingsboard.server.actors.ruleChain; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | import lombok.AllArgsConstructor; | 18 | import lombok.AllArgsConstructor; |
20 | import lombok.Data; | 19 | import lombok.Data; |
20 | +import org.thingsboard.server.actors.TbActorRef; | ||
21 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
22 | import org.thingsboard.server.common.data.rule.RuleNode; | 22 | import org.thingsboard.server.common.data.rule.RuleNode; |
23 | 23 | ||
@@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.rule.RuleNode; | @@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.rule.RuleNode; | ||
28 | @AllArgsConstructor | 28 | @AllArgsConstructor |
29 | final class RuleNodeCtx { | 29 | final class RuleNodeCtx { |
30 | private final TenantId tenantId; | 30 | private final TenantId tenantId; |
31 | - private final ActorRef chainActor; | ||
32 | - private final ActorRef selfActor; | 31 | + private final TbActorRef chainActor; |
32 | + private final TbActorRef selfActor; | ||
33 | private RuleNode self; | 33 | private RuleNode self; |
34 | } | 34 | } |
@@ -15,19 +15,21 @@ | @@ -15,19 +15,21 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.service; | 16 | package org.thingsboard.server.actors.service; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | 18 | +import lombok.extern.slf4j.Slf4j; |
19 | import org.thingsboard.server.actors.ActorSystemContext; | 19 | import org.thingsboard.server.actors.ActorSystemContext; |
20 | +import org.thingsboard.server.actors.TbActorCtx; | ||
20 | import org.thingsboard.server.actors.shared.ComponentMsgProcessor; | 21 | import org.thingsboard.server.actors.shared.ComponentMsgProcessor; |
21 | import org.thingsboard.server.actors.stats.StatsPersistMsg; | 22 | import org.thingsboard.server.actors.stats.StatsPersistMsg; |
22 | import org.thingsboard.server.common.data.id.EntityId; | 23 | import org.thingsboard.server.common.data.id.EntityId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 24 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | 25 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; |
25 | -import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | ||
26 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; | 26 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
27 | +import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | ||
27 | 28 | ||
28 | /** | 29 | /** |
29 | * @author Andrew Shvayka | 30 | * @author Andrew Shvayka |
30 | */ | 31 | */ |
32 | +@Slf4j | ||
31 | public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgProcessor<T>> extends ContextAwareActor { | 33 | public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgProcessor<T>> extends ContextAwareActor { |
32 | 34 | ||
33 | private long lastPersistedErrorTs = 0L; | 35 | private long lastPersistedErrorTs = 0L; |
@@ -43,15 +45,19 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | @@ -43,15 +45,19 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | ||
43 | this.id = id; | 45 | this.id = id; |
44 | } | 46 | } |
45 | 47 | ||
46 | - protected void setProcessor(P processor) { | ||
47 | - this.processor = processor; | ||
48 | - } | 48 | + abstract protected P createProcessor(TbActorCtx ctx); |
49 | 49 | ||
50 | @Override | 50 | @Override |
51 | - public void preStart() { | 51 | + public void init(TbActorCtx ctx) { |
52 | + super.init(ctx); | ||
53 | + this.processor = createProcessor(ctx); | ||
54 | + initProcessor(ctx); | ||
55 | + } | ||
56 | + | ||
57 | + protected void initProcessor(TbActorCtx ctx) { | ||
52 | try { | 58 | try { |
53 | log.debug("[{}][{}][{}] Starting processor.", tenantId, id, id.getEntityType()); | 59 | log.debug("[{}][{}][{}] Starting processor.", tenantId, id, id.getEntityType()); |
54 | - processor.start(context()); | 60 | + processor.start(ctx); |
55 | logLifecycleEvent(ComponentLifecycleEvent.STARTED); | 61 | logLifecycleEvent(ComponentLifecycleEvent.STARTED); |
56 | if (systemContext.isStatisticsEnabled()) { | 62 | if (systemContext.isStatisticsEnabled()) { |
57 | scheduleStatsPersistTick(); | 63 | scheduleStatsPersistTick(); |
@@ -66,7 +72,7 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | @@ -66,7 +72,7 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | ||
66 | 72 | ||
67 | private void scheduleStatsPersistTick() { | 73 | private void scheduleStatsPersistTick() { |
68 | try { | 74 | try { |
69 | - processor.scheduleStatsPersistTick(context(), systemContext.getStatisticsPersistFrequency()); | 75 | + processor.scheduleStatsPersistTick(ctx, systemContext.getStatisticsPersistFrequency()); |
70 | } catch (Exception e) { | 76 | } catch (Exception e) { |
71 | log.error("[{}][{}] Failed to schedule statistics store message. No statistics is going to be stored: {}", tenantId, id, e.getMessage()); | 77 | log.error("[{}][{}] Failed to schedule statistics store message. No statistics is going to be stored: {}", tenantId, id, e.getMessage()); |
72 | logAndPersist("onScheduleStatsPersistMsg", e); | 78 | logAndPersist("onScheduleStatsPersistMsg", e); |
@@ -74,10 +80,10 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | @@ -74,10 +80,10 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | ||
74 | } | 80 | } |
75 | 81 | ||
76 | @Override | 82 | @Override |
77 | - public void postStop() { | 83 | + public void destroy() { |
78 | try { | 84 | try { |
79 | - log.debug("[{}][{}] Stopping processor.", tenantId, id, id.getEntityType()); | ||
80 | - processor.stop(context()); | 85 | + log.debug("[{}][{}][{}] Stopping processor.", tenantId, id, id.getEntityType()); |
86 | + processor.stop(ctx); | ||
81 | logLifecycleEvent(ComponentLifecycleEvent.STOPPED); | 87 | logLifecycleEvent(ComponentLifecycleEvent.STOPPED); |
82 | } catch (Exception e) { | 88 | } catch (Exception e) { |
83 | log.warn("[{}][{}] Failed to stop {} processor: {}", tenantId, id, id.getEntityType(), e.getMessage()); | 89 | log.warn("[{}][{}] Failed to stop {} processor: {}", tenantId, id, id.getEntityType(), e.getMessage()); |
@@ -91,19 +97,20 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | @@ -91,19 +97,20 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | ||
91 | try { | 97 | try { |
92 | switch (msg.getEvent()) { | 98 | switch (msg.getEvent()) { |
93 | case CREATED: | 99 | case CREATED: |
94 | - processor.onCreated(context()); | 100 | + processor.onCreated(ctx); |
95 | break; | 101 | break; |
96 | case UPDATED: | 102 | case UPDATED: |
97 | - processor.onUpdate(context()); | 103 | + processor.onUpdate(ctx); |
98 | break; | 104 | break; |
99 | case ACTIVATED: | 105 | case ACTIVATED: |
100 | - processor.onActivate(context()); | 106 | + processor.onActivate(ctx); |
101 | break; | 107 | break; |
102 | case SUSPENDED: | 108 | case SUSPENDED: |
103 | - processor.onSuspend(context()); | 109 | + processor.onSuspend(ctx); |
104 | break; | 110 | break; |
105 | case DELETED: | 111 | case DELETED: |
106 | - processor.onStop(context()); | 112 | + processor.onStop(ctx); |
113 | + ctx.stop(ctx.getSelf()); | ||
107 | break; | 114 | break; |
108 | default: | 115 | default: |
109 | break; | 116 | break; |
@@ -125,7 +132,7 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | @@ -125,7 +132,7 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | ||
125 | 132 | ||
126 | protected void onStatsPersistTick(EntityId entityId) { | 133 | protected void onStatsPersistTick(EntityId entityId) { |
127 | try { | 134 | try { |
128 | - systemContext.getStatsActor().tell(new StatsPersistMsg(messagesProcessed, errorsOccurred, tenantId, entityId), ActorRef.noSender()); | 135 | + systemContext.getStatsActor().tell(new StatsPersistMsg(messagesProcessed, errorsOccurred, tenantId, entityId)); |
129 | resetStatsCounters(); | 136 | resetStatsCounters(); |
130 | } catch (Exception e) { | 137 | } catch (Exception e) { |
131 | logAndPersist("onStatsPersistTick", e); | 138 | logAndPersist("onStatsPersistTick", e); |
@@ -149,10 +156,10 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | @@ -149,10 +156,10 @@ public abstract class ComponentActor<T extends EntityId, P extends ComponentMsgP | ||
149 | errorsOccurred++; | 156 | errorsOccurred++; |
150 | String componentName = processor != null ? processor.getComponentName() : "Unknown"; | 157 | String componentName = processor != null ? processor.getComponentName() : "Unknown"; |
151 | if (critical) { | 158 | if (critical) { |
152 | - log.warn("[{}][{}][{}] Failed to process {} msg: {}", id, tenantId, componentName, method); | 159 | + log.warn("[{}][{}][{}] Failed to process method: {}", id, tenantId, componentName, method); |
153 | log.warn("Critical Error: ", e); | 160 | log.warn("Critical Error: ", e); |
154 | } else { | 161 | } else { |
155 | - log.debug("[{}][{}][{}] Failed to process {} msg: {}", id, tenantId, componentName, method); | 162 | + log.debug("[{}][{}][{}] Failed to process method: {}", id, tenantId, componentName, method); |
156 | log.debug("Debug Error: ", e); | 163 | log.debug("Debug Error: ", e); |
157 | } | 164 | } |
158 | long ts = System.currentTimeMillis(); | 165 | long ts = System.currentTimeMillis(); |
@@ -15,17 +15,18 @@ | @@ -15,17 +15,18 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.service; | 16 | package org.thingsboard.server.actors.service; |
17 | 17 | ||
18 | -import akka.actor.Terminated; | ||
19 | -import akka.actor.UntypedAbstractActor; | 18 | +import lombok.extern.slf4j.Slf4j; |
20 | import org.slf4j.Logger; | 19 | import org.slf4j.Logger; |
21 | import org.slf4j.LoggerFactory; | 20 | import org.slf4j.LoggerFactory; |
21 | +import org.thingsboard.server.actors.AbstractTbActor; | ||
22 | import org.thingsboard.server.actors.ActorSystemContext; | 22 | import org.thingsboard.server.actors.ActorSystemContext; |
23 | +import org.thingsboard.server.actors.ProcessFailureStrategy; | ||
24 | +import org.thingsboard.server.actors.TbActor; | ||
25 | +import org.thingsboard.server.actors.TbActorCtx; | ||
23 | import org.thingsboard.server.common.msg.TbActorMsg; | 26 | import org.thingsboard.server.common.msg.TbActorMsg; |
24 | 27 | ||
25 | - | ||
26 | -public abstract class ContextAwareActor extends UntypedAbstractActor { | ||
27 | - | ||
28 | - protected final Logger log = LoggerFactory.getLogger(getClass()); | 28 | +@Slf4j |
29 | +public abstract class ContextAwareActor extends AbstractTbActor { | ||
29 | 30 | ||
30 | public static final int ENTITY_PACK_LIMIT = 1024; | 31 | public static final int ENTITY_PACK_LIMIT = 1024; |
31 | 32 | ||
@@ -37,27 +38,29 @@ public abstract class ContextAwareActor extends UntypedAbstractActor { | @@ -37,27 +38,29 @@ public abstract class ContextAwareActor extends UntypedAbstractActor { | ||
37 | } | 38 | } |
38 | 39 | ||
39 | @Override | 40 | @Override |
40 | - public void onReceive(Object msg) { | 41 | + public boolean process(TbActorMsg msg) { |
41 | if (log.isDebugEnabled()) { | 42 | if (log.isDebugEnabled()) { |
42 | log.debug("Processing msg: {}", msg); | 43 | log.debug("Processing msg: {}", msg); |
43 | } | 44 | } |
44 | - if (msg instanceof TbActorMsg) { | ||
45 | - try { | ||
46 | - if (!process((TbActorMsg) msg)) { | ||
47 | - log.warn("Unknown message: {}!", msg); | ||
48 | - } | ||
49 | - } catch (Exception e) { | ||
50 | - throw e; | ||
51 | - } | ||
52 | - } else if (msg instanceof Terminated) { | ||
53 | - processTermination((Terminated) msg); | ||
54 | - } else { | ||
55 | - log.warn("Unknown message: {}!", msg); | 45 | + if (!doProcess(msg)) { |
46 | + log.warn("Unprocessed message: {}!", msg); | ||
56 | } | 47 | } |
48 | + return false; | ||
57 | } | 49 | } |
58 | 50 | ||
59 | - protected void processTermination(Terminated msg) { | 51 | + protected abstract boolean doProcess(TbActorMsg msg); |
52 | + | ||
53 | + @Override | ||
54 | + public ProcessFailureStrategy onProcessFailure(Throwable t) { | ||
55 | + log.debug("[{}] Processing failure: ", getActorRef().getActorId(), t); | ||
56 | + return doProcessFailure(t); | ||
60 | } | 57 | } |
61 | 58 | ||
62 | - protected abstract boolean process(TbActorMsg msg); | 59 | + protected ProcessFailureStrategy doProcessFailure(Throwable t) { |
60 | + if (t instanceof Error) { | ||
61 | + return ProcessFailureStrategy.stop(); | ||
62 | + } else { | ||
63 | + return ProcessFailureStrategy.resume(); | ||
64 | + } | ||
65 | + } | ||
63 | } | 66 | } |
@@ -15,12 +15,10 @@ | @@ -15,12 +15,10 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.service; | 16 | package org.thingsboard.server.actors.service; |
17 | 17 | ||
18 | -import akka.japi.Creator; | ||
19 | import org.thingsboard.server.actors.ActorSystemContext; | 18 | import org.thingsboard.server.actors.ActorSystemContext; |
19 | +import org.thingsboard.server.actors.TbActorCreator; | ||
20 | 20 | ||
21 | -public abstract class ContextBasedCreator<T> implements Creator<T> { | ||
22 | - | ||
23 | - private static final long serialVersionUID = 1L; | 21 | +public abstract class ContextBasedCreator implements TbActorCreator { |
24 | 22 | ||
25 | protected final transient ActorSystemContext context; | 23 | protected final transient ActorSystemContext context; |
26 | 24 |
@@ -15,85 +15,116 @@ | @@ -15,85 +15,116 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.service; | 16 | package org.thingsboard.server.actors.service; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | -import akka.actor.ActorSystem; | ||
20 | -import akka.actor.Props; | ||
21 | -import akka.actor.Terminated; | ||
22 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
23 | import org.springframework.beans.factory.annotation.Autowired; | 19 | import org.springframework.beans.factory.annotation.Autowired; |
24 | import org.springframework.beans.factory.annotation.Value; | 20 | import org.springframework.beans.factory.annotation.Value; |
25 | import org.springframework.boot.context.event.ApplicationReadyEvent; | 21 | import org.springframework.boot.context.event.ApplicationReadyEvent; |
26 | import org.springframework.context.event.EventListener; | 22 | import org.springframework.context.event.EventListener; |
27 | -import org.springframework.scheduling.annotation.Scheduled; | ||
28 | import org.springframework.stereotype.Service; | 23 | import org.springframework.stereotype.Service; |
29 | import org.thingsboard.server.actors.ActorSystemContext; | 24 | import org.thingsboard.server.actors.ActorSystemContext; |
25 | +import org.thingsboard.server.actors.DefaultTbActorSystem; | ||
26 | +import org.thingsboard.server.actors.TbActorId; | ||
27 | +import org.thingsboard.server.actors.TbActorRef; | ||
28 | +import org.thingsboard.server.actors.TbActorSystem; | ||
29 | +import org.thingsboard.server.actors.TbActorSystemSettings; | ||
30 | import org.thingsboard.server.actors.app.AppActor; | 30 | import org.thingsboard.server.actors.app.AppActor; |
31 | import org.thingsboard.server.actors.app.AppInitMsg; | 31 | import org.thingsboard.server.actors.app.AppInitMsg; |
32 | import org.thingsboard.server.actors.stats.StatsActor; | 32 | import org.thingsboard.server.actors.stats.StatsActor; |
33 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | 33 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; |
34 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 34 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; |
35 | -import scala.concurrent.Await; | ||
36 | -import scala.concurrent.Future; | ||
37 | -import scala.concurrent.duration.Duration; | ||
38 | 35 | ||
39 | import javax.annotation.PostConstruct; | 36 | import javax.annotation.PostConstruct; |
40 | import javax.annotation.PreDestroy; | 37 | import javax.annotation.PreDestroy; |
41 | -import java.util.concurrent.atomic.AtomicInteger; | 38 | +import java.util.concurrent.ExecutorService; |
39 | +import java.util.concurrent.Executors; | ||
40 | +import java.util.concurrent.ScheduledExecutorService; | ||
42 | 41 | ||
43 | @Service | 42 | @Service |
44 | @Slf4j | 43 | @Slf4j |
45 | public class DefaultActorService implements ActorService { | 44 | public class DefaultActorService implements ActorService { |
46 | 45 | ||
47 | - private static final String ACTOR_SYSTEM_NAME = "Akka"; | ||
48 | - | ||
49 | public static final String APP_DISPATCHER_NAME = "app-dispatcher"; | 46 | public static final String APP_DISPATCHER_NAME = "app-dispatcher"; |
50 | - public static final String CORE_DISPATCHER_NAME = "core-dispatcher"; | ||
51 | - public static final String SYSTEM_RULE_DISPATCHER_NAME = "system-rule-dispatcher"; | ||
52 | - public static final String TENANT_RULE_DISPATCHER_NAME = "rule-dispatcher"; | 47 | + public static final String TENANT_DISPATCHER_NAME = "tenant-dispatcher"; |
48 | + public static final String DEVICE_DISPATCHER_NAME = "device-dispatcher"; | ||
49 | + public static final String RULE_DISPATCHER_NAME = "rule-dispatcher"; | ||
53 | 50 | ||
54 | @Autowired | 51 | @Autowired |
55 | private ActorSystemContext actorContext; | 52 | private ActorSystemContext actorContext; |
56 | 53 | ||
57 | - private ActorSystem system; | 54 | + private TbActorSystem system; |
55 | + | ||
56 | + private TbActorRef appActor; | ||
57 | + | ||
58 | + @Value("${actors.system.throughput:5}") | ||
59 | + private int actorThroughput; | ||
60 | + | ||
61 | + @Value("${actors.system.max_actor_init_attempts:10}") | ||
62 | + private int maxActorInitAttempts; | ||
63 | + | ||
64 | + @Value("${actors.system.scheduler_pool_size:1}") | ||
65 | + private int schedulerPoolSize; | ||
66 | + | ||
67 | + @Value("${actors.system.app_dispatcher_pool_size:1}") | ||
68 | + private int appDispatcherSize; | ||
69 | + | ||
70 | + @Value("${actors.system.tenant_dispatcher_pool_size:2}") | ||
71 | + private int tenantDispatcherSize; | ||
58 | 72 | ||
59 | - private ActorRef appActor; | 73 | + @Value("${actors.system.device_dispatcher_pool_size:4}") |
74 | + private int deviceDispatcherSize; | ||
75 | + | ||
76 | + @Value("${actors.system.rule_dispatcher_pool_size:4}") | ||
77 | + private int ruleDispatcherSize; | ||
60 | 78 | ||
61 | @PostConstruct | 79 | @PostConstruct |
62 | public void initActorSystem() { | 80 | public void initActorSystem() { |
63 | - log.info("Initializing Actor system."); | 81 | + log.info("Initializing actor system."); |
64 | actorContext.setActorService(this); | 82 | actorContext.setActorService(this); |
65 | - system = ActorSystem.create(ACTOR_SYSTEM_NAME, actorContext.getConfig()); | 83 | + TbActorSystemSettings settings = new TbActorSystemSettings(actorThroughput, schedulerPoolSize, maxActorInitAttempts); |
84 | + system = new DefaultTbActorSystem(settings); | ||
85 | + | ||
86 | + system.createDispatcher(APP_DISPATCHER_NAME, initDispatcherExecutor(appDispatcherSize)); | ||
87 | + system.createDispatcher(TENANT_DISPATCHER_NAME, initDispatcherExecutor(tenantDispatcherSize)); | ||
88 | + system.createDispatcher(DEVICE_DISPATCHER_NAME, initDispatcherExecutor(deviceDispatcherSize)); | ||
89 | + system.createDispatcher(RULE_DISPATCHER_NAME, initDispatcherExecutor(ruleDispatcherSize)); | ||
90 | + | ||
66 | actorContext.setActorSystem(system); | 91 | actorContext.setActorSystem(system); |
67 | 92 | ||
68 | - appActor = system.actorOf(Props.create(new AppActor.ActorCreator(actorContext)).withDispatcher(APP_DISPATCHER_NAME), "appActor"); | 93 | + appActor = system.createRootActor(APP_DISPATCHER_NAME, new AppActor.ActorCreator(actorContext)); |
69 | actorContext.setAppActor(appActor); | 94 | actorContext.setAppActor(appActor); |
70 | 95 | ||
71 | - ActorRef statsActor = system.actorOf(Props.create(new StatsActor.ActorCreator(actorContext)).withDispatcher(CORE_DISPATCHER_NAME), "statsActor"); | 96 | + TbActorRef statsActor = system.createRootActor(TENANT_DISPATCHER_NAME, new StatsActor.ActorCreator(actorContext, "StatsActor")); |
72 | actorContext.setStatsActor(statsActor); | 97 | actorContext.setStatsActor(statsActor); |
73 | 98 | ||
74 | log.info("Actor system initialized."); | 99 | log.info("Actor system initialized."); |
75 | } | 100 | } |
76 | 101 | ||
102 | + private ExecutorService initDispatcherExecutor(int poolSize) { | ||
103 | + if (poolSize == 0) { | ||
104 | + int cores = Runtime.getRuntime().availableProcessors(); | ||
105 | + poolSize = Math.max(1, cores / 2); | ||
106 | + } | ||
107 | + return Executors.newWorkStealingPool(poolSize); | ||
108 | + } | ||
109 | + | ||
77 | @EventListener(ApplicationReadyEvent.class) | 110 | @EventListener(ApplicationReadyEvent.class) |
78 | public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { | 111 | public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { |
79 | log.info("Received application ready event. Sending application init message to actor system"); | 112 | log.info("Received application ready event. Sending application init message to actor system"); |
80 | - appActor.tell(new AppInitMsg(), ActorRef.noSender()); | 113 | + appActor.tell(new AppInitMsg()); |
81 | } | 114 | } |
82 | 115 | ||
83 | @EventListener(PartitionChangeEvent.class) | 116 | @EventListener(PartitionChangeEvent.class) |
84 | public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) { | 117 | public void onApplicationEvent(PartitionChangeEvent partitionChangeEvent) { |
85 | log.info("Received partition change event."); | 118 | log.info("Received partition change event."); |
86 | - this.appActor.tell(new PartitionChangeMsg(partitionChangeEvent.getServiceQueueKey(), partitionChangeEvent.getPartitions()), ActorRef.noSender()); | 119 | + this.appActor.tell(new PartitionChangeMsg(partitionChangeEvent.getServiceQueueKey(), partitionChangeEvent.getPartitions())); |
87 | } | 120 | } |
88 | 121 | ||
89 | @PreDestroy | 122 | @PreDestroy |
90 | public void stopActorSystem() { | 123 | public void stopActorSystem() { |
91 | - Future<Terminated> status = system.terminate(); | ||
92 | - try { | ||
93 | - Terminated terminated = Await.result(status, Duration.Inf()); | ||
94 | - log.info("Actor system terminated: {}", terminated); | ||
95 | - } catch (Exception e) { | ||
96 | - log.error("Failed to terminate actor system.", e); | 124 | + if (system != null) { |
125 | + log.info("Stopping actor system."); | ||
126 | + system.stop(); | ||
127 | + log.info("Actor system stopped."); | ||
97 | } | 128 | } |
98 | } | 129 | } |
99 | 130 |
application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java
@@ -15,18 +15,13 @@ | @@ -15,18 +15,13 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.shared; | 16 | package org.thingsboard.server.actors.shared; |
17 | 17 | ||
18 | -import akka.actor.ActorContext; | ||
19 | -import akka.actor.ActorRef; | ||
20 | -import akka.actor.Scheduler; | ||
21 | -import akka.event.LoggingAdapter; | ||
22 | import com.fasterxml.jackson.databind.ObjectMapper; | 18 | import com.fasterxml.jackson.databind.ObjectMapper; |
23 | -import lombok.AllArgsConstructor; | ||
24 | -import lombok.Data; | ||
25 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
26 | import org.thingsboard.server.actors.ActorSystemContext; | 20 | import org.thingsboard.server.actors.ActorSystemContext; |
27 | -import scala.concurrent.ExecutionContextExecutor; | ||
28 | -import scala.concurrent.duration.Duration; | 21 | +import org.thingsboard.server.actors.TbActorCtx; |
22 | +import org.thingsboard.server.common.msg.TbActorMsg; | ||
29 | 23 | ||
24 | +import java.util.concurrent.ScheduledExecutorService; | ||
30 | import java.util.concurrent.TimeUnit; | 25 | import java.util.concurrent.TimeUnit; |
31 | 26 | ||
32 | @Slf4j | 27 | @Slf4j |
@@ -40,31 +35,16 @@ public abstract class AbstractContextAwareMsgProcessor { | @@ -40,31 +35,16 @@ public abstract class AbstractContextAwareMsgProcessor { | ||
40 | this.systemContext = systemContext; | 35 | this.systemContext = systemContext; |
41 | } | 36 | } |
42 | 37 | ||
43 | - private Scheduler getScheduler() { | 38 | + private ScheduledExecutorService getScheduler() { |
44 | return systemContext.getScheduler(); | 39 | return systemContext.getScheduler(); |
45 | } | 40 | } |
46 | 41 | ||
47 | - private ExecutionContextExecutor getSystemDispatcher() { | ||
48 | - return systemContext.getActorSystem().dispatcher(); | 42 | + protected void schedulePeriodicMsgWithDelay(TbActorCtx ctx, TbActorMsg msg, long delayInMs, long periodInMs) { |
43 | + systemContext.schedulePeriodicMsgWithDelay(ctx, msg, delayInMs, periodInMs); | ||
49 | } | 44 | } |
50 | 45 | ||
51 | - protected void schedulePeriodicMsgWithDelay(ActorContext ctx, Object msg, long delayInMs, long periodInMs) { | ||
52 | - schedulePeriodicMsgWithDelay(msg, delayInMs, periodInMs, ctx.self()); | 46 | + protected void scheduleMsgWithDelay(TbActorCtx ctx, TbActorMsg msg, long delayInMs) { |
47 | + systemContext.scheduleMsgWithDelay(ctx, msg, delayInMs); | ||
53 | } | 48 | } |
54 | 49 | ||
55 | - private void schedulePeriodicMsgWithDelay(Object msg, long delayInMs, long periodInMs, ActorRef target) { | ||
56 | - log.debug("Scheduling periodic msg {} every {} ms with delay {} ms", msg, periodInMs, delayInMs); | ||
57 | - getScheduler().schedule(Duration.create(delayInMs, TimeUnit.MILLISECONDS), Duration.create(periodInMs, TimeUnit.MILLISECONDS), target, msg, getSystemDispatcher(), null); | ||
58 | - } | ||
59 | - | ||
60 | - protected void scheduleMsgWithDelay(ActorContext ctx, Object msg, long delayInMs) { | ||
61 | - scheduleMsgWithDelay(msg, delayInMs, ctx.self()); | ||
62 | - } | ||
63 | - | ||
64 | - private void scheduleMsgWithDelay(Object msg, long delayInMs, ActorRef target) { | ||
65 | - log.debug("Scheduling msg {} with delay {} ms", msg, delayInMs); | ||
66 | - getScheduler().scheduleOnce(Duration.create(delayInMs, TimeUnit.MILLISECONDS), target, msg, getSystemDispatcher(), null); | ||
67 | - } | ||
68 | - | ||
69 | - | ||
70 | } | 50 | } |
@@ -15,16 +15,15 @@ | @@ -15,16 +15,15 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.shared; | 16 | package org.thingsboard.server.actors.shared; |
17 | 17 | ||
18 | -import akka.actor.ActorContext; | ||
19 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
20 | import org.thingsboard.server.actors.ActorSystemContext; | 19 | import org.thingsboard.server.actors.ActorSystemContext; |
20 | +import org.thingsboard.server.actors.TbActorCtx; | ||
21 | import org.thingsboard.server.actors.stats.StatsPersistTick; | 21 | import org.thingsboard.server.actors.stats.StatsPersistTick; |
22 | import org.thingsboard.server.common.data.id.EntityId; | 22 | import org.thingsboard.server.common.data.id.EntityId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 23 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; | 24 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; |
25 | import org.thingsboard.server.common.msg.TbMsg; | 25 | import org.thingsboard.server.common.msg.TbMsg; |
26 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | 26 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; |
27 | -import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
28 | import org.thingsboard.server.common.msg.queue.RuleNodeException; | 27 | import org.thingsboard.server.common.msg.queue.RuleNodeException; |
29 | 28 | ||
30 | @Slf4j | 29 | @Slf4j |
@@ -42,38 +41,38 @@ public abstract class ComponentMsgProcessor<T extends EntityId> extends Abstract | @@ -42,38 +41,38 @@ public abstract class ComponentMsgProcessor<T extends EntityId> extends Abstract | ||
42 | 41 | ||
43 | public abstract String getComponentName(); | 42 | public abstract String getComponentName(); |
44 | 43 | ||
45 | - public abstract void start(ActorContext context) throws Exception; | 44 | + public abstract void start(TbActorCtx context) throws Exception; |
46 | 45 | ||
47 | - public abstract void stop(ActorContext context) throws Exception; | 46 | + public abstract void stop(TbActorCtx context) throws Exception; |
48 | 47 | ||
49 | public abstract void onPartitionChangeMsg(PartitionChangeMsg msg) throws Exception; | 48 | public abstract void onPartitionChangeMsg(PartitionChangeMsg msg) throws Exception; |
50 | 49 | ||
51 | - public void onCreated(ActorContext context) throws Exception { | 50 | + public void onCreated(TbActorCtx context) throws Exception { |
52 | start(context); | 51 | start(context); |
53 | } | 52 | } |
54 | 53 | ||
55 | - public void onUpdate(ActorContext context) throws Exception { | 54 | + public void onUpdate(TbActorCtx context) throws Exception { |
56 | restart(context); | 55 | restart(context); |
57 | } | 56 | } |
58 | 57 | ||
59 | - public void onActivate(ActorContext context) throws Exception { | 58 | + public void onActivate(TbActorCtx context) throws Exception { |
60 | restart(context); | 59 | restart(context); |
61 | } | 60 | } |
62 | 61 | ||
63 | - public void onSuspend(ActorContext context) throws Exception { | 62 | + public void onSuspend(TbActorCtx context) throws Exception { |
64 | stop(context); | 63 | stop(context); |
65 | } | 64 | } |
66 | 65 | ||
67 | - public void onStop(ActorContext context) throws Exception { | 66 | + public void onStop(TbActorCtx context) throws Exception { |
68 | stop(context); | 67 | stop(context); |
69 | } | 68 | } |
70 | 69 | ||
71 | - private void restart(ActorContext context) throws Exception { | 70 | + private void restart(TbActorCtx context) throws Exception { |
72 | stop(context); | 71 | stop(context); |
73 | start(context); | 72 | start(context); |
74 | } | 73 | } |
75 | 74 | ||
76 | - public void scheduleStatsPersistTick(ActorContext context, long statsPersistFrequency) { | 75 | + public void scheduleStatsPersistTick(TbActorCtx context, long statsPersistFrequency) { |
77 | schedulePeriodicMsgWithDelay(context, new StatsPersistTick(), statsPersistFrequency, statsPersistFrequency); | 76 | schedulePeriodicMsgWithDelay(context, new StatsPersistTick(), statsPersistFrequency, statsPersistFrequency); |
78 | } | 77 | } |
79 | 78 |
@@ -19,10 +19,15 @@ import com.fasterxml.jackson.databind.JsonNode; | @@ -19,10 +19,15 @@ import com.fasterxml.jackson.databind.JsonNode; | ||
19 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
20 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
21 | import org.thingsboard.server.actors.ActorSystemContext; | 21 | import org.thingsboard.server.actors.ActorSystemContext; |
22 | +import org.thingsboard.server.actors.TbActor; | ||
23 | +import org.thingsboard.server.actors.TbActorCtx; | ||
24 | +import org.thingsboard.server.actors.TbActorId; | ||
25 | +import org.thingsboard.server.actors.TbStringActorId; | ||
22 | import org.thingsboard.server.actors.service.ContextAwareActor; | 26 | import org.thingsboard.server.actors.service.ContextAwareActor; |
23 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 27 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
24 | import org.thingsboard.server.common.data.DataConstants; | 28 | import org.thingsboard.server.common.data.DataConstants; |
25 | import org.thingsboard.server.common.data.Event; | 29 | import org.thingsboard.server.common.data.Event; |
30 | +import org.thingsboard.server.common.msg.MsgType; | ||
26 | import org.thingsboard.server.common.msg.TbActorMsg; | 31 | import org.thingsboard.server.common.msg.TbActorMsg; |
27 | 32 | ||
28 | @Slf4j | 33 | @Slf4j |
@@ -35,24 +40,17 @@ public class StatsActor extends ContextAwareActor { | @@ -35,24 +40,17 @@ public class StatsActor extends ContextAwareActor { | ||
35 | } | 40 | } |
36 | 41 | ||
37 | @Override | 42 | @Override |
38 | - protected boolean process(TbActorMsg msg) { | ||
39 | - //TODO Move everything here, to work with TbActorMsg\ | ||
40 | - return false; | ||
41 | - } | ||
42 | - | ||
43 | - @Override | ||
44 | - public void onReceive(Object msg) { | 43 | + protected boolean doProcess(TbActorMsg msg) { |
45 | log.debug("Received message: {}", msg); | 44 | log.debug("Received message: {}", msg); |
46 | - if (msg instanceof StatsPersistMsg) { | ||
47 | - try { | ||
48 | - onStatsPersistMsg((StatsPersistMsg) msg); | ||
49 | - } catch (Exception e) { | ||
50 | - log.warn("Failed to persist statistics: {}", msg, e); | ||
51 | - } | 45 | + if (msg.getMsgType().equals(MsgType.STATS_PERSIST_MSG)) { |
46 | + onStatsPersistMsg((StatsPersistMsg) msg); | ||
47 | + return true; | ||
48 | + } else { | ||
49 | + return false; | ||
52 | } | 50 | } |
53 | } | 51 | } |
54 | 52 | ||
55 | - public void onStatsPersistMsg(StatsPersistMsg msg) throws Exception { | 53 | + public void onStatsPersistMsg(StatsPersistMsg msg) { |
56 | Event event = new Event(); | 54 | Event event = new Event(); |
57 | event.setEntityId(msg.getEntityId()); | 55 | event.setEntityId(msg.getEntityId()); |
58 | event.setTenantId(msg.getTenantId()); | 56 | event.setTenantId(msg.getTenantId()); |
@@ -65,15 +63,21 @@ public class StatsActor extends ContextAwareActor { | @@ -65,15 +63,21 @@ public class StatsActor extends ContextAwareActor { | ||
65 | return mapper.createObjectNode().put("server", serviceId).put("messagesProcessed", messagesProcessed).put("errorsOccurred", errorsOccurred); | 63 | return mapper.createObjectNode().put("server", serviceId).put("messagesProcessed", messagesProcessed).put("errorsOccurred", errorsOccurred); |
66 | } | 64 | } |
67 | 65 | ||
68 | - public static class ActorCreator extends ContextBasedCreator<StatsActor> { | ||
69 | - private static final long serialVersionUID = 1L; | 66 | + public static class ActorCreator extends ContextBasedCreator { |
67 | + private final String actorId; | ||
70 | 68 | ||
71 | - public ActorCreator(ActorSystemContext context) { | 69 | + public ActorCreator(ActorSystemContext context, String actorId) { |
72 | super(context); | 70 | super(context); |
71 | + this.actorId = actorId; | ||
72 | + } | ||
73 | + | ||
74 | + @Override | ||
75 | + public TbActorId createActorId() { | ||
76 | + return new TbStringActorId(actorId); | ||
73 | } | 77 | } |
74 | 78 | ||
75 | @Override | 79 | @Override |
76 | - public StatsActor create() { | 80 | + public TbActor createActor() { |
77 | return new StatsActor(context); | 81 | return new StatsActor(context); |
78 | } | 82 | } |
79 | } | 83 | } |
@@ -20,13 +20,21 @@ import lombok.Getter; | @@ -20,13 +20,21 @@ import lombok.Getter; | ||
20 | import lombok.ToString; | 20 | import lombok.ToString; |
21 | import org.thingsboard.server.common.data.id.EntityId; | 21 | import org.thingsboard.server.common.data.id.EntityId; |
22 | import org.thingsboard.server.common.data.id.TenantId; | 22 | import org.thingsboard.server.common.data.id.TenantId; |
23 | +import org.thingsboard.server.common.msg.MsgType; | ||
24 | +import org.thingsboard.server.common.msg.TbActorMsg; | ||
23 | 25 | ||
24 | @AllArgsConstructor | 26 | @AllArgsConstructor |
25 | @Getter | 27 | @Getter |
26 | @ToString | 28 | @ToString |
27 | -public final class StatsPersistMsg { | 29 | +public final class StatsPersistMsg implements TbActorMsg { |
30 | + | ||
28 | private long messagesProcessed; | 31 | private long messagesProcessed; |
29 | private long errorsOccurred; | 32 | private long errorsOccurred; |
30 | private TenantId tenantId; | 33 | private TenantId tenantId; |
31 | private EntityId entityId; | 34 | private EntityId entityId; |
35 | + | ||
36 | + @Override | ||
37 | + public MsgType getMsgType() { | ||
38 | + return MsgType.STATS_PERSIST_MSG; | ||
39 | + } | ||
32 | } | 40 | } |
@@ -15,16 +15,15 @@ | @@ -15,16 +15,15 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.tenant; | 16 | package org.thingsboard.server.actors.tenant; |
17 | 17 | ||
18 | -import akka.actor.ActorInitializationException; | ||
19 | -import akka.actor.ActorRef; | ||
20 | -import akka.actor.LocalActorRef; | ||
21 | -import akka.actor.OneForOneStrategy; | ||
22 | -import akka.actor.Props; | ||
23 | -import akka.actor.SupervisorStrategy; | ||
24 | -import akka.actor.Terminated; | ||
25 | -import com.google.common.collect.BiMap; | ||
26 | -import com.google.common.collect.HashBiMap; | 18 | +import lombok.extern.slf4j.Slf4j; |
27 | import org.thingsboard.server.actors.ActorSystemContext; | 19 | import org.thingsboard.server.actors.ActorSystemContext; |
20 | +import org.thingsboard.server.actors.TbActor; | ||
21 | +import org.thingsboard.server.actors.TbActorCtx; | ||
22 | +import org.thingsboard.server.actors.TbActorId; | ||
23 | +import org.thingsboard.server.actors.TbActorNotRegisteredException; | ||
24 | +import org.thingsboard.server.actors.TbActorRef; | ||
25 | +import org.thingsboard.server.actors.TbEntityActorId; | ||
26 | +import org.thingsboard.server.actors.TbEntityTypeActorIdPredicate; | ||
28 | import org.thingsboard.server.actors.device.DeviceActorCreator; | 27 | import org.thingsboard.server.actors.device.DeviceActorCreator; |
29 | import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor; | 28 | import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor; |
30 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 29 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
@@ -32,6 +31,7 @@ import org.thingsboard.server.actors.service.DefaultActorService; | @@ -32,6 +31,7 @@ import org.thingsboard.server.actors.service.DefaultActorService; | ||
32 | import org.thingsboard.server.common.data.EntityType; | 31 | import org.thingsboard.server.common.data.EntityType; |
33 | import org.thingsboard.server.common.data.Tenant; | 32 | import org.thingsboard.server.common.data.Tenant; |
34 | import org.thingsboard.server.common.data.id.DeviceId; | 33 | import org.thingsboard.server.common.data.id.DeviceId; |
34 | +import org.thingsboard.server.common.data.id.EntityId; | ||
35 | import org.thingsboard.server.common.data.id.RuleChainId; | 35 | import org.thingsboard.server.common.data.id.RuleChainId; |
36 | import org.thingsboard.server.common.data.id.TenantId; | 36 | import org.thingsboard.server.common.data.id.TenantId; |
37 | import org.thingsboard.server.common.data.rule.RuleChain; | 37 | import org.thingsboard.server.common.data.rule.RuleChain; |
@@ -45,32 +45,25 @@ import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | @@ -45,32 +45,25 @@ import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | ||
45 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | 45 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
46 | import org.thingsboard.server.common.msg.queue.RuleEngineException; | 46 | import org.thingsboard.server.common.msg.queue.RuleEngineException; |
47 | import org.thingsboard.server.common.msg.queue.ServiceType; | 47 | import org.thingsboard.server.common.msg.queue.ServiceType; |
48 | -import scala.concurrent.duration.Duration; | ||
49 | 48 | ||
50 | import java.util.List; | 49 | import java.util.List; |
51 | import java.util.Optional; | 50 | import java.util.Optional; |
52 | -import java.util.stream.Collectors; | ||
53 | 51 | ||
52 | +@Slf4j | ||
54 | public class TenantActor extends RuleChainManagerActor { | 53 | public class TenantActor extends RuleChainManagerActor { |
55 | 54 | ||
56 | - private final BiMap<DeviceId, ActorRef> deviceActors; | ||
57 | private boolean isRuleEngineForCurrentTenant; | 55 | private boolean isRuleEngineForCurrentTenant; |
58 | private boolean isCore; | 56 | private boolean isCore; |
59 | 57 | ||
60 | private TenantActor(ActorSystemContext systemContext, TenantId tenantId) { | 58 | private TenantActor(ActorSystemContext systemContext, TenantId tenantId) { |
61 | super(systemContext, tenantId); | 59 | super(systemContext, tenantId); |
62 | - this.deviceActors = HashBiMap.create(); | ||
63 | - } | ||
64 | - | ||
65 | - @Override | ||
66 | - public SupervisorStrategy supervisorStrategy() { | ||
67 | - return strategy; | ||
68 | } | 60 | } |
69 | 61 | ||
70 | boolean cantFindTenant = false; | 62 | boolean cantFindTenant = false; |
71 | 63 | ||
72 | @Override | 64 | @Override |
73 | - public void preStart() { | 65 | + public void init(TbActorCtx ctx) { |
66 | + super.init(ctx); | ||
74 | log.info("[{}] Starting tenant actor.", tenantId); | 67 | log.info("[{}] Starting tenant actor.", tenantId); |
75 | try { | 68 | try { |
76 | Tenant tenant = systemContext.getTenantService().findTenantById(tenantId); | 69 | Tenant tenant = systemContext.getTenantService().findTenantById(tenantId); |
@@ -104,12 +97,12 @@ public class TenantActor extends RuleChainManagerActor { | @@ -104,12 +97,12 @@ public class TenantActor extends RuleChainManagerActor { | ||
104 | } | 97 | } |
105 | 98 | ||
106 | @Override | 99 | @Override |
107 | - public void postStop() { | 100 | + public void destroy() { |
108 | log.info("[{}] Stopping tenant actor.", tenantId); | 101 | log.info("[{}] Stopping tenant actor.", tenantId); |
109 | } | 102 | } |
110 | 103 | ||
111 | @Override | 104 | @Override |
112 | - protected boolean process(TbActorMsg msg) { | 105 | + protected boolean doProcess(TbActorMsg msg) { |
113 | if (cantFindTenant) { | 106 | if (cantFindTenant) { |
114 | log.info("[{}] Processing missing Tenant msg: {}", tenantId, msg); | 107 | log.info("[{}] Processing missing Tenant msg: {}", tenantId, msg); |
115 | if (msg.getMsgType().equals(MsgType.QUEUE_TO_RULE_ENGINE_MSG)) { | 108 | if (msg.getMsgType().equals(MsgType.QUEUE_TO_RULE_ENGINE_MSG)) { |
@@ -126,13 +119,13 @@ public class TenantActor extends RuleChainManagerActor { | @@ -126,13 +119,13 @@ public class TenantActor extends RuleChainManagerActor { | ||
126 | //To Rule Chain Actors | 119 | //To Rule Chain Actors |
127 | broadcast(msg); | 120 | broadcast(msg); |
128 | } else if (ServiceType.TB_CORE.equals(serviceType)) { | 121 | } else if (ServiceType.TB_CORE.equals(serviceType)) { |
129 | - //To Device Actors | ||
130 | - List<DeviceId> repartitionedDevices = | ||
131 | - deviceActors.keySet().stream().filter(deviceId -> !isMyPartition(deviceId)).collect(Collectors.toList()); | ||
132 | - for (DeviceId deviceId : repartitionedDevices) { | ||
133 | - ActorRef deviceActor = deviceActors.remove(deviceId); | ||
134 | - context().stop(deviceActor); | ||
135 | - } | 122 | + List<TbActorId> deviceActorIds = ctx.filterChildren(new TbEntityTypeActorIdPredicate(EntityType.DEVICE) { |
123 | + @Override | ||
124 | + protected boolean testEntityId(EntityId entityId) { | ||
125 | + return super.testEntityId(entityId) && !isMyPartition(entityId); | ||
126 | + } | ||
127 | + }); | ||
128 | + deviceActorIds.forEach(id -> ctx.stop(id)); | ||
136 | } | 129 | } |
137 | break; | 130 | break; |
138 | case COMPONENT_LIFE_CYCLE_MSG: | 131 | case COMPONENT_LIFE_CYCLE_MSG: |
@@ -158,8 +151,8 @@ public class TenantActor extends RuleChainManagerActor { | @@ -158,8 +151,8 @@ public class TenantActor extends RuleChainManagerActor { | ||
158 | return true; | 151 | return true; |
159 | } | 152 | } |
160 | 153 | ||
161 | - private boolean isMyPartition(DeviceId deviceId) { | ||
162 | - return systemContext.resolve(ServiceType.TB_CORE, tenantId, deviceId).isMyPartition(); | 154 | + private boolean isMyPartition(EntityId entityId) { |
155 | + return systemContext.resolve(ServiceType.TB_CORE, tenantId, entityId).isMyPartition(); | ||
163 | } | 156 | } |
164 | 157 | ||
165 | private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) { | 158 | private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) { |
@@ -170,16 +163,15 @@ public class TenantActor extends RuleChainManagerActor { | @@ -170,16 +163,15 @@ public class TenantActor extends RuleChainManagerActor { | ||
170 | TbMsg tbMsg = msg.getTbMsg(); | 163 | TbMsg tbMsg = msg.getTbMsg(); |
171 | if (tbMsg.getRuleChainId() == null) { | 164 | if (tbMsg.getRuleChainId() == null) { |
172 | if (getRootChainActor() != null) { | 165 | if (getRootChainActor() != null) { |
173 | - getRootChainActor().tell(msg, self()); | 166 | + getRootChainActor().tell(msg); |
174 | } else { | 167 | } else { |
175 | tbMsg.getCallback().onFailure(new RuleEngineException("No Root Rule Chain available!")); | 168 | tbMsg.getCallback().onFailure(new RuleEngineException("No Root Rule Chain available!")); |
176 | log.info("[{}] No Root Chain: {}", tenantId, msg); | 169 | log.info("[{}] No Root Chain: {}", tenantId, msg); |
177 | } | 170 | } |
178 | } else { | 171 | } else { |
179 | - ActorRef ruleChainActor = get(tbMsg.getRuleChainId()); | ||
180 | - if (ruleChainActor != null) { | ||
181 | - ruleChainActor.tell(msg, self()); | ||
182 | - } else { | 172 | + try { |
173 | + ctx.tell(new TbEntityActorId(tbMsg.getRuleChainId()), msg); | ||
174 | + } catch (TbActorNotRegisteredException ex) { | ||
183 | log.trace("Received message for non-existing rule chain: [{}]", tbMsg.getRuleChainId()); | 175 | log.trace("Received message for non-existing rule chain: [{}]", tbMsg.getRuleChainId()); |
184 | //TODO: 3.1 Log it to dead letters queue; | 176 | //TODO: 3.1 Log it to dead letters queue; |
185 | tbMsg.getCallback().onSuccess(); | 177 | tbMsg.getCallback().onSuccess(); |
@@ -188,61 +180,39 @@ public class TenantActor extends RuleChainManagerActor { | @@ -188,61 +180,39 @@ public class TenantActor extends RuleChainManagerActor { | ||
188 | } | 180 | } |
189 | 181 | ||
190 | private void onRuleChainMsg(RuleChainAwareMsg msg) { | 182 | private void onRuleChainMsg(RuleChainAwareMsg msg) { |
191 | - getOrCreateActor(context(), msg.getRuleChainId()).tell(msg, self()); | 183 | + getOrCreateActor(msg.getRuleChainId()).tell(msg); |
192 | } | 184 | } |
193 | 185 | ||
194 | private void onToDeviceActorMsg(DeviceAwareMsg msg) { | 186 | private void onToDeviceActorMsg(DeviceAwareMsg msg) { |
195 | if (!isCore) { | 187 | if (!isCore) { |
196 | log.warn("RECEIVED INVALID MESSAGE: {}", msg); | 188 | log.warn("RECEIVED INVALID MESSAGE: {}", msg); |
197 | } | 189 | } |
198 | - getOrCreateDeviceActor(msg.getDeviceId()).tell(msg, ActorRef.noSender()); | 190 | + getOrCreateDeviceActor(msg.getDeviceId()).tell(msg); |
199 | } | 191 | } |
200 | 192 | ||
201 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { | 193 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { |
202 | if (isRuleEngineForCurrentTenant) { | 194 | if (isRuleEngineForCurrentTenant) { |
203 | - ActorRef target = getEntityActorRef(msg.getEntityId()); | 195 | + TbActorRef target = getEntityActorRef(msg.getEntityId()); |
204 | if (target != null) { | 196 | if (target != null) { |
205 | if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { | 197 | if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { |
206 | RuleChain ruleChain = systemContext.getRuleChainService(). | 198 | RuleChain ruleChain = systemContext.getRuleChainService(). |
207 | findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); | 199 | findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); |
208 | visit(ruleChain, target); | 200 | visit(ruleChain, target); |
209 | } | 201 | } |
210 | - target.tell(msg, ActorRef.noSender()); | 202 | + target.tell(msg); |
211 | } else { | 203 | } else { |
212 | log.debug("[{}] Invalid component lifecycle msg: {}", tenantId, msg); | 204 | log.debug("[{}] Invalid component lifecycle msg: {}", tenantId, msg); |
213 | } | 205 | } |
214 | } | 206 | } |
215 | } | 207 | } |
216 | 208 | ||
217 | - private ActorRef getOrCreateDeviceActor(DeviceId deviceId) { | ||
218 | - return deviceActors.computeIfAbsent(deviceId, k -> { | ||
219 | - log.debug("[{}][{}] Creating device actor.", tenantId, deviceId); | ||
220 | - ActorRef deviceActor = context().actorOf(Props.create(new DeviceActorCreator(systemContext, tenantId, deviceId)) | ||
221 | - .withDispatcher(DefaultActorService.CORE_DISPATCHER_NAME) | ||
222 | - , deviceId.toString()); | ||
223 | - context().watch(deviceActor); | ||
224 | - log.debug("[{}][{}] Created device actor: {}.", tenantId, deviceId, deviceActor); | ||
225 | - return deviceActor; | ||
226 | - }); | 209 | + private TbActorRef getOrCreateDeviceActor(DeviceId deviceId) { |
210 | + return ctx.getOrCreateChildActor(new TbEntityActorId(deviceId), | ||
211 | + () -> DefaultActorService.DEVICE_DISPATCHER_NAME, | ||
212 | + () -> new DeviceActorCreator(systemContext, tenantId, deviceId)); | ||
227 | } | 213 | } |
228 | 214 | ||
229 | - @Override | ||
230 | - protected void processTermination(Terminated message) { | ||
231 | - ActorRef terminated = message.actor(); | ||
232 | - if (terminated instanceof LocalActorRef) { | ||
233 | - boolean removed = deviceActors.inverse().remove(terminated) != null; | ||
234 | - if (removed) { | ||
235 | - log.debug("[{}] Removed actor:", terminated); | ||
236 | - } else { | ||
237 | - log.debug("Removed actor was not found in the device map!"); | ||
238 | - } | ||
239 | - } else { | ||
240 | - throw new IllegalStateException("Remote actors are not supported!"); | ||
241 | - } | ||
242 | - } | ||
243 | - | ||
244 | - public static class ActorCreator extends ContextBasedCreator<TenantActor> { | ||
245 | - private static final long serialVersionUID = 1L; | 215 | + public static class ActorCreator extends ContextBasedCreator { |
246 | 216 | ||
247 | private final TenantId tenantId; | 217 | private final TenantId tenantId; |
248 | 218 | ||
@@ -252,18 +222,14 @@ public class TenantActor extends RuleChainManagerActor { | @@ -252,18 +222,14 @@ public class TenantActor extends RuleChainManagerActor { | ||
252 | } | 222 | } |
253 | 223 | ||
254 | @Override | 224 | @Override |
255 | - public TenantActor create() { | ||
256 | - return new TenantActor(context, tenantId); | 225 | + public TbActorId createActorId() { |
226 | + return new TbEntityActorId(tenantId); | ||
257 | } | 227 | } |
258 | - } | ||
259 | 228 | ||
260 | - private final SupervisorStrategy strategy = new OneForOneStrategy(3, Duration.create("1 minute"), t -> { | ||
261 | - log.warn("[{}] Unknown failure", tenantId, t); | ||
262 | - if (t instanceof ActorInitializationException) { | ||
263 | - return SupervisorStrategy.stop(); | ||
264 | - } else { | ||
265 | - return SupervisorStrategy.resume(); | 229 | + @Override |
230 | + public TbActor createActor() { | ||
231 | + return new TenantActor(context, tenantId); | ||
266 | } | 232 | } |
267 | - }); | 233 | + } |
268 | 234 | ||
269 | } | 235 | } |
@@ -15,7 +15,6 @@ | @@ -15,7 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.queue; | 16 | package org.thingsboard.server.service.queue; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
20 | import org.springframework.beans.factory.annotation.Value; | 19 | import org.springframework.beans.factory.annotation.Value; |
21 | import org.springframework.scheduling.annotation.Scheduled; | 20 | import org.springframework.scheduling.annotation.Scheduled; |
@@ -150,7 +149,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -150,7 +149,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
150 | tbCoreDeviceRpcService.forwardRpcRequestToDeviceActor((ToDeviceRpcRequestActorMsg) tbActorMsg); | 149 | tbCoreDeviceRpcService.forwardRpcRequestToDeviceActor((ToDeviceRpcRequestActorMsg) tbActorMsg); |
151 | } else { | 150 | } else { |
152 | log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get()); | 151 | log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get()); |
153 | - actorContext.tell(actorMsg.get(), ActorRef.noSender()); | 152 | + actorContext.tell(actorMsg.get()); |
154 | } | 153 | } |
155 | } | 154 | } |
156 | callback.onSuccess(); | 155 | callback.onSuccess(); |
@@ -208,7 +207,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -208,7 +207,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
208 | Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreNotification.getComponentLifecycleMsg().toByteArray()); | 207 | Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreNotification.getComponentLifecycleMsg().toByteArray()); |
209 | if (actorMsg.isPresent()) { | 208 | if (actorMsg.isPresent()) { |
210 | log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get()); | 209 | log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get()); |
211 | - actorContext.tell(actorMsg.get(), ActorRef.noSender()); | 210 | + actorContext.tell(actorMsg.get()); |
212 | } | 211 | } |
213 | callback.onSuccess(); | 212 | callback.onSuccess(); |
214 | } | 213 | } |
@@ -279,7 +278,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -279,7 +278,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
279 | if (statsEnabled) { | 278 | if (statsEnabled) { |
280 | stats.log(toDeviceActorMsg); | 279 | stats.log(toDeviceActorMsg); |
281 | } | 280 | } |
282 | - actorContext.tell(new TransportToDeviceActorMsgWrapper(toDeviceActorMsg, callback), ActorRef.noSender()); | 281 | + actorContext.tell(new TransportToDeviceActorMsgWrapper(toDeviceActorMsg, callback)); |
283 | } | 282 | } |
284 | 283 | ||
285 | private void throwNotHandled(Object msg, TbCallback callback) { | 284 | private void throwNotHandled(Object msg, TbCallback callback) { |
@@ -15,7 +15,6 @@ | @@ -15,7 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.queue; | 16 | package org.thingsboard.server.service.queue; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | import com.google.protobuf.ProtocolStringList; | 18 | import com.google.protobuf.ProtocolStringList; |
20 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
21 | import org.springframework.beans.factory.annotation.Value; | 20 | import org.springframework.beans.factory.annotation.Value; |
@@ -51,7 +50,6 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStr | @@ -51,7 +50,6 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStr | ||
51 | import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy; | 50 | import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy; |
52 | import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategyFactory; | 51 | import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategyFactory; |
53 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 52 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; |
54 | -import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; | ||
55 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; | 53 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; |
56 | import org.thingsboard.server.service.stats.RuleEngineStatisticsService; | 54 | import org.thingsboard.server.service.stats.RuleEngineStatisticsService; |
57 | 55 | ||
@@ -232,7 +230,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -232,7 +230,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
232 | Optional<TbActorMsg> actorMsg = encodingService.decode(nfMsg.getComponentLifecycleMsg().toByteArray()); | 230 | Optional<TbActorMsg> actorMsg = encodingService.decode(nfMsg.getComponentLifecycleMsg().toByteArray()); |
233 | if (actorMsg.isPresent()) { | 231 | if (actorMsg.isPresent()) { |
234 | log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get()); | 232 | log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get()); |
235 | - actorContext.tell(actorMsg.get(), ActorRef.noSender()); | 233 | + actorContext.tell(actorMsg.get()); |
236 | } | 234 | } |
237 | callback.onSuccess(); | 235 | callback.onSuccess(); |
238 | } else if (nfMsg.hasFromDeviceRpcResponse()) { | 236 | } else if (nfMsg.hasFromDeviceRpcResponse()) { |
@@ -261,7 +259,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -261,7 +259,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
261 | } | 259 | } |
262 | } | 260 | } |
263 | msg = new QueueToRuleEngineMsg(tenantId, tbMsg, relationTypes, toRuleEngineMsg.getFailureMessage()); | 261 | msg = new QueueToRuleEngineMsg(tenantId, tbMsg, relationTypes, toRuleEngineMsg.getFailureMessage()); |
264 | - actorContext.tell(msg, ActorRef.noSender()); | 262 | + actorContext.tell(msg); |
265 | } | 263 | } |
266 | 264 | ||
267 | @Scheduled(fixedDelayString = "${queue.rule-engine.stats.print-interval-ms}") | 265 | @Scheduled(fixedDelayString = "${queue.rule-engine.stats.print-interval-ms}") |
@@ -15,7 +15,6 @@ | @@ -15,7 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.rpc; | 16 | package org.thingsboard.server.service.rpc; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | import com.fasterxml.jackson.core.JsonProcessingException; | 18 | import com.fasterxml.jackson.core.JsonProcessingException; |
20 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
21 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
@@ -122,7 +121,7 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { | @@ -122,7 +121,7 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { | ||
122 | log.trace("[{}][{}] Processing local rpc call to device actor [{}]", request.getTenantId(), request.getId(), request.getDeviceId()); | 121 | log.trace("[{}][{}] Processing local rpc call to device actor [{}]", request.getTenantId(), request.getId(), request.getDeviceId()); |
123 | UUID requestId = request.getId(); | 122 | UUID requestId = request.getId(); |
124 | localToDeviceRpcRequests.put(requestId, rpcMsg); | 123 | localToDeviceRpcRequests.put(requestId, rpcMsg); |
125 | - actorContext.tell(rpcMsg, ActorRef.noSender()); | 124 | + actorContext.tell(rpcMsg); |
126 | scheduleToDeviceTimeout(request, requestId); | 125 | scheduleToDeviceTimeout(request, requestId); |
127 | } | 126 | } |
128 | 127 |
application/src/main/resources/actor-system.conf
deleted
100644 → 0
1 | -# | ||
2 | -# Copyright © 2016-2020 The Thingsboard Authors | ||
3 | -# | ||
4 | -# Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | -# you may not use this file except in compliance with the License. | ||
6 | -# You may obtain a copy of the License at | ||
7 | -# | ||
8 | -# http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | -# | ||
10 | -# Unless required by applicable law or agreed to in writing, software | ||
11 | -# distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | -# See the License for the specific language governing permissions and | ||
14 | -# limitations under the License. | ||
15 | -# | ||
16 | - | ||
17 | - | ||
18 | -akka { | ||
19 | - # JVM shutdown, System.exit(-1), in case of a fatal error, | ||
20 | - # such as OutOfMemoryError | ||
21 | - jvm-exit-on-fatal-error = off | ||
22 | - loglevel = "INFO" | ||
23 | - loggers = ["akka.event.slf4j.Slf4jLogger"] | ||
24 | -} | ||
25 | - | ||
26 | -# This dispatcher is used for app | ||
27 | -app-dispatcher { | ||
28 | - type = Dispatcher | ||
29 | - executor = "fork-join-executor" | ||
30 | - fork-join-executor { | ||
31 | - # Min number of threads to cap factor-based parallelism number to | ||
32 | - parallelism-min = 1 | ||
33 | - # Max number of threads to cap factor-based parallelism number to | ||
34 | - parallelism-max = 1 | ||
35 | - | ||
36 | - # The parallelism factor is used to determine thread pool size using the | ||
37 | - # following formula: ceil(available processors * factor). Resulting size | ||
38 | - # is then bounded by the parallelism-min and parallelism-max values. | ||
39 | - parallelism-factor = 1.0 | ||
40 | - } | ||
41 | - # How long time the dispatcher will wait for new actors until it shuts down | ||
42 | - shutdown-timeout = 1s | ||
43 | - | ||
44 | - # Throughput defines the number of messages that are processed in a batch | ||
45 | - # before the thread is returned to the pool. Set to 1 for as fair as possible. | ||
46 | - throughput = 5 | ||
47 | -} | ||
48 | - | ||
49 | -# This dispatcher is used for rpc actors | ||
50 | -rpc-dispatcher { | ||
51 | - type = Dispatcher | ||
52 | - executor = "fork-join-executor" | ||
53 | - fork-join-executor { | ||
54 | - # Min number of threads to cap factor-based parallelism number to | ||
55 | - parallelism-min = 2 | ||
56 | - # Max number of threads to cap factor-based parallelism number to | ||
57 | - parallelism-max = 8 | ||
58 | - | ||
59 | - # The parallelism factor is used to determine thread pool size using the | ||
60 | - # following formula: ceil(available processors * factor). Resulting size | ||
61 | - # is then bounded by the parallelism-min and parallelism-max values. | ||
62 | - parallelism-factor = 0.5 | ||
63 | - } | ||
64 | - # How long time the dispatcher will wait for new actors until it shuts down | ||
65 | - shutdown-timeout = 1s | ||
66 | - | ||
67 | - # Throughput defines the number of messages that are processed in a batch | ||
68 | - # before the thread is returned to the pool. Set to 1 for as fair as possible. | ||
69 | - throughput = 5 | ||
70 | -} | ||
71 | - | ||
72 | -# This dispatcher is used for auth | ||
73 | -core-dispatcher { | ||
74 | - type = Dispatcher | ||
75 | - executor = "fork-join-executor" | ||
76 | - fork-join-executor { | ||
77 | - # Min number of threads to cap factor-based parallelism number to | ||
78 | - parallelism-min = 2 | ||
79 | - # Max number of threads to cap factor-based parallelism number to | ||
80 | - parallelism-max = 12 | ||
81 | - | ||
82 | - # The parallelism factor is used to determine thread pool size using the | ||
83 | - # following formula: ceil(available processors * factor). Resulting size | ||
84 | - # is then bounded by the parallelism-min and parallelism-max values. | ||
85 | - parallelism-factor = 0.25 | ||
86 | - } | ||
87 | - # How long time the dispatcher will wait for new actors until it shuts down | ||
88 | - shutdown-timeout = 1s | ||
89 | - | ||
90 | - # Throughput defines the number of messages that are processed in a batch | ||
91 | - # before the thread is returned to the pool. Set to 1 for as fair as possible. | ||
92 | - throughput = 5 | ||
93 | -} | ||
94 | - | ||
95 | -# This dispatcher is used for system rule chains and rule node actors | ||
96 | -system-rule-dispatcher { | ||
97 | - type = Dispatcher | ||
98 | - executor = "fork-join-executor" | ||
99 | - fork-join-executor { | ||
100 | - # Min number of threads to cap factor-based parallelism number to | ||
101 | - parallelism-min = 2 | ||
102 | - # Max number of threads to cap factor-based parallelism number to | ||
103 | - parallelism-max = 12 | ||
104 | - | ||
105 | - # The parallelism factor is used to determine thread pool size using the | ||
106 | - # following formula: ceil(available processors * factor). Resulting size | ||
107 | - # is then bounded by the parallelism-min and parallelism-max values. | ||
108 | - parallelism-factor = 0.25 | ||
109 | - } | ||
110 | - # How long time the dispatcher will wait for new actors until it shuts down | ||
111 | - shutdown-timeout = 1s | ||
112 | - | ||
113 | - # Throughput defines the number of messages that are processed in a batch | ||
114 | - # before the thread is returned to the pool. Set to 1 for as fair as possible. | ||
115 | - throughput = 5 | ||
116 | -} | ||
117 | - | ||
118 | -# This dispatcher is used for tenant rule chains and rule node actors | ||
119 | -rule-dispatcher { | ||
120 | - type = Dispatcher | ||
121 | - executor = "fork-join-executor" | ||
122 | - fork-join-executor { | ||
123 | - # Min number of threads to cap factor-based parallelism number to | ||
124 | - parallelism-min = 2 | ||
125 | - # Max number of threads to cap factor-based parallelism number to | ||
126 | - parallelism-max = 12 | ||
127 | - | ||
128 | - # The parallelism factor is used to determine thread pool size using the | ||
129 | - # following formula: ceil(available processors * factor). Resulting size | ||
130 | - # is then bounded by the parallelism-min and parallelism-max values. | ||
131 | - parallelism-factor = 0.25 | ||
132 | - } | ||
133 | - # How long time the dispatcher will wait for new actors until it shuts down | ||
134 | - shutdown-timeout = 1s | ||
135 | - | ||
136 | - # Throughput defines the number of messages that are processed in a batch | ||
137 | - # before the thread is returned to the pool. Set to 1 for as fair as possible. | ||
138 | - throughput = 5 | ||
139 | -} |
@@ -281,6 +281,14 @@ sql: | @@ -281,6 +281,14 @@ sql: | ||
281 | 281 | ||
282 | # Actor system parameters | 282 | # Actor system parameters |
283 | actors: | 283 | actors: |
284 | + system: | ||
285 | + throughput: "${ACTORS_SYSTEM_THROUGHPUT:5}" | ||
286 | + scheduler_pool_size: "${ACTORS_SYSTEM_SCHEDULER_POOL_SIZE:1}" | ||
287 | + max_actor_init_attempts: "${ACTORS_SYSTEM_MAX_ACTOR_INIT_ATTEMPTS:10}" | ||
288 | + app_dispatcher_pool_size: "${ACTORS_SYSTEM_APP_DISPATCHER_POOL_SIZE:1}" | ||
289 | + tenant_dispatcher_pool_size: "${ACTORS_SYSTEM_TENANT_DISPATCHER_POOL_SIZE:2}" | ||
290 | + device_dispatcher_pool_size: "${ACTORS_SYSTEM_DEVICE_DISPATCHER_POOL_SIZE:4}" | ||
291 | + rule_dispatcher_pool_size: "${ACTORS_SYSTEM_RULE_DISPATCHER_POOL_SIZE:4}" | ||
284 | tenant: | 292 | tenant: |
285 | create_components_on_init: "${ACTORS_TENANT_CREATE_COMPONENTS_ON_INIT:true}" | 293 | create_components_on_init: "${ACTORS_TENANT_CREATE_COMPONENTS_ON_INIT:true}" |
286 | session: | 294 | session: |
@@ -318,11 +326,6 @@ actors: | @@ -318,11 +326,6 @@ actors: | ||
318 | enabled: "${ACTORS_STATISTICS_ENABLED:true}" | 326 | enabled: "${ACTORS_STATISTICS_ENABLED:true}" |
319 | js_print_interval_ms: "${ACTORS_JS_STATISTICS_PRINT_INTERVAL_MS:10000}" | 327 | js_print_interval_ms: "${ACTORS_JS_STATISTICS_PRINT_INTERVAL_MS:10000}" |
320 | persist_frequency: "${ACTORS_STATISTICS_PERSIST_FREQUENCY:3600000}" | 328 | persist_frequency: "${ACTORS_STATISTICS_PERSIST_FREQUENCY:3600000}" |
321 | - queue: | ||
322 | - # Enable/disable persistence of un-processed messages to the queue | ||
323 | - enabled: "${ACTORS_QUEUE_ENABLED:true}" | ||
324 | - # Maximum allowed timeout for persistence into the queue | ||
325 | - timeout: "${ACTORS_QUEUE_PERSISTENCE_TIMEOUT:30000}" | ||
326 | 329 | ||
327 | cache: | 330 | cache: |
328 | # caffeine or redis | 331 | # caffeine or redis |
@@ -15,8 +15,6 @@ | @@ -15,8 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.rules.flow; | 16 | package org.thingsboard.server.rules.flow; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | -import com.datastax.driver.core.utils.UUIDs; | ||
20 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
21 | import org.junit.After; | 19 | import org.junit.After; |
22 | import org.junit.Assert; | 20 | import org.junit.Assert; |
@@ -26,7 +24,6 @@ import org.mockito.Mockito; | @@ -26,7 +24,6 @@ import org.mockito.Mockito; | ||
26 | import org.springframework.beans.factory.annotation.Autowired; | 24 | import org.springframework.beans.factory.annotation.Autowired; |
27 | import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; | 25 | import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; |
28 | import org.thingsboard.server.actors.ActorSystemContext; | 26 | import org.thingsboard.server.actors.ActorSystemContext; |
29 | -import org.thingsboard.server.actors.service.ActorService; | ||
30 | import org.thingsboard.server.common.data.*; | 27 | import org.thingsboard.server.common.data.*; |
31 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; | 28 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
32 | import org.thingsboard.server.common.data.kv.StringDataEntry; | 29 | import org.thingsboard.server.common.data.kv.StringDataEntry; |
@@ -36,7 +33,6 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; | @@ -36,7 +33,6 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; | ||
36 | import org.thingsboard.server.common.data.rule.RuleNode; | 33 | import org.thingsboard.server.common.data.rule.RuleNode; |
37 | import org.thingsboard.server.common.data.security.Authority; | 34 | import org.thingsboard.server.common.data.security.Authority; |
38 | import org.thingsboard.server.common.msg.TbMsg; | 35 | import org.thingsboard.server.common.msg.TbMsg; |
39 | -import org.thingsboard.server.common.msg.TbMsgDataType; | ||
40 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 36 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
41 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | 37 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
42 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 38 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; |
@@ -151,7 +147,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule | @@ -151,7 +147,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule | ||
151 | TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback); | 147 | TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback); |
152 | QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null); | 148 | QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null); |
153 | // Pushing Message to the system | 149 | // Pushing Message to the system |
154 | - actorSystem.tell(qMsg, ActorRef.noSender()); | 150 | + actorSystem.tell(qMsg); |
155 | Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess(); | 151 | Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess(); |
156 | 152 | ||
157 | TimePageData<Event> eventsPage = getDebugEvents(savedTenant.getId(), ruleChain.getFirstRuleNodeId(), 1000); | 153 | TimePageData<Event> eventsPage = getDebugEvents(savedTenant.getId(), ruleChain.getFirstRuleNodeId(), 1000); |
@@ -263,7 +259,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule | @@ -263,7 +259,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule | ||
263 | TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback); | 259 | TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback); |
264 | QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null); | 260 | QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null); |
265 | // Pushing Message to the system | 261 | // Pushing Message to the system |
266 | - actorSystem.tell(qMsg, ActorRef.noSender()); | 262 | + actorSystem.tell(qMsg); |
267 | 263 | ||
268 | Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess(); | 264 | Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess(); |
269 | 265 |
@@ -15,8 +15,6 @@ | @@ -15,8 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.rules.lifecycle; | 16 | package org.thingsboard.server.rules.lifecycle; |
17 | 17 | ||
18 | -import akka.actor.ActorRef; | ||
19 | -import com.datastax.driver.core.utils.UUIDs; | ||
20 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
21 | import org.junit.After; | 19 | import org.junit.After; |
22 | import org.junit.Assert; | 20 | import org.junit.Assert; |
@@ -26,7 +24,6 @@ import org.mockito.Mockito; | @@ -26,7 +24,6 @@ import org.mockito.Mockito; | ||
26 | import org.springframework.beans.factory.annotation.Autowired; | 24 | import org.springframework.beans.factory.annotation.Autowired; |
27 | import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; | 25 | import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; |
28 | import org.thingsboard.server.actors.ActorSystemContext; | 26 | import org.thingsboard.server.actors.ActorSystemContext; |
29 | -import org.thingsboard.server.actors.service.ActorService; | ||
30 | import org.thingsboard.server.common.data.DataConstants; | 27 | import org.thingsboard.server.common.data.DataConstants; |
31 | import org.thingsboard.server.common.data.Device; | 28 | import org.thingsboard.server.common.data.Device; |
32 | import org.thingsboard.server.common.data.Event; | 29 | import org.thingsboard.server.common.data.Event; |
@@ -40,7 +37,6 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; | @@ -40,7 +37,6 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; | ||
40 | import org.thingsboard.server.common.data.rule.RuleNode; | 37 | import org.thingsboard.server.common.data.rule.RuleNode; |
41 | import org.thingsboard.server.common.data.security.Authority; | 38 | import org.thingsboard.server.common.data.security.Authority; |
42 | import org.thingsboard.server.common.msg.TbMsg; | 39 | import org.thingsboard.server.common.msg.TbMsg; |
43 | -import org.thingsboard.server.common.msg.TbMsgDataType; | ||
44 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 40 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
45 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | 41 | import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
46 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; | 42 | import org.thingsboard.server.common.msg.queue.TbMsgCallback; |
@@ -142,7 +138,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac | @@ -142,7 +138,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac | ||
142 | TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback); | 138 | TbMsg tbMsg = TbMsg.newMsg("CUSTOM", device.getId(), new TbMsgMetaData(), "{}", tbMsgCallback); |
143 | QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null); | 139 | QueueToRuleEngineMsg qMsg = new QueueToRuleEngineMsg(savedTenant.getId(), tbMsg, null, null); |
144 | // Pushing Message to the system | 140 | // Pushing Message to the system |
145 | - actorSystem.tell(qMsg, ActorRef.noSender()); | 141 | + actorSystem.tell(qMsg); |
146 | Mockito.verify(tbMsgCallback, Mockito.timeout(3000)).onSuccess(); | 142 | Mockito.verify(tbMsgCallback, Mockito.timeout(3000)).onSuccess(); |
147 | 143 | ||
148 | 144 |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.actors; | ||
17 | + | ||
18 | +import lombok.Getter; | ||
19 | + | ||
20 | +public abstract class AbstractTbActor implements TbActor { | ||
21 | + | ||
22 | + @Getter | ||
23 | + protected TbActorCtx ctx; | ||
24 | + | ||
25 | + @Override | ||
26 | + public void init(TbActorCtx ctx) { | ||
27 | + this.ctx = ctx; | ||
28 | + } | ||
29 | + | ||
30 | + @Override | ||
31 | + public TbActorRef getActorRef() { | ||
32 | + return ctx; | ||
33 | + } | ||
34 | +} |
@@ -21,13 +21,19 @@ import lombok.extern.slf4j.Slf4j; | @@ -21,13 +21,19 @@ import lombok.extern.slf4j.Slf4j; | ||
21 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 21 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
22 | import org.thingsboard.server.common.msg.TbActorMsg; | 22 | import org.thingsboard.server.common.msg.TbActorMsg; |
23 | 23 | ||
24 | +import java.util.Collections; | ||
25 | +import java.util.List; | ||
26 | +import java.util.Set; | ||
24 | import java.util.concurrent.ConcurrentHashMap; | 27 | import java.util.concurrent.ConcurrentHashMap; |
25 | import java.util.concurrent.ConcurrentMap; | 28 | import java.util.concurrent.ConcurrentMap; |
26 | import java.util.concurrent.ExecutorService; | 29 | import java.util.concurrent.ExecutorService; |
27 | import java.util.concurrent.Executors; | 30 | import java.util.concurrent.Executors; |
28 | import java.util.concurrent.ScheduledExecutorService; | 31 | import java.util.concurrent.ScheduledExecutorService; |
32 | +import java.util.concurrent.TimeUnit; | ||
29 | import java.util.concurrent.locks.Lock; | 33 | import java.util.concurrent.locks.Lock; |
30 | import java.util.concurrent.locks.ReentrantLock; | 34 | import java.util.concurrent.locks.ReentrantLock; |
35 | +import java.util.function.Predicate; | ||
36 | +import java.util.stream.Collectors; | ||
31 | 37 | ||
32 | @Slf4j | 38 | @Slf4j |
33 | @Data | 39 | @Data |
@@ -36,6 +42,8 @@ public class DefaultTbActorSystem implements TbActorSystem { | @@ -36,6 +42,8 @@ public class DefaultTbActorSystem implements TbActorSystem { | ||
36 | private final ConcurrentMap<String, Dispatcher> dispatchers = new ConcurrentHashMap<>(); | 42 | private final ConcurrentMap<String, Dispatcher> dispatchers = new ConcurrentHashMap<>(); |
37 | private final ConcurrentMap<TbActorId, TbActorMailbox> actors = new ConcurrentHashMap<>(); | 43 | private final ConcurrentMap<TbActorId, TbActorMailbox> actors = new ConcurrentHashMap<>(); |
38 | private final ConcurrentMap<TbActorId, ReentrantLock> actorCreationLocks = new ConcurrentHashMap<>(); | 44 | private final ConcurrentMap<TbActorId, ReentrantLock> actorCreationLocks = new ConcurrentHashMap<>(); |
45 | + private final ConcurrentMap<TbActorId, Set<TbActorId>> parentChildMap = new ConcurrentHashMap<>(); | ||
46 | + | ||
39 | @Getter | 47 | @Getter |
40 | private final TbActorSystemSettings settings; | 48 | private final TbActorSystemSettings settings; |
41 | @Getter | 49 | @Getter |
@@ -65,16 +73,21 @@ public class DefaultTbActorSystem implements TbActorSystem { | @@ -65,16 +73,21 @@ public class DefaultTbActorSystem implements TbActorSystem { | ||
65 | } | 73 | } |
66 | 74 | ||
67 | @Override | 75 | @Override |
68 | - public TbActorId createRootActor(String dispatcherId, TbActorCreator creator) { | 76 | + public TbActorRef getActor(TbActorId actorId) { |
77 | + return actors.get(actorId); | ||
78 | + } | ||
79 | + | ||
80 | + @Override | ||
81 | + public TbActorRef createRootActor(String dispatcherId, TbActorCreator creator) { | ||
69 | return createActor(dispatcherId, creator, null); | 82 | return createActor(dispatcherId, creator, null); |
70 | } | 83 | } |
71 | 84 | ||
72 | @Override | 85 | @Override |
73 | - public TbActorId createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent) { | 86 | + public TbActorRef createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent) { |
74 | return createActor(dispatcherId, creator, parent); | 87 | return createActor(dispatcherId, creator, parent); |
75 | } | 88 | } |
76 | 89 | ||
77 | - private TbActorId createActor(String dispatcherId, TbActorCreator creator, TbActorId parent) { | 90 | + private TbActorRef createActor(String dispatcherId, TbActorCreator creator, TbActorId parent) { |
78 | Dispatcher dispatcher = dispatchers.get(dispatcherId); | 91 | Dispatcher dispatcher = dispatchers.get(dispatcherId); |
79 | if (dispatcher == null) { | 92 | if (dispatcher == null) { |
80 | log.warn("Dispatcher with id [{}] is not registered!", dispatcherId); | 93 | log.warn("Dispatcher with id [{}] is not registered!", dispatcherId); |
@@ -93,9 +106,20 @@ public class DefaultTbActorSystem implements TbActorSystem { | @@ -93,9 +106,20 @@ public class DefaultTbActorSystem implements TbActorSystem { | ||
93 | if (actorMailbox == null) { | 106 | if (actorMailbox == null) { |
94 | log.debug("Creating actor with id [{}]!", actorId); | 107 | log.debug("Creating actor with id [{}]!", actorId); |
95 | TbActor actor = creator.createActor(); | 108 | TbActor actor = creator.createActor(); |
96 | - TbActorMailbox mailbox = new TbActorMailbox(this, settings, actorId, parent, actor, dispatcher); | 109 | + TbActorRef parentRef = null; |
110 | + if (parent != null) { | ||
111 | + parentRef = getActor(parent); | ||
112 | + if (parentRef == null) { | ||
113 | + throw new TbActorNotRegisteredException(parent, "Parent Actor with id [" + parent + "] is not registered!"); | ||
114 | + } | ||
115 | + } | ||
116 | + TbActorMailbox mailbox = new TbActorMailbox(this, settings, actorId, parentRef, actor, dispatcher); | ||
97 | actors.put(actorId, mailbox); | 117 | actors.put(actorId, mailbox); |
98 | mailbox.initActor(); | 118 | mailbox.initActor(); |
119 | + actorMailbox = mailbox; | ||
120 | + if (parent != null) { | ||
121 | + parentChildMap.computeIfAbsent(parent, id -> ConcurrentHashMap.newKeySet()).add(actorId); | ||
122 | + } | ||
99 | } else { | 123 | } else { |
100 | log.debug("Actor with id [{}] is already registered!", actorId); | 124 | log.debug("Actor with id [{}] is already registered!", actorId); |
101 | } | 125 | } |
@@ -104,7 +128,12 @@ public class DefaultTbActorSystem implements TbActorSystem { | @@ -104,7 +128,12 @@ public class DefaultTbActorSystem implements TbActorSystem { | ||
104 | actorCreationLocks.remove(actorId); | 128 | actorCreationLocks.remove(actorId); |
105 | } | 129 | } |
106 | } | 130 | } |
107 | - return actorId; | 131 | + return actorMailbox; |
132 | + } | ||
133 | + | ||
134 | + @Override | ||
135 | + public void tell(TbActorRef target, TbActorMsg actorMsg) { | ||
136 | + target.tell(actorMsg); | ||
108 | } | 137 | } |
109 | 138 | ||
110 | @Override | 139 | @Override |
@@ -117,7 +146,41 @@ public class DefaultTbActorSystem implements TbActorSystem { | @@ -117,7 +146,41 @@ public class DefaultTbActorSystem implements TbActorSystem { | ||
117 | } | 146 | } |
118 | 147 | ||
119 | @Override | 148 | @Override |
149 | + public void broadcastToChildren(TbActorId parent, TbActorMsg msg) { | ||
150 | + broadcastToChildren(parent, id -> true, msg); | ||
151 | + } | ||
152 | + | ||
153 | + @Override | ||
154 | + public void broadcastToChildren(TbActorId parent, Predicate<TbActorId> childFilter, TbActorMsg msg) { | ||
155 | + Set<TbActorId> children = parentChildMap.get(parent); | ||
156 | + if (children != null) { | ||
157 | + children.stream().filter(childFilter).forEach(id -> tell(id, msg)); | ||
158 | + } | ||
159 | + } | ||
160 | + | ||
161 | + @Override | ||
162 | + public List<TbActorId> filterChildren(TbActorId parent, Predicate<TbActorId> childFilter) { | ||
163 | + Set<TbActorId> children = parentChildMap.get(parent); | ||
164 | + if (children != null) { | ||
165 | + return children.stream().filter(childFilter).collect(Collectors.toList()); | ||
166 | + } else { | ||
167 | + return Collections.emptyList(); | ||
168 | + } | ||
169 | + } | ||
170 | + | ||
171 | + @Override | ||
172 | + public void stop(TbActorRef actorRef) { | ||
173 | + stop(actorRef.getActorId()); | ||
174 | + } | ||
175 | + | ||
176 | + @Override | ||
120 | public void stop(TbActorId actorId) { | 177 | public void stop(TbActorId actorId) { |
178 | + Set<TbActorId> children = parentChildMap.remove(actorId); | ||
179 | + if (children != null) { | ||
180 | + for (TbActorId child : children) { | ||
181 | + stop(child); | ||
182 | + } | ||
183 | + } | ||
121 | TbActorMailbox mailbox = actors.remove(actorId); | 184 | TbActorMailbox mailbox = actors.remove(actorId); |
122 | if (mailbox != null) { | 185 | if (mailbox != null) { |
123 | mailbox.destroy(); | 186 | mailbox.destroy(); |
@@ -126,7 +189,17 @@ public class DefaultTbActorSystem implements TbActorSystem { | @@ -126,7 +189,17 @@ public class DefaultTbActorSystem implements TbActorSystem { | ||
126 | 189 | ||
127 | @Override | 190 | @Override |
128 | public void stop() { | 191 | public void stop() { |
129 | - dispatchers.values().forEach(dispatcher -> dispatcher.getExecutor().shutdownNow()); | 192 | + dispatchers.values().forEach(dispatcher -> { |
193 | + dispatcher.getExecutor().shutdown(); | ||
194 | + try { | ||
195 | + dispatcher.getExecutor().awaitTermination(3, TimeUnit.SECONDS); | ||
196 | + } catch (InterruptedException e) { | ||
197 | + log.warn("[{}] Failed to stop dispatcher", dispatcher.getDispatcherId(), e); | ||
198 | + } | ||
199 | + }); | ||
200 | + if (scheduler != null) { | ||
201 | + scheduler.shutdownNow(); | ||
202 | + } | ||
130 | actors.clear(); | 203 | actors.clear(); |
131 | } | 204 | } |
132 | 205 |
@@ -19,11 +19,15 @@ import org.thingsboard.server.common.msg.TbActorMsg; | @@ -19,11 +19,15 @@ import org.thingsboard.server.common.msg.TbActorMsg; | ||
19 | 19 | ||
20 | public interface TbActor { | 20 | public interface TbActor { |
21 | 21 | ||
22 | - void init(); | 22 | + boolean process(TbActorMsg msg); |
23 | 23 | ||
24 | - boolean process(TbActorCtx ctx, TbActorMsg msg); | 24 | + TbActorRef getActorRef(); |
25 | 25 | ||
26 | - void destroy(); | 26 | + default void init(TbActorCtx ctx) { |
27 | + } | ||
28 | + | ||
29 | + default void destroy() { | ||
30 | + } | ||
27 | 31 | ||
28 | default InitFailureStrategy onInitFailure(int attempt, Throwable t) { | 32 | default InitFailureStrategy onInitFailure(int attempt, Throwable t) { |
29 | return InitFailureStrategy.retryWithDelay(5000); | 33 | return InitFailureStrategy.retryWithDelay(5000); |
@@ -17,12 +17,25 @@ package org.thingsboard.server.actors; | @@ -17,12 +17,25 @@ package org.thingsboard.server.actors; | ||
17 | 17 | ||
18 | import org.thingsboard.server.common.msg.TbActorMsg; | 18 | import org.thingsboard.server.common.msg.TbActorMsg; |
19 | 19 | ||
20 | -public interface TbActorCtx { | 20 | +import java.util.List; |
21 | +import java.util.function.Predicate; | ||
22 | +import java.util.function.Supplier; | ||
23 | + | ||
24 | +public interface TbActorCtx extends TbActorRef { | ||
21 | 25 | ||
22 | TbActorId getSelf(); | 26 | TbActorId getSelf(); |
23 | 27 | ||
24 | - TbActorId getParent(); | 28 | + TbActorRef getParentRef(); |
29 | + | ||
30 | + void tell(TbActorId target, TbActorMsg msg); | ||
31 | + | ||
32 | + void stop(TbActorId target); | ||
33 | + | ||
34 | + TbActorRef getOrCreateChildActor(TbActorId actorId, Supplier<String> dispatcher, Supplier<TbActorCreator> creator); | ||
35 | + | ||
36 | + void broadcastToChildren(TbActorMsg msg); | ||
25 | 37 | ||
26 | - void tell(TbActorId target, TbActorMsg actorMsg); | 38 | + void broadcastToChildren(TbActorMsg msg, Predicate<TbActorId> childFilter); |
27 | 39 | ||
40 | + List<TbActorId> filterChildren(Predicate<TbActorId> childFilter); | ||
28 | } | 41 | } |
@@ -15,33 +15,6 @@ | @@ -15,33 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors; | 16 | package org.thingsboard.server.actors; |
17 | 17 | ||
18 | -import org.thingsboard.server.common.data.id.EntityId; | 18 | +public interface TbActorId { |
19 | 19 | ||
20 | -import java.util.Objects; | ||
21 | - | ||
22 | -public class TbActorId { | ||
23 | - | ||
24 | - private final EntityId entityId; | ||
25 | - | ||
26 | - public TbActorId(EntityId entityId) { | ||
27 | - this.entityId = entityId; | ||
28 | - } | ||
29 | - | ||
30 | - @Override | ||
31 | - public String toString() { | ||
32 | - return entityId.toString(); | ||
33 | - } | ||
34 | - | ||
35 | - @Override | ||
36 | - public boolean equals(Object o) { | ||
37 | - if (this == o) return true; | ||
38 | - if (o == null || getClass() != o.getClass()) return false; | ||
39 | - TbActorId actorId = (TbActorId) o; | ||
40 | - return entityId.equals(actorId.entityId); | ||
41 | - } | ||
42 | - | ||
43 | - @Override | ||
44 | - public int hashCode() { | ||
45 | - return Objects.hash(entityId); | ||
46 | - } | ||
47 | } | 20 | } |
@@ -19,9 +19,12 @@ import lombok.Data; | @@ -19,9 +19,12 @@ import lombok.Data; | ||
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | import org.thingsboard.server.common.msg.TbActorMsg; | 20 | import org.thingsboard.server.common.msg.TbActorMsg; |
21 | 21 | ||
22 | +import java.util.List; | ||
22 | import java.util.concurrent.ConcurrentLinkedQueue; | 23 | import java.util.concurrent.ConcurrentLinkedQueue; |
23 | import java.util.concurrent.TimeUnit; | 24 | import java.util.concurrent.TimeUnit; |
24 | import java.util.concurrent.atomic.AtomicBoolean; | 25 | import java.util.concurrent.atomic.AtomicBoolean; |
26 | +import java.util.function.Predicate; | ||
27 | +import java.util.function.Supplier; | ||
25 | 28 | ||
26 | @Slf4j | 29 | @Slf4j |
27 | @Data | 30 | @Data |
@@ -35,7 +38,7 @@ public final class TbActorMailbox implements TbActorCtx { | @@ -35,7 +38,7 @@ public final class TbActorMailbox implements TbActorCtx { | ||
35 | private final TbActorSystem system; | 38 | private final TbActorSystem system; |
36 | private final TbActorSystemSettings settings; | 39 | private final TbActorSystemSettings settings; |
37 | private final TbActorId selfId; | 40 | private final TbActorId selfId; |
38 | - private final TbActorId parentId; | 41 | + private final TbActorRef parentRef; |
39 | private final TbActor actor; | 42 | private final TbActor actor; |
40 | private final Dispatcher dispatcher; | 43 | private final Dispatcher dispatcher; |
41 | private final ConcurrentLinkedQueue<TbActorMsg> msgs = new ConcurrentLinkedQueue<>(); | 44 | private final ConcurrentLinkedQueue<TbActorMsg> msgs = new ConcurrentLinkedQueue<>(); |
@@ -47,11 +50,12 @@ public final class TbActorMailbox implements TbActorCtx { | @@ -47,11 +50,12 @@ public final class TbActorMailbox implements TbActorCtx { | ||
47 | dispatcher.getExecutor().execute(() -> tryInit(1)); | 50 | dispatcher.getExecutor().execute(() -> tryInit(1)); |
48 | } | 51 | } |
49 | 52 | ||
53 | + | ||
50 | private void tryInit(int attempt) { | 54 | private void tryInit(int attempt) { |
51 | try { | 55 | try { |
52 | log.debug("[{}] Trying to init actor, attempt: {}", selfId, attempt); | 56 | log.debug("[{}] Trying to init actor, attempt: {}", selfId, attempt); |
53 | if (!destroyInProgress.get()) { | 57 | if (!destroyInProgress.get()) { |
54 | - actor.init(); | 58 | + actor.init(this); |
55 | if (!destroyInProgress.get()) { | 59 | if (!destroyInProgress.get()) { |
56 | ready.set(READY); | 60 | ready.set(READY); |
57 | tryProcessQueue(false); | 61 | tryProcessQueue(false); |
@@ -94,7 +98,7 @@ public final class TbActorMailbox implements TbActorCtx { | @@ -94,7 +98,7 @@ public final class TbActorMailbox implements TbActorCtx { | ||
94 | if (msg != null) { | 98 | if (msg != null) { |
95 | try { | 99 | try { |
96 | log.debug("[{}] Going to process message: {}", selfId, msg); | 100 | log.debug("[{}] Going to process message: {}", selfId, msg); |
97 | - actor.process(this, msg); | 101 | + actor.process(msg); |
98 | } catch (Throwable t) { | 102 | } catch (Throwable t) { |
99 | log.debug("[{}] Failed to process message: {}", selfId, msg, t); | 103 | log.debug("[{}] Failed to process message: {}", selfId, msg, t); |
100 | ProcessFailureStrategy strategy = actor.onProcessFailure(t); | 104 | ProcessFailureStrategy strategy = actor.onProcessFailure(t); |
@@ -121,13 +125,38 @@ public final class TbActorMailbox implements TbActorCtx { | @@ -121,13 +125,38 @@ public final class TbActorMailbox implements TbActorCtx { | ||
121 | } | 125 | } |
122 | 126 | ||
123 | @Override | 127 | @Override |
124 | - public TbActorId getParent() { | ||
125 | - return parentId; | 128 | + public void tell(TbActorId target, TbActorMsg actorMsg) { |
129 | + system.tell(target, actorMsg); | ||
126 | } | 130 | } |
127 | 131 | ||
128 | @Override | 132 | @Override |
129 | - public void tell(TbActorId target, TbActorMsg actorMsg) { | ||
130 | - system.tell(target, actorMsg); | 133 | + public void broadcastToChildren(TbActorMsg msg) { |
134 | + system.broadcastToChildren(selfId, msg); | ||
135 | + } | ||
136 | + | ||
137 | + @Override | ||
138 | + public void broadcastToChildren(TbActorMsg msg, Predicate<TbActorId> childFilter) { | ||
139 | + system.broadcastToChildren(selfId, childFilter, msg); | ||
140 | + } | ||
141 | + | ||
142 | + @Override | ||
143 | + public List<TbActorId> filterChildren(Predicate<TbActorId> childFilter) { | ||
144 | + return system.filterChildren(selfId, childFilter); | ||
145 | + } | ||
146 | + | ||
147 | + @Override | ||
148 | + public void stop(TbActorId target) { | ||
149 | + system.stop(target); | ||
150 | + } | ||
151 | + | ||
152 | + @Override | ||
153 | + public TbActorRef getOrCreateChildActor(TbActorId actorId, Supplier<String> dispatcher, Supplier<TbActorCreator> creator) { | ||
154 | + TbActorRef actorRef = system.getActor(actorId); | ||
155 | + if (actorRef == null) { | ||
156 | + return system.createChildActor(dispatcher.get(), creator.get(), selfId); | ||
157 | + } else { | ||
158 | + return actorRef; | ||
159 | + } | ||
131 | } | 160 | } |
132 | 161 | ||
133 | public void destroy() { | 162 | public void destroy() { |
@@ -141,4 +170,14 @@ public final class TbActorMailbox implements TbActorCtx { | @@ -141,4 +170,14 @@ public final class TbActorMailbox implements TbActorCtx { | ||
141 | } | 170 | } |
142 | }); | 171 | }); |
143 | } | 172 | } |
173 | + | ||
174 | + @Override | ||
175 | + public TbActorId getActorId() { | ||
176 | + return selfId; | ||
177 | + } | ||
178 | + | ||
179 | + @Override | ||
180 | + public void tell(TbActorMsg actorMsg) { | ||
181 | + enqueue(actorMsg); | ||
182 | + } | ||
144 | } | 183 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.actors; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.msg.TbActorMsg; | ||
19 | + | ||
20 | +public interface TbActorRef { | ||
21 | + | ||
22 | + TbActorId getActorId(); | ||
23 | + | ||
24 | + void tell(TbActorMsg actorMsg); | ||
25 | + | ||
26 | +} |
@@ -17,8 +17,10 @@ package org.thingsboard.server.actors; | @@ -17,8 +17,10 @@ package org.thingsboard.server.actors; | ||
17 | 17 | ||
18 | import org.thingsboard.server.common.msg.TbActorMsg; | 18 | import org.thingsboard.server.common.msg.TbActorMsg; |
19 | 19 | ||
20 | +import java.util.List; | ||
20 | import java.util.concurrent.ExecutorService; | 21 | import java.util.concurrent.ExecutorService; |
21 | import java.util.concurrent.ScheduledExecutorService; | 22 | import java.util.concurrent.ScheduledExecutorService; |
23 | +import java.util.function.Predicate; | ||
22 | 24 | ||
23 | public interface TbActorSystem { | 25 | public interface TbActorSystem { |
24 | 26 | ||
@@ -28,14 +30,25 @@ public interface TbActorSystem { | @@ -28,14 +30,25 @@ public interface TbActorSystem { | ||
28 | 30 | ||
29 | void destroyDispatcher(String dispatcherId); | 31 | void destroyDispatcher(String dispatcherId); |
30 | 32 | ||
31 | - TbActorId createRootActor(String dispatcherId, TbActorCreator creator); | 33 | + TbActorRef getActor(TbActorId actorId); |
32 | 34 | ||
33 | - TbActorId createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent); | 35 | + TbActorRef createRootActor(String dispatcherId, TbActorCreator creator); |
36 | + | ||
37 | + TbActorRef createChildActor(String dispatcherId, TbActorCreator creator, TbActorId parent); | ||
38 | + | ||
39 | + void tell(TbActorRef target, TbActorMsg actorMsg); | ||
34 | 40 | ||
35 | void tell(TbActorId target, TbActorMsg actorMsg); | 41 | void tell(TbActorId target, TbActorMsg actorMsg); |
36 | 42 | ||
43 | + void stop(TbActorRef actorRef); | ||
44 | + | ||
37 | void stop(TbActorId actorId); | 45 | void stop(TbActorId actorId); |
38 | 46 | ||
39 | void stop(); | 47 | void stop(); |
40 | 48 | ||
49 | + void broadcastToChildren(TbActorId parent, TbActorMsg msg); | ||
50 | + | ||
51 | + void broadcastToChildren(TbActorId parent, Predicate<TbActorId> childFilter, TbActorMsg msg); | ||
52 | + | ||
53 | + List<TbActorId> filterChildren(TbActorId parent, Predicate<TbActorId> childFilter); | ||
41 | } | 54 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.actors; | ||
17 | + | ||
18 | +import lombok.Getter; | ||
19 | +import org.thingsboard.server.common.data.id.EntityId; | ||
20 | + | ||
21 | +import java.util.Objects; | ||
22 | + | ||
23 | +public class TbEntityActorId implements TbActorId { | ||
24 | + | ||
25 | + @Getter | ||
26 | + private final EntityId entityId; | ||
27 | + | ||
28 | + public TbEntityActorId(EntityId entityId) { | ||
29 | + this.entityId = entityId; | ||
30 | + } | ||
31 | + | ||
32 | + @Override | ||
33 | + public String toString() { | ||
34 | + return entityId.toString(); | ||
35 | + } | ||
36 | + | ||
37 | + @Override | ||
38 | + public boolean equals(Object o) { | ||
39 | + if (this == o) return true; | ||
40 | + if (o == null || getClass() != o.getClass()) return false; | ||
41 | + TbEntityActorId that = (TbEntityActorId) o; | ||
42 | + return entityId.equals(that.entityId); | ||
43 | + } | ||
44 | + | ||
45 | + @Override | ||
46 | + public int hashCode() { | ||
47 | + return Objects.hash(entityId); | ||
48 | + } | ||
49 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.actors; | ||
17 | + | ||
18 | +import java.util.Objects; | ||
19 | + | ||
20 | +public class TbStringActorId implements TbActorId { | ||
21 | + | ||
22 | + private final String id; | ||
23 | + | ||
24 | + public TbStringActorId(String id) { | ||
25 | + this.id = id; | ||
26 | + } | ||
27 | + | ||
28 | + @Override | ||
29 | + public String toString() { | ||
30 | + return id; | ||
31 | + } | ||
32 | + | ||
33 | + @Override | ||
34 | + public boolean equals(Object o) { | ||
35 | + if (this == o) return true; | ||
36 | + if (o == null || getClass() != o.getClass()) return false; | ||
37 | + TbStringActorId that = (TbStringActorId) o; | ||
38 | + return id.equals(that.id); | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public int hashCode() { | ||
43 | + return Objects.hash(id); | ||
44 | + } | ||
45 | +} |
@@ -81,10 +81,10 @@ public class ActorSystemTest { | @@ -81,10 +81,10 @@ public class ActorSystemTest { | ||
81 | ActorTestCtx testCtx1 = getActorTestCtx(1); | 81 | ActorTestCtx testCtx1 = getActorTestCtx(1); |
82 | ActorTestCtx testCtx2 = getActorTestCtx(1); | 82 | ActorTestCtx testCtx2 = getActorTestCtx(1); |
83 | 83 | ||
84 | - TbActorId actorId1 = actorSystem.createRootActor(ROOT_DISPATCHER, new SlowInitActor.SlowInitActorCreator( | ||
85 | - new TbActorId(new DeviceId(UUID.randomUUID())), testCtx1)); | ||
86 | - TbActorId actorId2 = actorSystem.createRootActor(ROOT_DISPATCHER, new SlowInitActor.SlowInitActorCreator( | ||
87 | - new TbActorId(new DeviceId(UUID.randomUUID())), testCtx2)); | 84 | + TbActorRef actorId1 = actorSystem.createRootActor(ROOT_DISPATCHER, new SlowInitActor.SlowInitActorCreator( |
85 | + new TbEntityActorId(new DeviceId(UUID.randomUUID())), testCtx1)); | ||
86 | + TbActorRef actorId2 = actorSystem.createRootActor(ROOT_DISPATCHER, new SlowInitActor.SlowInitActorCreator( | ||
87 | + new TbEntityActorId(new DeviceId(UUID.randomUUID())), testCtx2)); | ||
88 | 88 | ||
89 | actorSystem.tell(actorId1, new IntTbActorMsg(42)); | 89 | actorSystem.tell(actorId1, new IntTbActorMsg(42)); |
90 | actorSystem.tell(actorId2, new IntTbActorMsg(42)); | 90 | actorSystem.tell(actorId2, new IntTbActorMsg(42)); |
@@ -98,7 +98,7 @@ public class ActorSystemTest { | @@ -98,7 +98,7 @@ public class ActorSystemTest { | ||
98 | public void testOneActorCreated() throws InterruptedException { | 98 | public void testOneActorCreated() throws InterruptedException { |
99 | ActorTestCtx testCtx1 = getActorTestCtx(1); | 99 | ActorTestCtx testCtx1 = getActorTestCtx(1); |
100 | ActorTestCtx testCtx2 = getActorTestCtx(1); | 100 | ActorTestCtx testCtx2 = getActorTestCtx(1); |
101 | - TbActorId actorId = new TbActorId(new DeviceId(UUID.randomUUID())); | 101 | + TbActorId actorId = new TbEntityActorId(new DeviceId(UUID.randomUUID())); |
102 | submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx1))); | 102 | submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx1))); |
103 | submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx2))); | 103 | submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx2))); |
104 | 104 | ||
@@ -112,7 +112,7 @@ public class ActorSystemTest { | @@ -112,7 +112,7 @@ public class ActorSystemTest { | ||
112 | @Test | 112 | @Test |
113 | public void testActorCreatorCalledOnce() throws InterruptedException { | 113 | public void testActorCreatorCalledOnce() throws InterruptedException { |
114 | ActorTestCtx testCtx = getActorTestCtx(1); | 114 | ActorTestCtx testCtx = getActorTestCtx(1); |
115 | - TbActorId actorId = new TbActorId(new DeviceId(UUID.randomUUID())); | 115 | + TbActorId actorId = new TbEntityActorId(new DeviceId(UUID.randomUUID())); |
116 | for(int i =0; i < 1000; i++) { | 116 | for(int i =0; i < 1000; i++) { |
117 | submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx))); | 117 | submitPool.submit(() -> actorSystem.createRootActor(ROOT_DISPATCHER, new SlowCreateActor.SlowCreateActorCreator(actorId, testCtx))); |
118 | } | 118 | } |
@@ -138,12 +138,12 @@ public class ActorSystemTest { | @@ -138,12 +138,12 @@ public class ActorSystemTest { | ||
138 | 138 | ||
139 | List<ActorTestCtx> testCtxes = new ArrayList<>(); | 139 | List<ActorTestCtx> testCtxes = new ArrayList<>(); |
140 | 140 | ||
141 | - List<TbActorId> actorIds = new ArrayList<>(); | 141 | + List<TbActorRef> actorRefs = new ArrayList<>(); |
142 | for (int actorIdx = 0; actorIdx < actorsCount; actorIdx++) { | 142 | for (int actorIdx = 0; actorIdx < actorsCount; actorIdx++) { |
143 | ActorTestCtx testCtx = getActorTestCtx(msgNumber); | 143 | ActorTestCtx testCtx = getActorTestCtx(msgNumber); |
144 | 144 | ||
145 | - actorIds.add(actorSystem.createRootActor(ROOT_DISPATCHER, new TestRootActor.TestRootActorCreator( | ||
146 | - new TbActorId(new DeviceId(UUID.randomUUID())), testCtx))); | 145 | + actorRefs.add(actorSystem.createRootActor(ROOT_DISPATCHER, new TestRootActor.TestRootActorCreator( |
146 | + new TbEntityActorId(new DeviceId(UUID.randomUUID())), testCtx))); | ||
147 | testCtxes.add(testCtx); | 147 | testCtxes.add(testCtx); |
148 | } | 148 | } |
149 | 149 | ||
@@ -151,7 +151,7 @@ public class ActorSystemTest { | @@ -151,7 +151,7 @@ public class ActorSystemTest { | ||
151 | 151 | ||
152 | for (int i = 0; i < msgNumber; i++) { | 152 | for (int i = 0; i < msgNumber; i++) { |
153 | int tmp = randomIntegers[i]; | 153 | int tmp = randomIntegers[i]; |
154 | - submitPool.execute(() -> actorIds.forEach(actorId -> actorSystem.tell(actorId, new IntTbActorMsg(tmp)))); | 154 | + submitPool.execute(() -> actorRefs.forEach(actorId -> actorSystem.tell(actorId, new IntTbActorMsg(tmp)))); |
155 | } | 155 | } |
156 | log.info("Submitted all messages"); | 156 | log.info("Submitted all messages"); |
157 | 157 |
@@ -25,13 +25,13 @@ public class SlowInitActor extends TestRootActor { | @@ -25,13 +25,13 @@ public class SlowInitActor extends TestRootActor { | ||
25 | } | 25 | } |
26 | 26 | ||
27 | @Override | 27 | @Override |
28 | - public void init() { | 28 | + public void init(TbActorCtx ctx) { |
29 | try { | 29 | try { |
30 | Thread.sleep(500); | 30 | Thread.sleep(500); |
31 | } catch (InterruptedException e) { | 31 | } catch (InterruptedException e) { |
32 | e.printStackTrace(); | 32 | e.printStackTrace(); |
33 | } | 33 | } |
34 | - super.init(); | 34 | + super.init(ctx); |
35 | } | 35 | } |
36 | 36 | ||
37 | public static class SlowInitActorCreator implements TbActorCreator { | 37 | public static class SlowInitActorCreator implements TbActorCreator { |
@@ -20,7 +20,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -20,7 +20,7 @@ import lombok.extern.slf4j.Slf4j; | ||
20 | import org.thingsboard.server.common.msg.TbActorMsg; | 20 | import org.thingsboard.server.common.msg.TbActorMsg; |
21 | 21 | ||
22 | @Slf4j | 22 | @Slf4j |
23 | -public class TestRootActor implements TbActor { | 23 | +public class TestRootActor extends AbstractTbActor { |
24 | 24 | ||
25 | @Getter | 25 | @Getter |
26 | private final TbActorId actorId; | 26 | private final TbActorId actorId; |
@@ -37,12 +37,13 @@ public class TestRootActor implements TbActor { | @@ -37,12 +37,13 @@ public class TestRootActor implements TbActor { | ||
37 | } | 37 | } |
38 | 38 | ||
39 | @Override | 39 | @Override |
40 | - public void init() { | 40 | + public void init(TbActorCtx ctx) { |
41 | + super.init(ctx); | ||
41 | initialized = true; | 42 | initialized = true; |
42 | } | 43 | } |
43 | 44 | ||
44 | @Override | 45 | @Override |
45 | - public boolean process(TbActorCtx ctx, TbActorMsg msg) { | 46 | + public boolean process(TbActorMsg msg) { |
46 | if (initialized) { | 47 | if (initialized) { |
47 | int value = ((IntTbActorMsg) msg).getValue(); | 48 | int value = ((IntTbActorMsg) msg).getValue(); |
48 | sum += value; | 49 | sum += value; |
@@ -21,7 +21,6 @@ import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | @@ -21,7 +21,6 @@ import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; | ||
21 | /** | 21 | /** |
22 | * Created by ashvayka on 15.03.18. | 22 | * Created by ashvayka on 15.03.18. |
23 | */ | 23 | */ |
24 | -//TODO: add all "See" references | ||
25 | public enum MsgType { | 24 | public enum MsgType { |
26 | 25 | ||
27 | /** | 26 | /** |
@@ -97,6 +96,7 @@ public enum MsgType { | @@ -97,6 +96,7 @@ public enum MsgType { | ||
97 | 96 | ||
98 | STATS_PERSIST_TICK_MSG, | 97 | STATS_PERSIST_TICK_MSG, |
99 | 98 | ||
99 | + STATS_PERSIST_MSG, | ||
100 | 100 | ||
101 | /** | 101 | /** |
102 | * Message that is sent by TransportRuleEngineService to Device Actor. Represents messages from the device itself. | 102 | * Message that is sent by TransportRuleEngineService to Device Actor. Represents messages from the device itself. |
@@ -16,8 +16,9 @@ | @@ -16,8 +16,9 @@ | ||
16 | package org.thingsboard.server.common.msg.aware; | 16 | package org.thingsboard.server.common.msg.aware; |
17 | 17 | ||
18 | import org.thingsboard.server.common.data.id.DeviceId; | 18 | import org.thingsboard.server.common.data.id.DeviceId; |
19 | +import org.thingsboard.server.common.msg.TbActorMsg; | ||
19 | 20 | ||
20 | -public interface DeviceAwareMsg { | 21 | +public interface DeviceAwareMsg extends TbActorMsg { |
21 | 22 | ||
22 | DeviceId getDeviceId(); | 23 | DeviceId getDeviceId(); |
23 | } | 24 | } |
@@ -16,8 +16,9 @@ | @@ -16,8 +16,9 @@ | ||
16 | package org.thingsboard.server.common.msg.aware; | 16 | package org.thingsboard.server.common.msg.aware; |
17 | 17 | ||
18 | import org.thingsboard.server.common.data.id.RuleChainId; | 18 | import org.thingsboard.server.common.data.id.RuleChainId; |
19 | +import org.thingsboard.server.common.msg.TbActorMsg; | ||
19 | 20 | ||
20 | -public interface RuleChainAwareMsg { | 21 | +public interface RuleChainAwareMsg extends TbActorMsg { |
21 | 22 | ||
22 | RuleChainId getRuleChainId(); | 23 | RuleChainId getRuleChainId(); |
23 | 24 |
@@ -16,8 +16,9 @@ | @@ -16,8 +16,9 @@ | ||
16 | package org.thingsboard.server.common.msg.aware; | 16 | package org.thingsboard.server.common.msg.aware; |
17 | 17 | ||
18 | import org.thingsboard.server.common.data.id.TenantId; | 18 | import org.thingsboard.server.common.data.id.TenantId; |
19 | +import org.thingsboard.server.common.msg.TbActorMsg; | ||
19 | 20 | ||
20 | -public interface TenantAwareMsg { | 21 | +public interface TenantAwareMsg extends TbActorMsg { |
21 | 22 | ||
22 | TenantId getTenantId(); | 23 | TenantId getTenantId(); |
23 | 24 |
@@ -62,8 +62,6 @@ | @@ -62,8 +62,6 @@ | ||
62 | <jackson-annotations.version>2.10.2</jackson-annotations.version> | 62 | <jackson-annotations.version>2.10.2</jackson-annotations.version> |
63 | <jackson-core.version>2.10.2</jackson-core.version> | 63 | <jackson-core.version>2.10.2</jackson-core.version> |
64 | <json-schema-validator.version>2.2.6</json-schema-validator.version> | 64 | <json-schema-validator.version>2.2.6</json-schema-validator.version> |
65 | - <scala.version>2.13</scala.version> | ||
66 | - <akka.version>2.6.3</akka.version> | ||
67 | <californium.version>1.0.2</californium.version> | 65 | <californium.version>1.0.2</californium.version> |
68 | <gson.version>2.6.2</gson.version> | 66 | <gson.version>2.6.2</gson.version> |
69 | <velocity.version>1.7</velocity.version> | 67 | <velocity.version>1.7</velocity.version> |
@@ -782,6 +780,11 @@ | @@ -782,6 +780,11 @@ | ||
782 | </dependency> | 780 | </dependency> |
783 | <dependency> | 781 | <dependency> |
784 | <groupId>org.thingsboard.common</groupId> | 782 | <groupId>org.thingsboard.common</groupId> |
783 | + <artifactId>actor</artifactId> | ||
784 | + <version>${project.version}</version> | ||
785 | + </dependency> | ||
786 | + <dependency> | ||
787 | + <groupId>org.thingsboard.common</groupId> | ||
785 | <artifactId>dao-api</artifactId> | 788 | <artifactId>dao-api</artifactId> |
786 | <version>${project.version}</version> | 789 | <version>${project.version}</version> |
787 | </dependency> | 790 | </dependency> |
@@ -1114,16 +1117,6 @@ | @@ -1114,16 +1117,6 @@ | ||
1114 | </exclusions> | 1117 | </exclusions> |
1115 | </dependency> | 1118 | </dependency> |
1116 | <dependency> | 1119 | <dependency> |
1117 | - <groupId>com.typesafe.akka</groupId> | ||
1118 | - <artifactId>akka-actor_${scala.version}</artifactId> | ||
1119 | - <version>${akka.version}</version> | ||
1120 | - </dependency> | ||
1121 | - <dependency> | ||
1122 | - <groupId>com.typesafe.akka</groupId> | ||
1123 | - <artifactId>akka-slf4j_${scala.version}</artifactId> | ||
1124 | - <version>${akka.version}</version> | ||
1125 | - </dependency> | ||
1126 | - <dependency> | ||
1127 | <groupId>org.eclipse.californium</groupId> | 1120 | <groupId>org.eclipse.californium</groupId> |
1128 | <artifactId>californium-core</artifactId> | 1121 | <artifactId>californium-core</artifactId> |
1129 | <version>${californium.version}</version> | 1122 | <version>${californium.version}</version> |