/** * The same as calling {@link #runWithRetries(Runnable, RetryStrategy, Predicate)} where a retryable failure * is defined as a {@link RetryableException}. * * @param runnable the callable to run * @param retryStrategy the retry strategy to use if the supplier fails in a retryable way * @param <T> the type of throwable * @throws T if the runnable failed in a way that is not retryable, or the retries were exhausted. * If retries were exhausted, a {@link RetriesExhaustedException} will be added as a suppressed exception. * If the call was interrupted while waiting between retries, the {@link InterruptedException} will be added * as a suppressed exception */ public static <T extends Throwable> void runWithRetries(Runnable<T> runnable, RetryStrategy retryStrategy) throws T { runWithRetries(runnable, retryStrategy, DEFAULT_PREDICATE); }
/** * The same as calling {@link #runWithRetries(Runnable, RetryStrategy, Predicate)} where a retryable failure * is defined as a {@link RetryableException}. * * @param runnable the callable to run * @param retryStrategy the retry strategy to use if the supplier fails in a retryable way * @param <T> the type of throwable * @throws T if the runnable failed in a way that is not retryable, or the retries were exhausted. * If retries were exhausted, a {@link RetriesExhaustedException} will be added as a suppressed exception. * If the call was interrupted while waiting between retries, the {@link InterruptedException} will be added * as a suppressed exception */ public static <T extends Throwable> void runWithRetries(Runnable<T> runnable, RetryStrategy retryStrategy) throws T { runWithRetries(runnable, retryStrategy, DEFAULT_PREDICATE); }
@Override public void createTopic(final String topic) throws TopicAlreadyExistsException, IOException { if (messagingAdmin == null) { throw new UnsupportedOperationException("Messaging not supported"); } try { Retries.runWithRetries(() -> messagingAdmin.createTopic(topic), retryStrategy); } catch (TopicAlreadyExistsException | IOException | RuntimeException | Error e) { throw e; } catch (Exception e) { // this should never happen throw new RuntimeException(e); } }
@Override public void deleteTopic(final String topic) throws TopicNotFoundException, IOException { if (messagingAdmin == null) { throw new UnsupportedOperationException("Messaging not supported"); } try { Retries.runWithRetries(() -> messagingAdmin.deleteTopic(topic), retryStrategy); } catch (TopicNotFoundException | IOException | RuntimeException | Error e) { throw e; } catch (Exception e) { // this should never happen throw new RuntimeException(e); } }
@Override public void createTopic(final String topic, final Map<String, String> properties) throws TopicAlreadyExistsException, IOException { if (messagingAdmin == null) { throw new UnsupportedOperationException("Messaging not supported"); } try { Retries.runWithRetries(() -> messagingAdmin.createTopic(topic, properties), retryStrategy); } catch (TopicAlreadyExistsException | IOException | RuntimeException | Error e) { throw e; } catch (Exception e) { // this should never happen throw new RuntimeException(e); } }
@Override public void updateTopic(final String topic, final Map<String, String> properties) throws TopicNotFoundException, IOException { if (messagingAdmin == null) { throw new UnsupportedOperationException("Messaging not supported"); } try { Retries.runWithRetries(() -> messagingAdmin.updateTopic(topic, properties), retryStrategy); } catch (TopicNotFoundException | IOException | RuntimeException | Error e) { throw e; } catch (Exception e) { // this should never happen throw new RuntimeException(e); } }
@Override public void deleteTopic(final String topic) throws TopicNotFoundException, IOException { if (messagingAdmin == null) { throw new UnsupportedOperationException("Messaging not supported"); } try { Retries.runWithRetries(() -> messagingAdmin.deleteTopic(topic), retryStrategy); } catch (TopicNotFoundException | IOException | RuntimeException | Error e) { throw e; } catch (Exception e) { // this should never happen throw new RuntimeException(e); } } }
@Override public void createTopic(final String topic) throws TopicAlreadyExistsException, IOException { if (messagingAdmin == null) { throw new UnsupportedOperationException("Messaging not supported"); } try { Retries.runWithRetries(() -> messagingAdmin.createTopic(topic), retryStrategy); } catch (TopicAlreadyExistsException | IOException | RuntimeException | Error e) { throw e; } catch (Exception e) { // this should never happen throw new RuntimeException(e); } }
@Override public void createTopic(final String topic, final Map<String, String> properties) throws TopicAlreadyExistsException, IOException { if (messagingAdmin == null) { throw new UnsupportedOperationException("Messaging not supported"); } try { Retries.runWithRetries(() -> messagingAdmin.createTopic(topic, properties), retryStrategy); } catch (TopicAlreadyExistsException | IOException | RuntimeException | Error e) { throw e; } catch (Exception e) { // this should never happen throw new RuntimeException(e); } }
@Override public void updateTopic(final String topic, final Map<String, String> properties) throws TopicNotFoundException, IOException { if (messagingAdmin == null) { throw new UnsupportedOperationException("Messaging not supported"); } try { Retries.runWithRetries(() -> messagingAdmin.updateTopic(topic, properties), retryStrategy); } catch (TopicNotFoundException | IOException | RuntimeException | Error e) { throw e; } catch (Exception e) { // this should never happen throw new RuntimeException(e); } }
@Override public void dropDataset(final String name) throws DatasetManagementException { Retries.runWithRetries(() -> { try { datasetFramework.deleteInstance(createInstanceId(name)); } catch (IOException ioe) { // not the prettiest message, but this replicates exactly what RemoteDatasetFramework throws throw new DatasetManagementException(String.format("Failed to delete instance %s, details: %s", name, ioe.getMessage()), ioe); } }, retryStrategy); }
@Override public void updateDataset(final String name, final DatasetProperties properties) throws DatasetManagementException { Retries.runWithRetries(() -> { try { datasetFramework.updateInstance(createInstanceId(name), properties); } catch (IOException ioe) { // not the prettiest message, but this replicates exactly what RemoteDatasetFramework throws throw new DatasetManagementException(String.format("Failed to update instance %s, details: %s", name, ioe.getMessage()), ioe); } }, retryStrategy); }
@Override public void updateDataset(final String name, final DatasetProperties properties) throws DatasetManagementException { Retries.runWithRetries(() -> { try { datasetFramework.updateInstance(createInstanceId(name), properties); } catch (IOException ioe) { // not the prettiest message, but this replicates exactly what RemoteDatasetFramework throws throw new DatasetManagementException(String.format("Failed to update instance %s, details: %s", name, ioe.getMessage()), ioe); } }, retryStrategy); }
@Override public void truncateDataset(final String name) throws DatasetManagementException { Retries.runWithRetries(() -> { try { datasetFramework.truncateInstance(createInstanceId(name)); } catch (IOException ioe) { // not the prettiest message, but this replicates exactly what RemoteDatasetFramework throws throw new DatasetManagementException(String.format("Failed to truncate instance %s, details: %s", name, ioe.getMessage()), ioe); } }, retryStrategy); }
@Override public void truncateDataset(final String name) throws DatasetManagementException { Retries.runWithRetries(() -> { try { datasetFramework.truncateInstance(createInstanceId(name)); } catch (IOException ioe) { // not the prettiest message, but this replicates exactly what RemoteDatasetFramework throws throw new DatasetManagementException(String.format("Failed to truncate instance %s, details: %s", name, ioe.getMessage()), ioe); } }, retryStrategy); }
@Override public void dropDataset(final String name) throws DatasetManagementException { Retries.runWithRetries(() -> { try { datasetFramework.deleteInstance(createInstanceId(name)); } catch (IOException ioe) { // not the prettiest message, but this replicates exactly what RemoteDatasetFramework throws throw new DatasetManagementException(String.format("Failed to delete instance %s, details: %s", name, ioe.getMessage()), ioe); } }, retryStrategy); }
private void deleteLocalDatasets() { for (final Map.Entry<String, String> entry : datasetFramework.getDatasetNameMapping().entrySet()) { if (keepLocal(entry.getKey())) { continue; } final String localInstanceName = entry.getValue(); final DatasetId instanceId = new DatasetId(workflowRunId.getNamespace(), localInstanceName); LOG.debug("Deleting Workflow local dataset instance: {}", localInstanceName); try { Retries.runWithRetries(() -> datasetFramework.deleteInstance(instanceId), RetryStrategies.fixDelay(Constants.Retry.LOCAL_DATASET_OPERATION_RETRY_DELAY_SECONDS, TimeUnit.SECONDS)); } catch (Exception e) { LOG.warn("Failed to delete the Workflow local dataset instance {}", localInstanceName, e); } } }
@Override public void createDataset(final String name, final String type, final DatasetProperties properties) throws DatasetManagementException { Retries.runWithRetries(() -> { try { // we have to do this check since addInstance method can only be used when app impersonation is enabled if (principalId != null) { datasetFramework.addInstance(type, createInstanceId(name), properties, principalId); } else { datasetFramework.addInstance(type, createInstanceId(name), properties); } } catch (IOException ioe) { // not the prettiest message, but this replicates exactly what RemoteDatasetFramework throws throw new DatasetManagementException(String.format("Failed to add instance %s, details: %s", name, ioe.getMessage()), ioe); } }, retryStrategy); }
/** * Persists running state to the {@link RemoteRuntimeDataset}. */ private void persistRunningState(ProgramRunId programRunId, ProgramOptions programOptions) { // Only retry for a max of 5 seconds. If it still failed to persist, it will fail to launch the program. RetryStrategy retryStrategy = RetryStrategies.timeLimit(5L, TimeUnit.SECONDS, RetryStrategies.exponentialDelay(100L, 1000L, TimeUnit.MILLISECONDS)); Retries.runWithRetries(() -> Transactionals.execute(transactional, context -> { RemoteRuntimeDataset dataset = RemoteRuntimeDataset.create(context, datasetFramework); dataset.write(programRunId, programOptions); }, RetryableException.class), retryStrategy); }
/** * Persists running state to the {@link RemoteRuntimeDataset}. */ private void persistRunningState(ProgramRunId programRunId, ProgramOptions programOptions) { // Only retry for a max of 5 seconds. If it still failed to persist, it will fail to launch the program. RetryStrategy retryStrategy = RetryStrategies.timeLimit(5L, TimeUnit.SECONDS, RetryStrategies.exponentialDelay(100L, 1000L, TimeUnit.MILLISECONDS)); Retries.runWithRetries(() -> Transactionals.execute(transactional, context -> { RemoteRuntimeDataset dataset = RemoteRuntimeDataset.create(context, datasetFramework); dataset.write(programRunId, programOptions); }, RetryableException.class), retryStrategy); }