[
https://issues.apache.org/jira/browse/NIP-50?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Mark Payne resolved NIP-50.
---------------------------
Resolution: Fixed
Given the lazy consensus vote
([https://lists.apache.org/thread/pcxgkbjg498m1sfwj6onl7hkpj80tj19)] this NIP
has been approved.
> Partial Component State Updates
> -------------------------------
>
> Key: NIP-50
> URL: https://issues.apache.org/jira/browse/NIP-50
> Project: NiFi Improvement Proposal
> Issue Type: Improvement
> Reporter: Mark Payne
> Assignee: Mark Payne
> Priority: Major
>
> h2. Motivation
> {{setState}} and {{replace}} replace the entire state map. To change one key,
> a component must get the map, copy it, change the key, and write the whole
> map back. That is more code than the change needs, and two writers doing it
> at the same time can drop each other's keys.
> Many components store independent keys in one map (one per table, partition,
> or cursor) and often change only a few of them. A method that accepts just
> those keys is simpler to use. It also lets a state store persist only what
> changed, which can be cheaper when the map is large.
> h2. Proposed Solution
> Add one method to both {{ProcessSession}} and {{StateManager}}:
> {code:java}
> void patchState(Map<String, String> updatedState, Scope scope) throws
> IOException;
> {code}
> The map is a patch, not a full replacement:
> * Present keys with a non-null value are created or overwritten.
> * Present keys with a {{null}} value are removed. Removing a key that is not
> there is a no-op. An empty string is stored; it does not remove the key.
> * Keys that are not in the map are left as they are.
> If no state is stored yet ({{StateMap}} version {{-1}}), the call matches
> {{setState}} after {{null}} values are dropped.
> A {{null}} map is not allowed. An empty map is a no-op: no write and no
> version change.
> {{ProcessSession.patchState}} follows the same commit rules as {{setState}}:
> the patch is cached on the session, {{getState}} in that session sees it, and
> it is published on commit only if it is still the latest remote state.
> Rollback discards it. A second {{patchState}} in the same session applies on
> top of the first cached result.
> A default implementation is provided on both interfaces. Existing
> {{StateManager}} and {{ProcessSession}} implementations stay
> source-compatible. The default gets the current state, copies it into a new
> {{HashMap}}, applies the patch, and calls {{replace}} until that succeeds:
> {code}
> StateMap current;
> do {
> current = getState(scope);
> Map<String, String> updated = new HashMap<>(current.toMap());
> for (each key/value in updatedState) {
> if (value is null) {
> updated.remove(key);
> } else {
> updated.put(key, value);
> }
> }
> } while (!replace(current, updated, scope));
> {code}
> On {{ProcessSession}}, {{replace}} is {{replaceState}}. {{getState}} and
> {{replaceState}} already see session-cached state, so the same loop honors
> commit and rollback.
> h2. NiFi API Changes
> New default methods on {{org.apache.nifi.processor.ProcessSession}} and
> {{org.apache.nifi.components.state.StateManager}}, using the loop above.
> {{StateTooLargeException}} still applies to the map after the patch is
> applied.
> Backward compatible: additive default methods only.
> h2. Voting Period
> This NIP is proposed with a 24-hour lazy consensus voting period.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)