@Test public void testContinuedOperationAfterLayerFail() { createSubmitObjects(); class FailableMockRenderer extends MockRenderer { boolean mockFail; public FailableMockRenderer(MapContent map) { super(map); } public void setFail(boolean fail) { this.mockFail = fail; } @Override protected void pretendToPaint() { graphics.setColor(Color.red); graphics.fill(PANE); super.pretendToPaint(); if (mockFail) { listeners.forEach( listener -> listener.errorOccurred( new RuntimeException( "Simulated layer rendering failure"))); } } }; FailableMockRenderer failableRenderer = new FailableMockRenderer(mapContent); this.renderer = failableRenderer; renderer.setPaintTime(10); clearGraphics(); listener.setExpected(WaitingRenderingExecutorListener.Type.STARTED); listener.setExpected(WaitingRenderingExecutorListener.Type.COMPLETED); executor.submit(mapContent, renderer, graphics, listener); int timeoutMillis = 5000; listener.await(WaitingRenderingExecutorListener.Type.STARTED, timeoutMillis); listener.await(WaitingRenderingExecutorListener.Type.COMPLETED, timeoutMillis); assertTrue(listener.eventReceived(WaitingRenderingExecutorListener.Type.STARTED)); assertTrue(listener.eventReceived(WaitingRenderingExecutorListener.Type.COMPLETED)); checkGraphicsWasPainted(); clearGraphics(); listener.setExpected(WaitingRenderingExecutorListener.Type.STARTED); listener.setExpected(WaitingRenderingExecutorListener.Type.FAILED); failableRenderer.setFail(true); executor.submit(mapContent, renderer, graphics, listener); listener.await(WaitingRenderingExecutorListener.Type.STARTED, timeoutMillis); listener.await(WaitingRenderingExecutorListener.Type.FAILED, timeoutMillis); assertTrue(listener.eventReceived(WaitingRenderingExecutorListener.Type.STARTED)); assertTrue(listener.eventReceived(WaitingRenderingExecutorListener.Type.FAILED)); checkGraphicsWasPainted(); clearGraphics(); listener.setExpected(WaitingRenderingExecutorListener.Type.STARTED); listener.setExpected(WaitingRenderingExecutorListener.Type.COMPLETED); failableRenderer.setFail(false); executor.submit(mapContent, renderer, graphics, listener); listener.await(WaitingRenderingExecutorListener.Type.STARTED, timeoutMillis); listener.await(WaitingRenderingExecutorListener.Type.COMPLETED, timeoutMillis); assertTrue(listener.eventReceived(WaitingRenderingExecutorListener.Type.STARTED)); assertTrue(listener.eventReceived(WaitingRenderingExecutorListener.Type.COMPLETED)); checkGraphicsWasPainted(); }
@Override public synchronized long submit( MapContent mapContent, GTRenderer renderer, Graphics2D graphics, RenderingExecutorListener listener) { long rtnValue = RenderingExecutor.TASK_REJECTED; if (taskExecutor.isShutdown()) { throw new IllegalStateException("Calling submit after the executor has been shutdown"); } if (mapContent == null) { throw new IllegalArgumentException("mapContent must not be null"); } if (graphics == null) { throw new IllegalArgumentException("graphics must not be null"); } if (mapContent.getViewport().isEmpty()) { throw new IllegalArgumentException("The viewport must not be empty"); } if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } if (tasksLatch.getCount() == 0) { tasksLatch = new CountDownLatch(1); long id = NEXT_ID.getAndIncrement(); RenderingExecutorEvent event = new RenderingExecutorEvent(this, id); listener.onRenderingStarted(event); RenderingTask task = new RenderingTask(mapContent, graphics, renderer); Future<Boolean> future = taskExecutor.submit(task); currentTasks.add(new TaskInfo(id, task, mapContent, future, listener)); rtnValue = id; } return rtnValue; }
DefaultRenderingExecutor implements RenderingExecutor { @Override public synchronized long submit( MapContent mapContent, GTRenderer renderer, Graphics2D graphics, RenderingExecutorListener listener) { long rtnValue = RenderingExecutor.TASK_REJECTED; if (taskExecutor.isShutdown()) { throw new IllegalStateException("Calling submit after the executor has been shutdown"); } if (mapContent == null) { throw new IllegalArgumentException("mapContent must not be null"); } if (graphics == null) { throw new IllegalArgumentException("graphics must not be null"); } if (mapContent.getViewport().isEmpty()) { throw new IllegalArgumentException("The viewport must not be empty"); } if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } if (tasksLatch.getCount() == 0) { tasksLatch = new CountDownLatch(1); long id = NEXT_ID.getAndIncrement(); RenderingExecutorEvent event = new RenderingExecutorEvent(this, id); listener.onRenderingStarted(event); RenderingTask task = new RenderingTask(mapContent, graphics, renderer); Future<Boolean> future = taskExecutor.submit(task); currentTasks.add(new TaskInfo(id, task, mapContent, future, listener)); rtnValue = id; } return rtnValue; } }
DefaultRenderingExecutor implements RenderingExecutor { @Override public synchronized long submit( MapContent mapContent, GTRenderer renderer, Graphics2D graphics, RenderingExecutorListener listener) { long rtnValue = RenderingExecutor.TASK_REJECTED; if (taskExecutor.isShutdown()) { throw new IllegalStateException("Calling submit after the executor has been shutdown"); } if (mapContent == null) { throw new IllegalArgumentException("mapContent must not be null"); } if (graphics == null) { throw new IllegalArgumentException("graphics must not be null"); } if (mapContent.getViewport().isEmpty()) { throw new IllegalArgumentException("The viewport must not be empty"); } if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } if (tasksLatch.getCount() == 0) { tasksLatch = new CountDownLatch(1); long id = NEXT_ID.getAndIncrement(); RenderingExecutorEvent event = new RenderingExecutorEvent(this, id); listener.onRenderingStarted(event); RenderingTask task = new RenderingTask(mapContent, graphics, renderer); Future<Boolean> future = taskExecutor.submit(task); currentTasks.add(new TaskInfo(id, task, mapContent, future, listener)); rtnValue = id; } return rtnValue; } DefaultRenderingExecutor(); }
DefaultRenderingExecutor implements RenderingExecutor { @Override public synchronized long submit( MapContent mapContent, GTRenderer renderer, Graphics2D graphics, RenderingExecutorListener listener) { long rtnValue = RenderingExecutor.TASK_REJECTED; if (taskExecutor.isShutdown()) { throw new IllegalStateException("Calling submit after the executor has been shutdown"); } if (mapContent == null) { throw new IllegalArgumentException("mapContent must not be null"); } if (graphics == null) { throw new IllegalArgumentException("graphics must not be null"); } if (mapContent.getViewport().isEmpty()) { throw new IllegalArgumentException("The viewport must not be empty"); } if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } if (tasksLatch.getCount() == 0) { tasksLatch = new CountDownLatch(1); long id = NEXT_ID.getAndIncrement(); RenderingExecutorEvent event = new RenderingExecutorEvent(this, id); listener.onRenderingStarted(event); RenderingTask task = new RenderingTask(mapContent, graphics, renderer); Future<Boolean> future = taskExecutor.submit(task); currentTasks.add(new TaskInfo(id, task, mapContent, future, listener)); rtnValue = id; } return rtnValue; } DefaultRenderingExecutor(); @Override long getPollingInterval(); @Override void setPollingInterval(long interval); @Override synchronized long submit(
            MapContent mapContent,
            GTRenderer renderer,
            Graphics2D graphics,
            RenderingExecutorListener listener); @Override long submit(
            MapContent mapContent,
            List<RenderingOperands> operands,
            RenderingExecutorListener listener); @Override synchronized void cancel(long taskId); @Override synchronized void cancelAll(); @Override void shutdown(); @Override boolean isShutdown(); }
DefaultRenderingExecutor implements RenderingExecutor { @Override public synchronized long submit( MapContent mapContent, GTRenderer renderer, Graphics2D graphics, RenderingExecutorListener listener) { long rtnValue = RenderingExecutor.TASK_REJECTED; if (taskExecutor.isShutdown()) { throw new IllegalStateException("Calling submit after the executor has been shutdown"); } if (mapContent == null) { throw new IllegalArgumentException("mapContent must not be null"); } if (graphics == null) { throw new IllegalArgumentException("graphics must not be null"); } if (mapContent.getViewport().isEmpty()) { throw new IllegalArgumentException("The viewport must not be empty"); } if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } if (tasksLatch.getCount() == 0) { tasksLatch = new CountDownLatch(1); long id = NEXT_ID.getAndIncrement(); RenderingExecutorEvent event = new RenderingExecutorEvent(this, id); listener.onRenderingStarted(event); RenderingTask task = new RenderingTask(mapContent, graphics, renderer); Future<Boolean> future = taskExecutor.submit(task); currentTasks.add(new TaskInfo(id, task, mapContent, future, listener)); rtnValue = id; } return rtnValue; } DefaultRenderingExecutor(); @Override long getPollingInterval(); @Override void setPollingInterval(long interval); @Override synchronized long submit(
            MapContent mapContent,
            GTRenderer renderer,
            Graphics2D graphics,
            RenderingExecutorListener listener); @Override long submit(
            MapContent mapContent,
            List<RenderingOperands> operands,
            RenderingExecutorListener listener); @Override synchronized void cancel(long taskId); @Override synchronized void cancelAll(); @Override void shutdown(); @Override boolean isShutdown(); static final long DEFAULT_POLLING_INTERVAL; }