Interrupting RoboRunner
The highlighted comment was created in this revision.
Something else I'm working on is providing a way to interrupt RoboRunner in the middle of a challenge. I'm not sure in what ways that could potentially mess up RoboRunner yet, but I did have to make a couple of changes to make this work:
First, in order to stop RoboRunner completely (and not just the current battle), I had to make an InterruptedException result in the bypass of all queued battles:
In BattleRunner:
private void getAllFutures(List<Future<String>> futures) { for (Future<String> future : futures) { try { future.get(); } catch (InterruptedException e) { e.printStackTrace(); return; } catch (ExecutionException e) { e.printStackTrace(); } } }
There might be some additional modification, but for now, I just added a return statement if an InterruptedException occurs (will probably also get rid of the printStackTrace call). This prevents calling get() on all remaining Futures. While I think this was an unexpected condition in RoboRunner, in RoboJogger an InterruptedException is now an expected result whenever a stop command is issued for RoboRunner. A remaining question is, what, if anything, will be broken as a result of this?
Another change I made to ScoreLog, such that trying to access battle results for a "botList" that does not exist will not cause a NullPointerException:
In ScoreLog:
public List<BattleScore> getBattleScores(String botList) { List<BattleScore> scores = _scores.get(botList); return (scores == null)? null : ImmutableList.copyOf(_scores.get(botList)); }
I provided the null check on scores. I was kind of surprised that ImmutableList didn't do that by design. The most likely scenario where this happens is related to my other change -- if a challenge is interrupted before battles have been run against all opponents, when I later access results from the ScoreLog, I am not aware of missing results until the getBattleScores method returns null. I suppose I could have also just added a try/catch in my own code for NullPointerException without having to change RoboRunner, but I felt doing so was not the better way of handling it.
These changes are not finalized. I'm just writing about them for the sake of discussion.
I just noticed that for getting battle results, there is a method hasBotList(String) method that I could call before trying to get battle scores. This would prevent the NPE without modifying RoboRunner. Given this, I could see arguing either way about whether getBattleScores should throw NPE or return null for a botList that does not exist.