private void onConnectionError(@Nullable Integer responseCode, long droppedEvents, long reportedEvents) { dropped += droppedEvents; reported += reportedEvents; // if the response code is null, the server did not even send a response if (responseCode == null || responseCode > 429) { // this server seems to have connection or capacity issues, try next switchToNextServerUrl(); } else if (responseCode == 404) { logger.warn("It seems like you are using a version of the APM Server which is not compatible with this agent. " + "Please use APM Server 6.5.0 or newer."); } long backoffTimeSeconds = getBackoffTimeSeconds(errorCount++); logger.info("Backing off for {} seconds (±10%)", backoffTimeSeconds); final long backoffTimeMillis = TimeUnit.SECONDS.toMillis(backoffTimeSeconds); if (backoffTimeMillis > 0) { // back off because there are connection issues with the apm server try { synchronized (WAIT_LOCK) { WAIT_LOCK.wait(backoffTimeMillis + getRandomJitter(backoffTimeMillis)); } } catch (InterruptedException e) { logger.info("APM Agent ReportingEventHandler had been interrupted", e); } } }
@Test void testExponentialBackoff() { assertThat(IntakeV2ReportingEventHandler.getBackoffTimeSeconds(0)).isEqualTo(0); assertThat(IntakeV2ReportingEventHandler.getBackoffTimeSeconds(1)).isEqualTo(1); assertThat(IntakeV2ReportingEventHandler.getBackoffTimeSeconds(2)).isEqualTo(4); assertThat(IntakeV2ReportingEventHandler.getBackoffTimeSeconds(3)).isEqualTo(9); assertThat(IntakeV2ReportingEventHandler.getBackoffTimeSeconds(4)).isEqualTo(16); assertThat(IntakeV2ReportingEventHandler.getBackoffTimeSeconds(5)).isEqualTo(25); assertThat(IntakeV2ReportingEventHandler.getBackoffTimeSeconds(6)).isEqualTo(36); assertThat(IntakeV2ReportingEventHandler.getBackoffTimeSeconds(7)).isEqualTo(36); }