| 642 | } |
| 643 | |
| 644 | private void addStatementTimeout(CompletableFuture<?> result, TimeoutToken timeoutToken) { |
| 645 | long durationNs = timeoutToken.disable(); |
| 646 | TimeValue timeout = timeoutToken.timeout(); |
| 647 | final UUID jobId = mostRecentJobID; |
| 648 | long timeoutNanos = timeout.nanos(); |
| 649 | if (jobId == null || timeoutNanos <= 0) { |
| 650 | return; |
| 651 | } |
| 652 | long remainingTimeoutNs = timeoutNanos - durationNs; |
| 653 | Runnable kill = () -> { |
| 654 | if (result.isDone()) { |
| 655 | return; |
| 656 | } |
| 657 | KillJobsNodeRequest request = new KillJobsNodeRequest( |
| 658 | List.of(), |
| 659 | List.of(jobId), |
| 660 | sessionSettings.userName(), |
| 661 | JobKilledException.of("statement_timeout (" + timeout.toString() + "/exec)") |
| 662 | ); |
| 663 | executor.client().execute(KillJobsNodeAction.INSTANCE, request); |
| 664 | }; |
| 665 | if (remainingTimeoutNs <= 0) { |
| 666 | kill.run(); |
| 667 | } else { |
| 668 | ScheduledExecutorService scheduler = executor.scheduler(); |
| 669 | ScheduledFuture<?> schedule = scheduler.schedule(kill, remainingTimeoutNs, TimeUnit.NANOSECONDS); |
| 670 | result.whenComplete((_, _) -> schedule.cancel(false)); |
| 671 | } |
| 672 | } |
| 673 | |
| 674 | private CompletableFuture<?> triggerDeferredExecutions(boolean forceBulk) { |
| 675 | int numDeferred = deferredExecutionsByStmt.size(); |