阿卡流。为UniformFanOutShape实现自定义逻辑

时间:2016-11-28 20:59:31

标签: java akka akka-stream

我正在尝试为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拉出,因此消息卡在接收器中。你能帮我解决一下吗? 提前谢谢!

干杯, 塞吉

0 个答案:

没有答案