org.apache.beam.sdk.util.Sleeper Java Examples
The following examples show how to use
org.apache.beam.sdk.util.Sleeper.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: WindowedWordCountIT.java From beam with Apache License 2.0 | 6 votes |
@Override public boolean matchesSafely(List<ShardedFile> outputFiles) { try { // Load output data List<String> outputLines = new ArrayList<>(); for (ShardedFile outputFile : outputFiles) { outputLines.addAll( outputFile.readFilesWithRetries(Sleeper.DEFAULT, BACK_OFF_FACTORY.backoff())); } // Since the windowing is nondeterministic we only check the sums actualCounts = new TreeMap<>(); for (String line : outputLines) { String[] splits = line.split(": ", -1); String word = splits[0]; long count = Long.parseLong(splits[1]); actualCounts.merge(word, count, (a, b) -> a + b); } return actualCounts.equals(expectedWordCounts); } catch (Exception e) { throw new RuntimeException( String.format("Failed to read from sharded output: %s due to exception", outputFiles), e); } }
Example #2
Source File: TextTableProviderTest.java From beam with Apache License 2.0 | 6 votes |
@Test public void testInvalidJson() throws Exception { File deadLetterFile = new File(tempFolder.getRoot(), "dead-letter-file"); Files.write( tempFolder.newFile("test.json").toPath(), INVALID_JSON_TEXT.getBytes(Charsets.UTF_8)); BeamSqlEnv env = BeamSqlEnv.inMemory(new TextTableProvider()); env.executeDdl( String.format( "CREATE EXTERNAL TABLE test %s TYPE text LOCATION '%s/*' " + "TBLPROPERTIES '{\"format\":\"json\", \"deadLetterFile\": \"%s\"}'", SQL_JSON_SCHEMA, tempFolder.getRoot(), deadLetterFile.getAbsoluteFile())); PCollection<Row> rows = BeamSqlRelUtils.toPCollection(pipeline, env.parseQuery("SELECT * FROM test")); PAssert.that(rows).empty(); pipeline.run(); assertThat( new NumberedShardedFile(deadLetterFile.getAbsoluteFile() + "*") .readFilesWithRetries(Sleeper.DEFAULT, BackOff.STOP_BACKOFF), containsInAnyOrder(INVALID_JSON_TEXT)); }
Example #3
Source File: TextTableProviderTest.java From beam with Apache License 2.0 | 6 votes |
@Test public void testWriteLines() throws Exception { File destinationFile = new File(tempFolder.getRoot(), "lines-outputs"); BeamSqlEnv env = BeamSqlEnv.inMemory(new TextTableProvider()); env.executeDdl( String.format( "CREATE EXTERNAL TABLE test %s TYPE text LOCATION '%s' TBLPROPERTIES '{\"format\":\"lines\"}'", SQL_LINES_SCHEMA, destinationFile.getAbsolutePath())); BeamSqlRelUtils.toPCollection( pipeline, env.parseQuery("INSERT INTO test VALUES ('hello'), ('goodbye')")); pipeline.run(); assertThat( new NumberedShardedFile(destinationFile.getAbsolutePath() + "*") .readFilesWithRetries(Sleeper.DEFAULT, BackOff.STOP_BACKOFF), containsInAnyOrder("hello", "goodbye")); }
Example #4
Source File: TextTableProviderTest.java From beam with Apache License 2.0 | 6 votes |
@Test public void testWriteCsv() throws Exception { File destinationFile = new File(tempFolder.getRoot(), "csv-outputs"); BeamSqlEnv env = BeamSqlEnv.inMemory(new TextTableProvider()); // NumberedShardedFile env.executeDdl( String.format( "CREATE EXTERNAL TABLE test %s TYPE text LOCATION '%s' TBLPROPERTIES '{\"format\":\"csv\"}'", SQL_CSV_SCHEMA, destinationFile.getAbsolutePath())); BeamSqlRelUtils.toPCollection( pipeline, env.parseQuery("INSERT INTO test VALUES ('hello', 42), ('goodbye', 13)")); pipeline.run(); assertThat( new NumberedShardedFile(destinationFile.getAbsolutePath() + "*") .readFilesWithRetries(Sleeper.DEFAULT, BackOff.STOP_BACKOFF), containsInAnyOrder("hello,42", "goodbye,13")); }
Example #5
Source File: TextTableProviderTest.java From beam with Apache License 2.0 | 6 votes |
@Test public void testWriteJson() throws Exception { File destinationFile = new File(tempFolder.getRoot(), "json-outputs"); BeamSqlEnv env = BeamSqlEnv.inMemory(new TextTableProvider()); env.executeDdl( String.format( "CREATE EXTERNAL TABLE test %s TYPE text LOCATION '%s' TBLPROPERTIES '{\"format\":\"json\"}'", SQL_JSON_SCHEMA, destinationFile.getAbsolutePath())); BeamSqlRelUtils.toPCollection( pipeline, env.parseQuery("INSERT INTO test(name, age) VALUES ('Jack', 13)")); pipeline.run(); assertThat( new NumberedShardedFile(destinationFile.getAbsolutePath() + "*") .readFilesWithRetries(Sleeper.DEFAULT, BackOff.STOP_BACKOFF), containsInAnyOrder(JSON_TEXT)); }
Example #6
Source File: FileChecksumMatcher.java From beam with Apache License 2.0 | 6 votes |
/** * Computes a checksum of the given sharded file. Not safe to call until the writing is complete. */ private String getActualChecksum(ShardedFile shardedFile) { // Load output data List<String> outputs; try { outputs = shardedFile.readFilesWithRetries(Sleeper.DEFAULT, BACK_OFF_FACTORY.backoff()); } catch (Exception e) { throw new RuntimeException(String.format("Failed to read from: %s", shardedFile), e); } // Verify outputs. Checksum is computed using SHA-1 algorithm actualChecksum = computeHash(outputs); LOG.debug("Generated checksum: {}", actualChecksum); return actualChecksum; }
Example #7
Source File: DatastoreV1.java From beam with Apache License 2.0 | 6 votes |
private RunQueryResponse runQueryWithRetries(RunQueryRequest request) throws Exception { Sleeper sleeper = Sleeper.DEFAULT; BackOff backoff = RUNQUERY_BACKOFF.backoff(); while (true) { try { RunQueryResponse response = datastore.runQuery(request); rpcSuccesses.inc(); return response; } catch (DatastoreException exception) { rpcErrors.inc(); if (NON_RETRYABLE_ERRORS.contains(exception.getCode())) { throw exception; } if (!BackOffUtils.next(sleeper, backoff)) { LOG.error("Aborting after {} retries.", MAX_RETRIES); throw exception; } } } }
Example #8
Source File: DataflowBatchWorkerHarness.java From beam with Apache License 2.0 | 6 votes |
@VisibleForTesting static void processWork( DataflowWorkerHarnessOptions pipelineOptions, final BatchDataflowWorker worker, Sleeper sleeper) throws InterruptedException { int numThreads = chooseNumberOfThreads(pipelineOptions); ExecutorService executor = pipelineOptions.getExecutorService(); final List<Callable<Boolean>> tasks = new ArrayList<>(); LOG.debug("Starting {} worker threads", numThreads); // We start the appropriate number of threads. for (int i = 0; i < numThreads; ++i) { tasks.add(new WorkerThread(worker, sleeper)); } LOG.debug("Waiting for {} worker threads", numThreads); // We wait forever unless there is a big problem. executor.invokeAll(tasks); LOG.error("All threads died."); }
Example #9
Source File: BackOffExecutor.java From feast with Apache License 2.0 | 6 votes |
private void execute(Retriable retriable, FluentBackoff backoff) throws Exception { Sleeper sleeper = Sleeper.DEFAULT; BackOff backOff = backoff.backoff(); while (true) { try { retriable.execute(); break; } catch (Exception e) { if (retriable.isExceptionRetriable(e) && BackOffUtils.next(sleeper, backOff)) { retriable.cleanUpAfterFailure(); } else { throw e; } } } }
Example #10
Source File: V1TestUtil.java From beam with Apache License 2.0 | 5 votes |
private void flushBatch() throws DatastoreException, IOException, InterruptedException { LOG.info("Writing batch of {} entities", entities.size()); Sleeper sleeper = Sleeper.DEFAULT; BackOff backoff = FluentBackoff.DEFAULT .withMaxRetries(MAX_RETRIES) .withInitialBackoff(INITIAL_BACKOFF) .backoff(); while (true) { // Batch mutate entities. try { CommitRequest.Builder commitRequest = CommitRequest.newBuilder(); for (Entity entity : entities) { commitRequest.addMutations(mutationBuilder.apply(entity)); } commitRequest.setMode(CommitRequest.Mode.NON_TRANSACTIONAL); datastore.commit(commitRequest.build()); // Break if the commit threw no exception. break; } catch (DatastoreException exception) { LOG.error( "Error writing to the Datastore ({}): {}", exception.getCode(), exception.getMessage()); if (!BackOffUtils.next(sleeper, backoff)) { LOG.error("Aborting after {} retries.", MAX_RETRIES); throw exception; } } } LOG.info("Successfully wrote {} entities", entities.size()); entities.clear(); }
Example #11
Source File: JdbcIO.java From beam with Apache License 2.0 | 5 votes |
private void executeBatch() throws SQLException, IOException, InterruptedException { if (records.isEmpty()) { return; } Sleeper sleeper = Sleeper.DEFAULT; BackOff backoff = retryBackOff.backoff(); while (true) { try (PreparedStatement preparedStatement = connection.prepareStatement(spec.getStatement().get())) { try { // add each record in the statement batch for (T record : records) { processRecord(record, preparedStatement); } // execute the batch preparedStatement.executeBatch(); // commit the changes connection.commit(); break; } catch (SQLException exception) { if (!spec.getRetryStrategy().apply(exception)) { throw exception; } LOG.warn("Deadlock detected, retrying", exception); // clean up the statement batch and the connection state preparedStatement.clearBatch(); connection.rollback(); if (!BackOffUtils.next(sleeper, backoff)) { // we tried the max number of times throw exception; } } } } records.clear(); }
Example #12
Source File: SnsIO.java From beam with Apache License 2.0 | 5 votes |
@ProcessElement public void processElement(ProcessContext context) throws Exception { PublishRequest request = (PublishRequest) spec.getPublishRequestFn().apply(context.element()); Sleeper sleeper = Sleeper.DEFAULT; BackOff backoff = retryBackoff.backoff(); int attempt = 0; while (true) { attempt++; try { PublishResponse pr = producer.publish(request); context.output(pr); break; } catch (Exception ex) { // Fail right away if there is no retry configuration if (spec.getRetryConfiguration() == null || !spec.getRetryConfiguration().getRetryPredicate().test(ex)) { SNS_WRITE_FAILURES.inc(); LOG.info("Unable to publish message {} due to {} ", request.message(), ex); throw new IOException("Error writing to SNS (no attempt made to retry)", ex); } if (!BackOffUtils.next(sleeper, backoff)) { throw new IOException( String.format( "Error writing to SNS after %d attempt(s). No more attempts allowed", attempt), ex); } else { // Note: this used in test cases to verify behavior LOG.warn(String.format(RETRY_ATTEMPT_LOG, attempt), ex); } } } }
Example #13
Source File: SnsIO.java From beam with Apache License 2.0 | 5 votes |
@ProcessElement public void processElement(ProcessContext context) throws Exception { PublishRequest request = context.element(); Sleeper sleeper = Sleeper.DEFAULT; BackOff backoff = retryBackoff.backoff(); int attempt = 0; while (true) { attempt++; try { PublishResult pr = producer.publish(request); context.output(pr); break; } catch (Exception ex) { // Fail right away if there is no retry configuration if (spec.getRetryConfiguration() == null || !spec.getRetryConfiguration().getRetryPredicate().test(ex)) { SNS_WRITE_FAILURES.inc(); LOG.info("Unable to publish message {} due to {} ", request.getMessage(), ex); throw new IOException("Error writing to SNS (no attempt made to retry)", ex); } if (!BackOffUtils.next(sleeper, backoff)) { throw new IOException( String.format( "Error writing to SNS after %d attempt(s). No more attempts allowed", attempt), ex); } else { // Note: this used in test cases to verify behavior LOG.warn(String.format(RETRY_ATTEMPT_LOG, attempt), ex); } } } }
Example #14
Source File: SimplifiedKinesisClient.java From beam with Apache License 2.0 | 5 votes |
public List<Shard> listShards(final String streamName) throws TransientKinesisException { return wrapExceptions( () -> { List<Shard> shards = Lists.newArrayList(); String lastShardId = null; // DescribeStream has limits that can be hit fairly easily if we are attempting // to configure multiple KinesisIO inputs in the same account. Retry up to // LIST_SHARDS_DESCRIBE_STREAM_MAX_ATTEMPTS times if we end up hitting that limit. // // Only pass the wrapped exception up once that limit is reached. Use FluentBackoff // to implement the retry policy. FluentBackoff retryBackoff = FluentBackoff.DEFAULT .withMaxRetries(LIST_SHARDS_DESCRIBE_STREAM_MAX_ATTEMPTS) .withInitialBackoff(LIST_SHARDS_DESCRIBE_STREAM_INITIAL_BACKOFF); StreamDescription description = null; do { BackOff backoff = retryBackoff.backoff(); Sleeper sleeper = Sleeper.DEFAULT; while (true) { try { description = kinesis.describeStream(streamName, lastShardId).getStreamDescription(); break; } catch (LimitExceededException exc) { if (!BackOffUtils.next(sleeper, backoff)) { throw exc; } } } shards.addAll(description.getShards()); lastShardId = shards.get(shards.size() - 1).getShardId(); } while (description.getHasMoreShards()); return shards; }); }
Example #15
Source File: ClickHouseIO.java From beam with Apache License 2.0 | 5 votes |
private void flush() throws Exception { BackOff backOff = retryBackoff.backoff(); int attempt = 0; if (buffer.isEmpty()) { return; } batchSize.update(buffer.size()); while (true) { try (ClickHouseStatement statement = connection.createStatement()) { statement.sendRowBinaryStream( insertSql(schema(), table()), stream -> { for (Row row : buffer) { ClickHouseWriter.writeRow(stream, schema(), row); } }); buffer.clear(); break; } catch (SQLException e) { if (!BackOffUtils.next(Sleeper.DEFAULT, backOff)) { throw e; } else { retries.inc(); LOG.warn(String.format(RETRY_ATTEMPT_LOG, attempt), e); attempt++; } } } }
Example #16
Source File: DataflowBatchWorkerHarness.java From beam with Apache License 2.0 | 5 votes |
/** Initializes the worker and starts the actual read loop (in {@link #processWork}). */ public void run() throws InterruptedException { // Configure standard file systems. FileSystems.setDefaultPipelineOptions(pipelineOptions); DataflowWorkUnitClient client = new DataflowWorkUnitClient(pipelineOptions, LOG); BatchDataflowWorker worker = BatchDataflowWorker.forBatchIntrinsicWorkerHarness(client, pipelineOptions); worker.startStatusServer(); processWork(pipelineOptions, worker, Sleeper.DEFAULT); }
Example #17
Source File: StreamingDataflowWorker.java From beam with Apache License 2.0 | 5 votes |
private void getConfig(String computation) { BackOff backoff = FluentBackoff.DEFAULT .withInitialBackoff(Duration.millis(100)) .withMaxBackoff(Duration.standardMinutes(1)) .withMaxCumulativeBackoff(Duration.standardMinutes(5)) .backoff(); while (running.get()) { try { if (windmillServiceEnabled) { getConfigFromDataflowService(computation); } else { getConfigFromWindmill(computation); } return; } catch (IllegalArgumentException | IOException e) { LOG.warn("Error fetching config: ", e); try { if (!BackOffUtils.next(Sleeper.DEFAULT, backoff)) { return; } } catch (IOException ioe) { LOG.warn("Error backing off, will not retry: ", ioe); return; } catch (InterruptedException ie) { Thread.currentThread().interrupt(); return; } } } }
Example #18
Source File: PubsubHelper.java From beam with Apache License 2.0 | 5 votes |
private PubsubHelper(PubsubClient pubsubClient, String project) { this.pubsubClient = pubsubClient; this.project = project; createdTopics = new ArrayList<>(); createdSubscriptions = new ArrayList<>(); sleeper = Sleeper.DEFAULT; backOff = FluentBackoff.DEFAULT .withInitialBackoff(Duration.standardSeconds(1)) .withMaxRetries(3) .backoff(); }
Example #19
Source File: GrpcWindmillServer.java From beam with Apache License 2.0 | 5 votes |
private <ResponseT> ResponseT callWithBackoff(Supplier<ResponseT> function) { BackOff backoff = grpcBackoff(); int rpcErrors = 0; while (true) { try { return function.get(); } catch (StatusRuntimeException e) { try { if (++rpcErrors % 20 == 0) { LOG.warn( "Many exceptions calling gRPC. Last exception: {} with status {}", e, e.getStatus()); } if (!BackOffUtils.next(Sleeper.DEFAULT, backoff)) { throw new WindmillServerStub.RpcException(e); } } catch (IOException | InterruptedException i) { if (i instanceof InterruptedException) { Thread.currentThread().interrupt(); } WindmillServerStub.RpcException rpcException = new WindmillServerStub.RpcException(e); rpcException.addSuppressed(i); throw rpcException; } } } }
Example #20
Source File: SolrIO.java From beam with Apache License 2.0 | 4 votes |
private void flushBatch() throws IOException, InterruptedException { if (batch.isEmpty()) { return; } try { UpdateRequest updateRequest = new UpdateRequest(); updateRequest.add(batch); Sleeper sleeper = Sleeper.DEFAULT; BackOff backoff = retryBackoff.backoff(); int attempt = 0; while (true) { attempt++; try { solrClient.process(spec.getCollection(), updateRequest); break; } catch (Exception exception) { // fail immediately if no retry configuration doesn't handle this if (spec.getRetryConfiguration() == null || !spec.getRetryConfiguration().getRetryPredicate().test(exception)) { throw new IOException( "Error writing to Solr (no attempt made to retry)", exception); } // see if we can pause and try again if (!BackOffUtils.next(sleeper, backoff)) { throw new IOException( String.format( "Error writing to Solr after %d attempt(s). No more attempts allowed", attempt), exception); } else { // Note: this used in test cases to verify behavior LOG.warn(String.format(RETRY_ATTEMPT_LOG, attempt), exception); } } } } finally { batch.clear(); } }
Example #21
Source File: DataflowBatchWorkerHarness.java From beam with Apache License 2.0 | 4 votes |
WorkerThread(final BatchDataflowWorker worker, final Sleeper sleeper) { this.worker = worker; this.sleeper = sleeper; this.backOff = createBackOff(); }
Example #22
Source File: DynamoDBIO.java From beam with Apache License 2.0 | 4 votes |
private void flushBatch() throws IOException, InterruptedException { if (batch.isEmpty()) { return; } try { // Since each element is a KV<tableName, writeRequest> in the batch, we need to group them // by tableName Map<String, List<WriteRequest>> mapTableRequest = batch.stream() .collect( Collectors.groupingBy( KV::getKey, Collectors.mapping(KV::getValue, Collectors.toList()))); BatchWriteItemRequest batchRequest = BatchWriteItemRequest.builder().requestItems(mapTableRequest).build(); Sleeper sleeper = Sleeper.DEFAULT; BackOff backoff = retryBackoff.backoff(); int attempt = 0; while (true) { attempt++; try { client.batchWriteItem(batchRequest); break; } catch (Exception ex) { // Fail right away if there is no retry configuration if (spec.getRetryConfiguration() == null || !spec.getRetryConfiguration().getRetryPredicate().test(ex)) { DYNAMO_DB_WRITE_FAILURES.inc(); LOG.info( "Unable to write batch items {} due to {} ", batchRequest.requestItems().entrySet(), ex); throw new IOException("Error writing to DynamoDB (no attempt made to retry)", ex); } if (!BackOffUtils.next(sleeper, backoff)) { throw new IOException( String.format( "Error writing to DynamoDB after %d attempt(s). No more attempts allowed", attempt), ex); } else { // Note: this used in test cases to verify behavior LOG.warn(String.format(RETRY_ATTEMPT_LOG, attempt), ex); } } } } finally { batch.clear(); } }
Example #23
Source File: SpannerIOWriteTest.java From beam with Apache License 2.0 | 4 votes |
@Test public void retryMaxOnSchemaChangeException() throws InterruptedException { List<Mutation> mutationList = Arrays.asList(m((long) 1)); String errString = "Transaction aborted. " + "Database schema probably changed during transaction, retry may succeed."; // mock sleeper so that it does not actually sleep. WriteToSpannerFn.sleeper = Mockito.mock(Sleeper.class); // Respond with Aborted transaction when(serviceFactory.mockDatabaseClient().writeAtLeastOnce(any())) .thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, errString)); // When spanner aborts transaction for more than 5 time, pipeline execution stops with // PipelineExecutionException thrown.expect(PipelineExecutionException.class); thrown.expectMessage(errString); SpannerWriteResult result = pipeline .apply(Create.of(mutationList)) .apply( SpannerIO.write() .withProjectId("test-project") .withInstanceId("test-instance") .withDatabaseId("test-database") .withServiceFactory(serviceFactory) .withBatchSizeBytes(0) .withFailureMode(FailureMode.FAIL_FAST)); // One error PAssert.that(result.getFailedMutations()) .satisfies( m -> { assertEquals(1, Iterables.size(m)); return null; }); pipeline.run().waitUntilFinish(); // 0 calls to sleeper verify(WriteToSpannerFn.sleeper, times(0)).sleep(anyLong()); // 5 write attempts for the single mutationGroup. verify(serviceFactory.mockDatabaseClient(), times(5)).writeAtLeastOnce(any()); }
Example #24
Source File: DynamoDBIO.java From beam with Apache License 2.0 | 4 votes |
private void flushBatch() throws IOException, InterruptedException { if (batch.isEmpty()) { return; } try { // Since each element is a KV<tableName, writeRequest> in the batch, we need to group them // by tableName Map<String, List<WriteRequest>> mapTableRequest = batch.stream() .collect( Collectors.groupingBy( KV::getKey, Collectors.mapping(KV::getValue, Collectors.toList()))); BatchWriteItemRequest batchRequest = new BatchWriteItemRequest(); mapTableRequest .entrySet() .forEach( entry -> batchRequest.addRequestItemsEntry(entry.getKey(), entry.getValue())); Sleeper sleeper = Sleeper.DEFAULT; BackOff backoff = retryBackoff.backoff(); int attempt = 0; while (true) { attempt++; try { client.batchWriteItem(batchRequest); break; } catch (Exception ex) { // Fail right away if there is no retry configuration if (spec.getRetryConfiguration() == null || !spec.getRetryConfiguration().getRetryPredicate().test(ex)) { DYNAMO_DB_WRITE_FAILURES.inc(); LOG.info( "Unable to write batch items {} due to {} ", batchRequest.getRequestItems().entrySet(), ex); throw new IOException("Error writing to DynamoDB (no attempt made to retry)", ex); } if (!BackOffUtils.next(sleeper, backoff)) { throw new IOException( String.format( "Error writing to DynamoDB after %d attempt(s). No more attempts allowed", attempt), ex); } else { // Note: this used in test cases to verify behavior LOG.warn(String.format(RETRY_ATTEMPT_LOG, attempt), ex); } } } } finally { batch.clear(); } }
Example #25
Source File: BaseClickHouseTest.java From beam with Apache License 2.0 | 4 votes |
@BeforeClass public static void setup() throws IOException, InterruptedException { // network sharing doesn't work with ClassRule network = Network.newNetwork(); zookeeper = new GenericContainer<>("zookeeper:3.4.13") .withStartupAttempts(10) .withExposedPorts(2181) .withNetwork(network) .withNetworkAliases("zookeeper"); // so far zookeeper container always starts successfully, so no extra retries zookeeper.start(); clickHouse = (ClickHouseContainer) new ClickHouseContainer(CLICKHOUSE_IMAGE) .withStartupAttempts(10) .withCreateContainerCmdModifier( // type inference for `(CreateContainerCmd) -> cmd.` doesn't work cmd -> ((CreateContainerCmd) cmd) .withMemory(256 * 1024 * 1024L) .withMemorySwap(4L * 1024 * 1024 * 1024L)) .withNetwork(network) .withClasspathResourceMapping( "config.d/zookeeper_default.xml", "/etc/clickhouse-server/config.d/zookeeper_default.xml", BindMode.READ_ONLY); BackOff backOff = FluentBackoff.DEFAULT .withMaxRetries(3) .withInitialBackoff(Duration.standardSeconds(15)) .backoff(); // try to start clickhouse-server a couple of times, see BEAM-6639 while (true) { try { Unreliables.retryUntilSuccess( 10, () -> { DockerClientFactory.instance() .checkAndPullImage(DockerClientFactory.instance().client(), CLICKHOUSE_IMAGE); return null; }); clickHouse.start(); break; } catch (Exception e) { if (!BackOffUtils.next(Sleeper.DEFAULT, backOff)) { throw e; } else { List<Image> images = DockerClientFactory.instance().client().listImagesCmd().withShowAll(true).exec(); String listImagesOutput = "listImagesCmd:\n" + Joiner.on('\n').join(images) + "\n"; LOG.warn("failed to start clickhouse-server\n\n" + listImagesOutput, e); } } } }
Example #26
Source File: SpannerIOWriteTest.java From beam with Apache License 2.0 | 4 votes |
@Test public void retryOnAbortedAndDeadlineExceeded() throws InterruptedException { List<Mutation> mutationList = Arrays.asList(m((long) 1)); String errString = "Transaction aborted. " + "Database schema probably changed during transaction, retry may succeed."; // mock sleeper so that it does not actually sleep. WriteToSpannerFn.sleeper = Mockito.mock(Sleeper.class); // Respond with (1) Aborted transaction a couple of times (2) deadline exceeded // (3) Aborted transaction 3 times (4) deadline exceeded and finally return success. when(serviceFactory.mockDatabaseClient().writeAtLeastOnce(any())) .thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, errString)) .thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, errString)) .thenThrow( SpannerExceptionFactory.newSpannerException( ErrorCode.DEADLINE_EXCEEDED, "simulated Timeout 1")) .thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, errString)) .thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, errString)) .thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, errString)) .thenThrow( SpannerExceptionFactory.newSpannerException( ErrorCode.DEADLINE_EXCEEDED, "simulated Timeout 2")) .thenReturn(Timestamp.now()); SpannerWriteResult result = pipeline .apply(Create.of(mutationList)) .apply( SpannerIO.write() .withProjectId("test-project") .withInstanceId("test-instance") .withDatabaseId("test-database") .withServiceFactory(serviceFactory) .withBatchSizeBytes(0) .withFailureMode(FailureMode.FAIL_FAST)); // Zero error PAssert.that(result.getFailedMutations()) .satisfies( m -> { assertEquals(0, Iterables.size(m)); return null; }); pipeline.run().waitUntilFinish(); // 2 calls to sleeper verify(WriteToSpannerFn.sleeper, times(2)).sleep(anyLong()); // 8 write attempts for the single mutationGroup. verify(serviceFactory.mockDatabaseClient(), times(8)).writeAtLeastOnce(any()); }
Example #27
Source File: SpannerIOWriteTest.java From beam with Apache License 2.0 | 4 votes |
@Test public void retryOnSchemaChangeException() throws InterruptedException { List<Mutation> mutationList = Arrays.asList(m((long) 1)); String errString = "Transaction aborted. " + "Database schema probably changed during transaction, retry may succeed."; // mock sleeper so that it does not actually sleep. WriteToSpannerFn.sleeper = Mockito.mock(Sleeper.class); // respond with 2 timeouts and a success. when(serviceFactory.mockDatabaseClient().writeAtLeastOnce(any())) .thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, errString)) .thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, errString)) .thenReturn(Timestamp.now()); SpannerWriteResult result = pipeline .apply(Create.of(mutationList)) .apply( SpannerIO.write() .withProjectId("test-project") .withInstanceId("test-instance") .withDatabaseId("test-database") .withServiceFactory(serviceFactory) .withBatchSizeBytes(0) .withFailureMode(FailureMode.FAIL_FAST)); // all success, so veryify no errors PAssert.that(result.getFailedMutations()) .satisfies( m -> { assertEquals(0, Iterables.size(m)); return null; }); pipeline.run().waitUntilFinish(); // 0 calls to sleeper verify(WriteToSpannerFn.sleeper, times(0)).sleep(anyLong()); // 3 write attempts for the single mutationGroup. verify(serviceFactory.mockDatabaseClient(), times(3)).writeAtLeastOnce(any()); }
Example #28
Source File: SpannerIOWriteTest.java From beam with Apache License 2.0 | 4 votes |
@Test public void deadlineExceededFailsAfterRetries() throws InterruptedException { List<Mutation> mutationList = Arrays.asList(m((long) 1)); // mock sleeper so that it does not actually sleep. WriteToSpannerFn.sleeper = Mockito.mock(Sleeper.class); // respond with all timeouts. when(serviceFactory.mockDatabaseClient().writeAtLeastOnce(any())) .thenThrow( SpannerExceptionFactory.newSpannerException( ErrorCode.DEADLINE_EXCEEDED, "simulated Timeout")); SpannerWriteResult result = pipeline .apply(Create.of(mutationList)) .apply( SpannerIO.write() .withProjectId("test-project") .withInstanceId("test-instance") .withDatabaseId("test-database") .withServiceFactory(serviceFactory) .withBatchSizeBytes(0) .withMaxCumulativeBackoff(Duration.standardHours(2)) .withFailureMode(SpannerIO.FailureMode.REPORT_FAILURES)); // One error PAssert.that(result.getFailedMutations()) .satisfies( m -> { assertEquals(1, Iterables.size(m)); return null; }); pipeline.run().waitUntilFinish(); // Due to jitter in backoff algorithm, we cannot test for an exact number of retries, // but there will be more than 16 (normally 18). int numSleeps = Mockito.mockingDetails(WriteToSpannerFn.sleeper).getInvocations().size(); assertTrue(String.format("Should be least 16 sleeps, got %d", numSleeps), numSleeps > 16); long totalSleep = Mockito.mockingDetails(WriteToSpannerFn.sleeper).getInvocations().stream() .mapToLong(i -> i.getArgument(0)) .reduce(0L, Long::sum); // Total sleep should be greater then 2x maxCumulativeBackoff: 120m, // because the batch is repeated inidividually due REPORT_FAILURES. assertTrue( String.format("Should be least 7200s of sleep, got %d", totalSleep), totalSleep >= Duration.standardHours(2).getMillis()); // Number of write attempts should be numSleeps + 2 write attempts: // 1 batch attempt, numSleeps/2 batch retries, // then 1 individual attempt + numSleeps/2 individual retries verify(serviceFactory.mockDatabaseClient(), times(numSleeps + 2)).writeAtLeastOnce(any()); }
Example #29
Source File: SpannerIOWriteTest.java From beam with Apache License 2.0 | 4 votes |
@Test public void deadlineExceededRetries() throws InterruptedException { List<Mutation> mutationList = Arrays.asList(m((long) 1)); // mock sleeper so that it does not actually sleep. WriteToSpannerFn.sleeper = Mockito.mock(Sleeper.class); // respond with 2 timeouts and a success. when(serviceFactory.mockDatabaseClient().writeAtLeastOnce(any())) .thenThrow( SpannerExceptionFactory.newSpannerException( ErrorCode.DEADLINE_EXCEEDED, "simulated Timeout 1")) .thenThrow( SpannerExceptionFactory.newSpannerException( ErrorCode.DEADLINE_EXCEEDED, "simulated Timeout 2")) .thenReturn(Timestamp.now()); SpannerWriteResult result = pipeline .apply(Create.of(mutationList)) .apply( SpannerIO.write() .withProjectId("test-project") .withInstanceId("test-instance") .withDatabaseId("test-database") .withServiceFactory(serviceFactory) .withBatchSizeBytes(0) .withFailureMode(SpannerIO.FailureMode.REPORT_FAILURES)); // all success, so veryify no errors PAssert.that(result.getFailedMutations()) .satisfies( m -> { assertEquals(0, Iterables.size(m)); return null; }); pipeline.run().waitUntilFinish(); // 2 calls to sleeper verify(WriteToSpannerFn.sleeper, times(2)).sleep(anyLong()); // 3 write attempts for the single mutationGroup. verify(serviceFactory.mockDatabaseClient(), times(3)).writeAtLeastOnce(any()); }
Example #30
Source File: DatastoreV1.java From beam with Apache License 2.0 | 4 votes |
/** * Writes a batch of mutations to Cloud Datastore. * * <p>If a commit fails, it will be retried up to {@link #MAX_RETRIES} times. All mutations in * the batch will be committed again, even if the commit was partially successful. If the retry * limit is exceeded, the last exception from Cloud Datastore will be thrown. * * @throws DatastoreException if the commit fails or IOException or InterruptedException if * backing off between retries fails. */ private void flushBatch() throws DatastoreException, IOException, InterruptedException { LOG.debug("Writing batch of {} mutations", mutations.size()); Sleeper sleeper = Sleeper.DEFAULT; BackOff backoff = BUNDLE_WRITE_BACKOFF.backoff(); while (true) { // Batch upsert entities. CommitRequest.Builder commitRequest = CommitRequest.newBuilder(); commitRequest.addAllMutations(mutations); commitRequest.setMode(CommitRequest.Mode.NON_TRANSACTIONAL); long startTime = System.currentTimeMillis(), endTime; if (throttler.throttleRequest(startTime)) { LOG.info("Delaying request due to previous failures"); throttledSeconds.inc(WriteBatcherImpl.DATASTORE_BATCH_TARGET_LATENCY_MS / 1000); sleeper.sleep(WriteBatcherImpl.DATASTORE_BATCH_TARGET_LATENCY_MS); continue; } try { datastore.commit(commitRequest.build()); endTime = System.currentTimeMillis(); writeBatcher.addRequestLatency(endTime, endTime - startTime, mutations.size()); throttler.successfulRequest(startTime); rpcSuccesses.inc(); // Break if the commit threw no exception. break; } catch (DatastoreException exception) { if (exception.getCode() == Code.DEADLINE_EXCEEDED) { /* Most errors are not related to request size, and should not change our expectation of * the latency of successful requests. DEADLINE_EXCEEDED can be taken into * consideration, though. */ endTime = System.currentTimeMillis(); writeBatcher.addRequestLatency(endTime, endTime - startTime, mutations.size()); } // Only log the code and message for potentially-transient errors. The entire exception // will be propagated upon the last retry. LOG.error( "Error writing batch of {} mutations to Datastore ({}): {}", mutations.size(), exception.getCode(), exception.getMessage()); rpcErrors.inc(); if (NON_RETRYABLE_ERRORS.contains(exception.getCode())) { throw exception; } if (!BackOffUtils.next(sleeper, backoff)) { LOG.error("Aborting after {} retries.", MAX_RETRIES); throw exception; } } } LOG.debug("Successfully wrote {} mutations", mutations.size()); mutations.clear(); mutationsSize = 0; }