Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIFI-4987: Added TTL to RedisDistributedMapCacheClientService #2726

Closed
wants to merge 3 commits into from

Conversation

zenfenan
Copy link
Contributor

Note to reviewers

I have replaced the original getAndPutIfAbsent with a new approach. setNX doesn't take TTL so I modified the function to do this: check exists(key) is false then set(key, value). Do let me know, if there are any concerns.


Thank you for submitting a contribution to Apache NiFi.

In order to streamline the review of the contribution we ask you
to ensure the following steps have been taken:

For all changes:

  • Is there a JIRA ticket associated with this PR? Is it referenced
    in the commit message?

  • Does your PR title start with NIFI-XXXX where XXXX is the JIRA number you are trying to resolve? Pay particular attention to the hyphen "-" character.

  • Has your PR been rebased against the latest commit within the target branch (typically master)?

  • Is your initial contribution a single, squashed commit?

For code changes:

  • Have you ensured that the full suite of tests is executed via mvn -Pcontrib-check clean install at the root nifi folder?
  • Have you written or updated unit tests to verify your changes?
  • If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0?
  • If applicable, have you updated the LICENSE file, including the main LICENSE file under nifi-assembly?
  • If applicable, have you updated the NOTICE file, including the main NOTICE file found under nifi-assembly?
  • If adding new Properties, have you added .displayName in addition to .name (programmatic access) for each of the new properties?

For documentation related changes:

  • Have you ensured that format looks appropriate for the output in which it is rendered?

Note:

Please ensure that once the PR is submitted, you check travis-ci for build issues and submit an update to your PR as soon as possible.

@bbende
Copy link
Contributor

bbende commented May 21, 2018

@zenfenan the getAndPutIfAbsent method needs to be an atomic operation which is the reason we are using the watch and multi step operation so we can't remove that.

As an example, the HBase implementation is implemented with the same approach you have in this PR and creates the problem described here:

https://stackoverflow.com/questions/49905725/getting-duplicates-with-nifi-hbase-1-1-2-clientmapcacheservice

@bbende
Copy link
Contributor

bbende commented May 21, 2018

Was looking into this a little more and I believe we can keep all of the origin getAndPutIfAbsent, and just add the following right after the set:

redisConnection.expire(kv.getKey(), 1000);

Replacing 1000 with whatever time variable.

Copy link
Contributor Author

@zenfenan zenfenan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bbende Thanks for pointing it out.

One question: When the Cache update strategy is set to Keep original and the TTL was initially set to 0 secs (meaning TTL set to -1 or forever) and lets say key1 with a value was set in the cache. Later the TTL was modified to something like 1 hour and key1 comes again. What is expected to be the outcome? I think the TTL has to be updated from -1 to the new value and the flowfile should be sent to success relationship. Correct?

Update
Just realized, if we go by that way, it would introduce unnecessary complexity. So I think it's better to go with set in stone approach when Keep original strategy is used i.e. if 0 secs is set, it will live forever any further flowfile carrying that key will be sent to failure regardless of the TTL modified later, if it is set to some time like 1 hour, till 1 hour all flowfiles carrying the existing key will be sent to failure and after 1 hour, that key will expire.

@bbende
Copy link
Contributor

bbende commented May 22, 2018

The TTL concept is really specific to the implementation (Redis in this case). From the perspective of the DMC interface, the API for getAndPutIfAbsent is saying it will only do a put if the key wasn't there. So I wouldn't really expect anything about the key to change unless the put was performed, so I lean towards not updating the TTL when the key was already there because to me the TTL is part of the put which didn't happen.

The current logic in PutDistributedMapCache looks like if "keep original" is chosen and there is an existing value for the key, then it routes to failure, so I don't think that should be changed unless someone believes that is a bug and wasn't the intended behavior.

I was also looking at the commands again, and I noticed this as another way to do a put-if-absent with TTL:

redisConnection.set(kv.getKey(), kv.getValue(), Expiration.milliseconds(-1), RedisStringCommands.SetOption.ifAbsent());

The only issue is that "setnx" returns a boolean that tells us if the set was done which we check after the transaction is done, and "set" is void, so I'm not sure if it is better to just use setnx + expire. You'll have to play with it to see how it works out.

@zenfenan
Copy link
Contributor Author

@bbende I have made the changes.

@bbende
Copy link
Contributor

bbende commented May 22, 2018

@zenfenan thanks for the updates, I think there is also a small changed needed in putIfAbsent correct? If setnx returns true then set expire?

Copy link
Contributor Author

@zenfenan zenfenan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bbende Yeah. My bad. I have now added TTL to putIfAbsent() as well.

@asfgit asfgit closed this in 06d45c3 May 23, 2018
@bbende
Copy link
Contributor

bbende commented May 23, 2018

Looks good, merged, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants