teetime-framework/TeeTime

RoundRobbinStrategy Divide By Zero on Last Port Removed

Closed this issue · 6 comments

Opened ports are already zero size by the time onPortRemoved is called.

31 Oct 2017 12:45:16,294 WARN [Thread for DataSource-3] exceptionHandling.TerminatingExceptionListener Exception occurred in DataSource-3
java.lang.ArithmeticException: / by zero
at teetime.stage.basic.merger.strategy.RoundRobinStrategy.onPortRemoved(RoundRobinStrategy.java:60)
at teetime.stage.basic.merger.strategy.RoundRobinStrategy.onPortRemoved(RoundRobinStrategy.java:28)
at teetime.util.framework.port.PortList.firePortRemoved(PortList.java:72)
at teetime.util.framework.port.PortList.remove(PortList.java:47)
at teetime.framework.AbstractStage.removeDynamicPort(AbstractStage.java:578)
at com.aexp.bdp.zinc.dataflow.oper.DataMerger.removePort(DataMerger.java:18)
at com.aexp.bdp.zinc.dataflow.oper.DataSource.execute(DataSource.java:257)
at teetime.framework.AbstractStage.executeWithCatchedExceptions(AbstractStage.java:155)
at teetime.framework.AbstractStage.executeByFramework(AbstractStage.java:149)
at teetime.framework.StageFacade.runStage(StageFacade.java:76)
at teetime.framework.scheduling.pushpullmodel.AbstractRunnableStage.run(AbstractRunnableStage.java:56)
at java.lang.Thread.run(Thread.java:748)
at teetime.framework.scheduling.pushpullmodel.TeeTimeThread.run(TeeTimeThread.java:46)

Thanks for your report.

It is not intended to remove all input ports of the merger. Why do you want to do this?

Initially I went down the path of removing producers from the merger when complete. This did not work out well, so now just overriding the Merger and detecting when all producers have completed, then calling abortEventually() on the execution. Let me know if there's a better way. So this may not be a bug.

I'm not sure if I got your point. I think your problem is that you do not know how to terminate a running TeeTime configuration.
TeeTime automatically terminates the execution gracefully if all producers have finished. Each producer sends a termination signal through the stages according to their connections. So, usually there is no reason to terminate the application by yourself. It is only necessary if you use producers that are ment to run infinitely until receiving an external abort command.
Please give some more details if I could not solve your problem.

I assumed terminate() on the execution or a stage terminated the entire flow. The API terminateStage() documentation "seems" to indicate this as well: "Terminates the execution of the stage. After terminating, this stage sends a signal to all its direct and indirect successor stages to terminate."
But I obviously misinterpreted the doc. Anyway my producers know individually when they run out of data to send, so terminateStage() works great for this scenario. Would maybe advise a less "dramatic" API like complete() .

Both issues are closed now. I've added a corresponding article to describe TeeTime's automatic termination process. See the wiki or my comment on the issue 353.