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

Fail-fast if max-idle-seconds is set below 2 seconds #14727

Merged
merged 8 commits into from Mar 27, 2019
Merged

Fail-fast if max-idle-seconds is set below 2 seconds #14727

merged 8 commits into from Mar 27, 2019

Conversation

galibey
Copy link
Contributor

@galibey galibey commented Mar 21, 2019

Fixes: #14697

Alexander Galibey added 4 commits March 21, 2019 13:03
There was a incorrect check here that waited for eviction by MaxIdle
parameter and touched the record in the same time
Copy link
Contributor

@mustafaiman mustafaiman left a comment

Choose a reason for hiding this comment

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

minor comment about doc. Otherwise looks good to me 👍

@@ -202,6 +204,9 @@
protected static final String NULL_AGGREGATOR_IS_NOT_ALLOWED = "Aggregator should not be null!";
protected static final String NULL_PROJECTION_IS_NOT_ALLOWED = "Projection should not be null!";

protected static final String MAX_IDLE_TIME_IS_TOO_SMALL = "Parameter maxIdle in seconds representation must be greater or"
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not arguing my english is perfect here but I think the message must be "greater than or equal to"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right. Fixed. Thanks.

@@ -139,6 +139,8 @@
protected static final String NULL_LISTENER_IS_NOT_ALLOWED = "Null listener is not allowed!";
protected static final String NULL_AGGREGATOR_IS_NOT_ALLOWED = "Aggregator should not be null!";
protected static final String NULL_PROJECTION_IS_NOT_ALLOWED = "Projection should not be null!";
protected static final String MAX_IDLE_TIME_IS_TOO_SMALL = "Parameter maxIdle in seconds representation must be greater or "
Copy link
Contributor

Choose a reason for hiding this comment

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

the same issue with "greater than or equal to"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@hazelcast hazelcast deleted a comment from galibey Mar 26, 2019
@mmedenjak
Copy link
Contributor

One concern - what if the user is already using IMap with expiration and is setting the TTL to 1 second? We will start throwing IllegalArgumentException with this PR. @tkountis WDYT? Is this a plausible scenario? And better question - if the user is using a TTL of 1 second, is it a valid setting at all?

@mustafaiman
Copy link
Contributor

@mmedenjak
I wrote this test into BasicMapTests

    @Test
    public void testOneSecondTtl() {
        final IMap<String, String> map = getInstance().getMap(randomString());
        long start, end;
        start = System.currentTimeMillis();
        for (int i = 0; i < 300000; i++) {
            map.put("key", "value", 2000, MILLISECONDS);
            end = System.currentTimeMillis();
            assertEquals("Iteration " + i + ". Ms until now: " + (end - start), "value", map.get("key"));
        }
    }

It takes about 20 seconds on my machine and test passes fine. When I change TTL value to 1999 milliseconds, the test fails within the first second. I guess having a 1 second TTL does not make sense either. Because we round down creation time. If the entry is created at x4998ms time offset, we record it as x4000 by rounding down. When we check elapsedMillis during map.get, most of the time elapsed time is larger than 1000ms.

@galibey
Copy link
Contributor Author

galibey commented Mar 27, 2019

@mmedenjak
Here we added a validation only for MaxIdle. For TTL it's still possible to define 1s.
For TTL even with 1s it will work more or less as expected, but with MaxIdle=1s it will never work, the entry will always be evicted regardless of user's touches.

Copy link
Contributor

@mmedenjak mmedenjak left a comment

Choose a reason for hiding this comment

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

Ok, ok, I'm convinced :) Maybe we can add this as a note in the changelog cc @Serdaro

@ahmetmircik
Copy link
Member

4 concerns with this change:

  • fail-fast should only work for cluster-versions >= 3.12, now this check is not rolling upgrade friendly.
  • tend to see 1sec as a legitimate value to set, even this is a rare case. Mostly seems, we are leaking an implementation detail to public api.
  • since this is not a backward compatible change lots of existing code can fail in a minor release.
  • in the future, if we unify imap and icache code, this change can become a headache point since icache supports 1secs but imap does not.

@mmedenjak
Copy link
Contributor

@ahmetmircik It's a tricky question. I guess this was introduced because we shaved off some data to make HD records more compact, which is great. Now, we have this quirky behaviour.
Reverting the HD record format isn't a good option because everyone loses because of a few which actually care about higher precision.
Having a test like the one Mustafa posted fail is very counterintuitive. The entry is mutated almost constantly but it's expired nevertheless.
But I must admit this feels a bit like we're leaking implementation details and it may be disruptive to some users. It's a detail that we currently don't support such precision and it may be fixed in some other way. I'm going to go with some middle ground:

  • the exceptions should be removed
  • can you look into whether there's a way that we can signal that the entry was, in fact, mutated during the first second and avoid the issue?
  • if not, can you leave some documentation in javadoc and reference manual that setting max-idle-seconds to 1 second can lead to unexpected behaviour.

@galibey
Copy link
Contributor Author

galibey commented Mar 28, 2019

@mmedenjak

  • can you look into whether there's a way that we can signal that the entry was, in fact, mutated during the first second and avoid the issue?

Without increasing precision it won't help much, e.g.,
first access occurred at 0.001s, we count as 1s, and then, second access was at 1.999s, we count as 2s. So, the entry will still live although almost 2s passed.

I agree that we should remove a throwing of the exception and add to javadoc that our current precision is 1s and all below 1s can lead to unexpected behaviour.

galibey added a commit that referenced this pull request Mar 28, 2019
Revert "Fail-fast if max-idle-seconds is set below 2 seconds (#14727)"

This reverts commit 336bd4d and add to javadoc the MaxIdle time precision limitation
@galibey galibey deleted the fix/3.13/14697-max-idle-seconds branch May 22, 2019 10:42
@mmedenjak mmedenjak added the Source: Internal PR or issue was opened by an employee label Apr 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fail-fast if max-idle-seconds is set below 2 seconds
5 participants