Oh yeah, I do love this behavior of ProcessSession.  And thanks for the
tip, it's easy to forget that there are efficiencies to be gained by using
different parts of an API.

-- Mke


On Wed, May 8, 2024 at 11:04 AM Mark Payne <marka...@hotmail.com> wrote:

> Yeah, that was something that kinda flew under the radar. Definitely
> improved the API.
>
> Not really related, but on the note of things you may not realize, with
> that code snippet :)
> If you have access to update the processor mentioned here, you should
> avoid using session.putAttribute many times.
> Under the hood, in order to maintain object immutability it has to create
> a new FlowFile object (and a new HashMap of all attributes!)
> for every call to putAttribute. So if there are 100 attributes that match
> that’s potentially a huge amount of garbage getting created. Instead,
> you could just use:
>
> ```
> final Map<String, String> attributes = new HashMap<>();
> flowFile.getAttributes().forEach( (key, value) -> {
>   if (key.startsWith(“foo”)) {
>     attributes.put(“original-“ + key, value);
>   }
> }
>
> flowFIle = session.putAllAttributes(flowFile, attributes);
> ```
>
> Thanks
> -Mark
>
>
>
> > On May 8, 2024, at 10:30 AM, Michael Moser <moser...@gmail.com> wrote:
> >
> > Wow, thanks for this information!  Just last week I saw code that
> modified
> > attributes in a stream:
> >
> > flowFile.getAttributes().entrySet().stream().filter(e ->
> > e.getKey().startsWith("foo"))
> >    .forEach(e -> session.putAttribute(flowFile, "original-" + e.getKey,
> > e.getValue()));
> >
> > and I wondered how that could possibly work since the return value of
> > session.putAttribute is ignored!  Now I know.
> >
> > -- Mike
> >
> > On Tue, May 7, 2024 at 3:02 PM Russell Bateman <r...@windofkeltia.com>
> > wrote:
> >
> >> Yes, what you described is what was happening, Mark. I didn't display
> >> all of the code to the session methods, and I did re-read the in-coming
> >> flowfile for different purposes than I had already read and written it.
> >> So, I wasn't helpful enough. In the end, however, I had forgotten,
> >> immediately after the call to session.putAllAttributes(), to update the
> >> resulting flowfile for passing to session.transfer(). That solved it for
> >> 1.1.2 which wasn't necessary for 1.13.2 or later versions. Being
> >> helpful, the newer versions made me a spoiled, entitled child and I will
> >> repent immediately.
> >>
> >> Thanks, guys! DevOps are happy they don't have to upgrade the customers
> >> to NiFi 1.13.2. (In a way, I'm unhappy about that, but...).
> >>
> >> Best regards,
> >>
> >> Russ
> >>
> >> On 5/7/24 11:53, Mark Payne wrote:
> >>> The call to session.putAttribute would throw an Exception because you
> >>> provided an outdated version of the flowFile (did not capturing the
> >>> result of calling session.write)
> >>>
> >>> Now, as NiFi matured, we found that:
> >>> (a) for more complex processors that aren’t just a series of sequential
> >>> steps it becomes difficult to manage all of that bookkeeping.
> >>> (b) it was not intuitive to require this
> >>> (c) the ProcessSession already had more or less what it needed in order
> >>> to determine what the most up-to-date version of the FlowFile was.
> >>>
> >>> So we updated the ProcessSession to automatically grab the latest
> >>> version of the FlowFile for these methods. But since you’re trying to
> >>> run an old version, you’ll need to make sure that you capture all of
> >>> those outputs and always keep track of the most recent version of a
> >>> FlowFile.
> >>
>
>

Reply via email to