我正在尝试为UniformFanOutShape实现自定义逻辑,但似乎我做错了什么。我的目标是实现自定义形状,它将根据消息内部的数据将消息重定向到正确的Outlet。
public class SPMessageSplitter extends GraphStage<UniformFanOutShape<SPFinderData,SPFinderData>> {
//Inlet
public final Inlet<SPFinderData> in = Inlet.create("Inlet.in");
//Outlets
public final Outlet<SPFinderData> flOut = Outlet.create("FL.out");
public final Outlet<SPFinderData> sOut = Outlet.create("SD.out");
public final Outlet<SPFinderData> cOut = Outlet.create("CD.out");
private Outlet[] outlets = {flOut, sOut, cOut};
//Shape
private final UniformFanOutShape<SPFinderData, SPFinderData> shape = new UniformFanOutShape<>(in, (Outlet<SPFinderData>[])outlets);
@Override
public UniformFanOutShape<SPFinderData, SPFinderData> shape() {
return shape;
}
@Override
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
IntReplacement pendingCount = new IntReplacement(3);
IntReplacement downstreamRunning = new IntReplacement(3);
BoolReplacement pending0 = BoolReplacement.TRUE;
BoolReplacement pending1 = BoolReplacement.TRUE;
BoolReplacement pending2 = BoolReplacement.TRUE;
//In handler
{
setHandler(in, new AbstractInHandler() {
@Override
public void onPush() throws Exception {
SPFinderData elem = grab(in);
System.out.print("Splitter: ON PUSH!");
push(findOutlet(elem), elem);
pendingCount.setInteger(downstreamRunning.getInteger());
}
});
}
//Handler for FL.out outlet
{
setHandler(flOut, new AbstractOutHandler() {
@Override
public void onPull() throws Exception {
{
pendingCount.setInteger(pendingCount.getInteger() - 1);
pending0.setValue(false);
if (pendingCount.getInteger() == 0) pull(in);
}
}
@Override
public void onDownstreamFinish() {
downstreamRunning.setInteger(downstreamRunning.getInteger() - 1);
if (downstreamRunning.getInteger() == 0) completeStage();
else {
if (pending0.getBoolValue()) pendingCount.setInteger(pendingCount.getInteger() - 1);
if (pendingCount.getInteger() == 0 && !hasBeenPulled(in)) pull(in);
}
}
});
}
//Handler for SD.out outlet
{
setHandler(sOut, new AbstractOutHandler() {
@Override
public void onPull() throws Exception {
{
pendingCount.setInteger(pendingCount.getInteger() - 1);
pending1.setValue(false);
if (pendingCount.getInteger() == 0) pull(in);
}
}
@Override
public void onDownstreamFinish() {
downstreamRunning.setInteger(downstreamRunning.getInteger() - 1);
if (downstreamRunning.getInteger() == 0) completeStage();
else {
if (pending1.getBoolValue()) pendingCount.setInteger(pendingCount.getInteger() - 1);
if (pendingCount.getInteger() == 0 && !hasBeenPulled(in)) pull(in);
}
}
});
}
//Handler for CDir.out outlet
{
setHandler(cOut, new AbstractOutHandler() {
@Override
public void onPull() throws Exception {
{
pendingCount.setInteger(pendingCount.getInteger() - 1);
pending2.setValue(false);
if (pendingCount.getInteger() == 0) pull(in);
}
}
@Override
public void onDownstreamFinish() {
downstreamRunning.setInteger(downstreamRunning.getInteger() - 1);
if (downstreamRunning.getInteger() == 0) completeStage();
else {
if (pending2.getBoolValue()) pendingCount.setInteger(pendingCount.getInteger() - 1);
if (pendingCount.getInteger() == 0 && !hasBeenPulled(in)) pull(in);
}
}
});
}
};
}
private Outlet<SPFinderData> findOutlet(SPFinderData elem) {
if(elem.isF() || elem.isL()) {
System.out.println("Splitte: Redirect to FL.");
return flOut;
} else if(!elem.getCD()) {
System.out.println("Splitte: Redirect to S.");
return sOut;
}
System.out.println("Splitte: Redirect to C.");
return cOut;
}
}
我已经从数组中创建了Sink,其中包含49个元素。我还将loggin放入几乎所有形状的onPush和onPull函数中。但结果是,我新创建的形状仅处理4条消息,然后停止从Inlet拉出,因此消息卡在接收器中。你能帮我解决一下吗? 提前谢谢!
干杯, 塞吉