|
Often times, a Processor will route a FlowFile to a relationship where the user wants the logic to dictate that the FlowFile should be retried X number of times, and then upon X failures, the FlowFile should be routed elsewhere.
The typical pattern in NiFi for handling retries is to route a 'failure' relationship back to the processor itself. This has the downside, though, of not being able to handle the logic above, of try X number of times, then do something else. It results in just retrying forever.
This often results in users building complicated logic into the flow with multiple Processors, or using the RetryFlowFile processor. But this approach has its own downsides. It's tedious to set up. It's not very clean on the UI, making it less obvious what is happening in the flow. And most importantly, if we have a flow A -> B -> A, and both of the connections fill up with backpressure we end up in a situation where data can stop flowing. Self-loops don't have this issue because there are special provisions for this in the framework to avoid the situation.
To address all of these issues, we should supply a mechanism that is driven by the framework in which any Processor can be easily configured to retry some specified number of times.
This is a complex task that involves updates to many parts of the framework, including UI, REST backend, data model, and processing/engine.
| # | Title | Notes |
|---|---|---|
| 1 | UI: Provide ability to configure how many retries per Relationship |
|
| 2 | UI: Provide ability to configure backoff mechanism |
|
| 3 | UI: Provide ability to configure Max Backoff Period | When a FlowFile is penalized or a Processor yielded, we should wait double the last retry period (i.e., use an exponential backoff) up to some configurable max amount of time. User must be able to specify the max amount of time. |
| 4 | UI: Introduce new tab in Processor config dialog for Relationships | Currently, a user configures which Relationships should be auto-terminated in the Settings tab of the configuration dialog. We now will have more complex configuration for each Relationship and as such need to a new tab in this dialog. The ability to configure which relationships are auto-terminated should be removed from the Settings tab and added to this new Relationships tab. This tab should list all Relationships for the Processor and allow the user to configure whether or not to auto-terminate the Relationship, as it does now. It should also allow configuring whether or not FlowFiles routed to a given Relationship should be retried. It will be valid to configure both a specific number of retries AND auto-terminating the Relationship. Or just one or the other. This tab should also contain the Max Backoff Period and Backoff Mechanism outlined above. |
| 5 | Update DTO Data Model | The ProcessorConfigDTO data model must be updated to include the new logic. The DTO will need the following members added: Set<String> retriedRelationships; // The name of any Relationship that is to be retried. String backoffMechanism; // Should be an enum but currently the DTO's do not make use of enums and instead use String objects with an Allowable Values specified in the @ApiModelProperty annotation. Best to stay consistent. String maxBackoffPeriod; This means we will also need to ensure that we update the DtoFactory class to properly populate these values when creating the DTO. |
| 6 | Update ProcessorResource to validate arguments | The new retriedRelationships, backoffMechanism, and maxBackoffPeriod elements should have their values validated when attempting to perform a POST or a PUT to a Processor. The request should throw an IllegalArgumentException if one of the values is invalid. For example, if the max backoff period were set to "5" instead of "5 mins" |
| 7 | Update Flow Data Model | Update the serialization logic to persist these new configurations on the Processor and to handle the deserialization logic. Must also update the flow-configuration.xsd schema |
| 8 | Update Versioned Processor Config Data Model | Update the VersionedProcessor in much the same way that we update the DTO so that changes to the processor are tracked in registry, exported versions, etc. |
| 9 | Update Flow Mapper | Update the FlowMapper to ensure that the new fields in the VersionedProcessor are populated when mapping a ProcessorNode to a VersionedProcessor |
| 10 | Update Versioned Flow Comparator | Update VersionedFlowComparator so that if the configuration for retry logic is updated, it's recognized as a local change |
| 11 | Update Flow Fingerprint | Update Flow Fingerprint to ensure that nodes within the cluster have the same configuration values |
| 12 | Update ProcessorNode | Update ProcessorNode to hold the new configuration elements for retry logic configuration in much the same way as the DTO data model. However, for the ProcessorNode, it will be important that an enum be used for the backoff mechanism. |
| 13 | Update ProcessContext | Update ProcessContext so that processor developers have the ability to determine whether or not a given Relationship is configured for retrying and how many times it is to be retried |
| 14 | Update User Guide | A new section must be added to the User Guide explaining the new tab and how to configure the different options. Additionally, any screenshots that show the Processor configuration dialog are now outdated and should be updated. |
| 15 | Implement the Retry Logic | A description of the Implementation Logic is given below. |
| 16 | Update FileSystemSwapManager | Update the FileSystemSwapManager to ensure that the data that is written out indicates the number of retries for a given FlowFile. Ensure that swap files written in the old format, which does not include this information, are still readable. |
This is a major feature, which touches critical parts of the framework. The following testing needs to be done, at a minimum, in order to consider the feature a success.
| # | Title | Notes |
|---|---|---|
| 1 | Update StandardProcessSessionIT |
|
| 2 | Create System Test |
|
| 3 | Create Stateless System Test |
|
| 4 | Manual Testing |
|
Most of the logic for implementing this feature will exist in the StandardProcessSession.
The StandardProcessSession's checkpoint() logic must be updated to take the following logic into consideration.
It will also be important to take into account the performance impacts of the changes. Specifically, there should be no noticeable impact in throughput when the data is not retried. To verify this, we will need to run some simple flows like GenerateFlowFile → UpdateAttribute → UpdateAttribute before and after the change with no retry logic configured. The performance should be nearly identical.
The following are out of scope for this Feature Proposal but worth considering in the future: