Improve TbMsgGeneratorNode to be executed in singleton mode

This commit is contained in:
Igor Kulikov 2019-02-13 18:32:49 +02:00
parent bf14c3a955
commit 7e96edd6ac
5 changed files with 50 additions and 10 deletions

View File

@ -57,6 +57,7 @@ import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
import scala.concurrent.duration.Duration; import scala.concurrent.duration.Duration;
import java.util.Collections; import java.util.Collections;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -102,6 +103,12 @@ class DefaultTbContext implements TbContext {
scheduleMsgWithDelay(new RuleNodeToSelfMsg(msg), delayMs, nodeCtx.getSelfActor()); scheduleMsgWithDelay(new RuleNodeToSelfMsg(msg), delayMs, nodeCtx.getSelfActor());
} }
@Override
public boolean isLocalEntity(EntityId entityId) {
Optional<ServerAddress> address = mainCtx.getRoutingService().resolveById(entityId);
return !address.isPresent();
}
private void scheduleMsgWithDelay(Object msg, long delayInMs, ActorRef target) { private void scheduleMsgWithDelay(Object msg, long delayInMs, ActorRef target) {
mainCtx.getScheduler().scheduleOnce(Duration.create(delayInMs, TimeUnit.MILLISECONDS), target, msg, mainCtx.getActorSystem().dispatcher(), nodeCtx.getSelfActor()); mainCtx.getScheduler().scheduleOnce(Duration.create(delayInMs, TimeUnit.MILLISECONDS), target, msg, mainCtx.getActorSystem().dispatcher(), nodeCtx.getSelfActor());
} }

View File

@ -83,7 +83,9 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
@Override @Override
public void onClusterEventMsg(ClusterEventMsg msg) { public void onClusterEventMsg(ClusterEventMsg msg) {
if (tbNode != null) {
tbNode.onClusterEventMsg(defaultCtx, msg);
}
} }
public void onRuleToSelfMsg(RuleNodeToSelfMsg msg) throws Exception { public void onRuleToSelfMsg(RuleNodeToSelfMsg msg) throws Exception {

View File

@ -51,6 +51,8 @@ public interface TbContext {
void tellSelf(TbMsg msg, long delayMs); void tellSelf(TbMsg msg, long delayMs);
boolean isLocalEntity(EntityId entityId);
void tellFailure(TbMsg msg, Throwable th); void tellFailure(TbMsg msg, Throwable th);
void updateSelf(RuleNode self); void updateSelf(RuleNode self);

View File

@ -16,6 +16,7 @@
package org.thingsboard.rule.engine.api; package org.thingsboard.rule.engine.api;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -30,4 +31,6 @@ public interface TbNode {
void destroy(); void destroy();
default void onClusterEventMsg(TbContext ctx, ClusterEventMsg msg) {}
} }

View File

@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -56,6 +57,7 @@ public class TbMsgGeneratorNode implements TbNode {
private EntityId originatorId; private EntityId originatorId;
private UUID nextTickId; private UUID nextTickId;
private TbMsg prevMsg; private TbMsg prevMsg;
private volatile boolean initialized;
@Override @Override
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
@ -66,21 +68,42 @@ public class TbMsgGeneratorNode implements TbNode {
} else { } else {
originatorId = ctx.getSelfId(); originatorId = ctx.getSelfId();
} }
updateGeneratorState(ctx);
}
@Override
public void onClusterEventMsg(TbContext ctx, ClusterEventMsg msg) {
updateGeneratorState(ctx);
}
private void updateGeneratorState(TbContext ctx) {
if (ctx.isLocalEntity(originatorId)) {
if (!initialized) {
initialized = true;
this.jsEngine = ctx.createJsScriptEngine(config.getJsScript(), "prevMsg", "prevMetadata", "prevMsgType"); this.jsEngine = ctx.createJsScriptEngine(config.getJsScript(), "prevMsg", "prevMetadata", "prevMsgType");
scheduleTickMsg(ctx); scheduleTickMsg(ctx);
} }
} else if (initialized) {
initialized = false;
destroy();
}
}
@Override @Override
public void onMsg(TbContext ctx, TbMsg msg) { public void onMsg(TbContext ctx, TbMsg msg) {
if (msg.getType().equals(TB_MSG_GENERATOR_NODE_MSG) && msg.getId().equals(nextTickId)) { if (initialized && msg.getType().equals(TB_MSG_GENERATOR_NODE_MSG) && msg.getId().equals(nextTickId)) {
withCallback(generate(ctx), withCallback(generate(ctx),
m -> { m -> {
if (initialized) {
ctx.tellNext(m, SUCCESS); ctx.tellNext(m, SUCCESS);
scheduleTickMsg(ctx); scheduleTickMsg(ctx);
}
}, },
t -> { t -> {
if (initialized) {
ctx.tellFailure(msg, t); ctx.tellFailure(msg, t);
scheduleTickMsg(ctx); scheduleTickMsg(ctx);
}
}); });
} }
} }
@ -102,8 +125,10 @@ public class TbMsgGeneratorNode implements TbNode {
if (prevMsg == null) { if (prevMsg == null) {
prevMsg = ctx.newMsg("", originatorId, new TbMsgMetaData(), "{}"); prevMsg = ctx.newMsg("", originatorId, new TbMsgMetaData(), "{}");
} }
if (initialized) {
TbMsg generated = jsEngine.executeGenerate(prevMsg); TbMsg generated = jsEngine.executeGenerate(prevMsg);
prevMsg = ctx.newMsg(generated.getType(), originatorId, generated.getMetaData(), generated.getData()); prevMsg = ctx.newMsg(generated.getType(), originatorId, generated.getMetaData(), generated.getData());
}
return prevMsg; return prevMsg;
}); });
} }
@ -113,6 +138,7 @@ public class TbMsgGeneratorNode implements TbNode {
prevMsg = null; prevMsg = null;
if (jsEngine != null) { if (jsEngine != null) {
jsEngine.destroy(); jsEngine.destroy();
jsEngine = null;
} }
} }
} }