On the Couchbase server, the expiration date suddenly increases

Hi all.

I want to start with that I’ve checked system time on application and couchbase servers. Everything is fine.

Couchbase adds the same time constant for each expiry. This constant is specific for each Couchbase server. For one server it is ~2 minutes 20 sec. For another, it is ~6 minutes 18 sec. If I decide to store something for 1 minute, then it will be really stored for 3 or 7 minutes. I don’t have any idea why does it happen. Can you help me?

I’ve used this test to catch this issue.

public static IEnumerable<object[]> Expiries = new List<object[]>
{
    new object[] { TimeSpan.FromSeconds(10) },
    new object[] { TimeSpan.FromSeconds(30) },
    new object[] { TimeSpan.FromMinutes(1) },
    new object[] { TimeSpan.FromMinutes(10) },
    new object[] { TimeSpan.FromMinutes(30) },
    new object[] { TimeSpan.FromHours(1) },
    new object[] { TimeSpan.FromHours(10) },
    new object[] { TimeSpan.FromDays(1) },
    new object[] { TimeSpan.FromDays(10) }
};

[Theory]
[MemberData(nameof(Expiries))]
[Trait(TraitConstants.TraitCategory, TraitConstants.IntegrationTestCategory)]
public async Task InsertGet_EternalCouchbaseConstants_ConstantsAreValid(TimeSpan expiry)
{
    await Initialize();

    var stopWatch = Stopwatch.StartNew();

    await _collection.InsertAsync(CouchbaseId, "someString", options => options
        .Expiry(expiry));

    var getResult = await _collection.GetAsync(CouchbaseId, options => options
        .Expiry());

    stopWatch.Stop();

    var expectedExpiryTime = SystemClock.Instance.GetCurrentInstant().ToDateTimeUtc().Add(expiry);
    var minExpectedExpiryTime = expectedExpiryTime.Subtract(stopWatch.Elapsed);
    var maxExpectedExpiryTime = expectedExpiryTime.Add(stopWatch.Elapsed);

    Assert.NotNull(getResult.ExpiryTime);
    var expiryTimeUtc = getResult.ExpiryTime.Value.ToUniversalTime();

    Assert.True(expiryTimeUtc > minExpectedExpiryTime);
    Assert.True(expiryTimeUtc > maxExpectedExpiryTime); //Should be less
    var difference = expiryTimeUtc - expectedExpiryTime;
    _testOutputHelper.WriteLine($"Inserted expiry: {expiry}.");
    _testOutputHelper.WriteLine($"Expected expiry time: {expectedExpiryTime}.");
    _testOutputHelper.WriteLine($"Getted expiry time: {expiryTimeUtc}.");
    _testOutputHelper.WriteLine($"Difference: {difference}.");
}

@Ramirag

I’ve done some testing, and so far I can’t reproduce this problem locally. I know you say you’ve checked system clocks, but I really feel like that is the most likely culprit.

In case it helps in your research, I can describe how the data flows. When you call InsertAsync with the document, that is sent to the Couchbase Server as a number of seconds until expiration (not as a specific date/time) so long as it’s less than 30 days. Once over 30 days, it sends to the server as a date/time (more precisely, as the number of seconds since the Unix epoch).

When getting the expiration back from the server, it is returned as the number of seconds since the Unix epoch. This is converted into a date/time and into the client’s system time zone before returning to you.

Based on this, the most likely location for a problem would be on the Couchbase server, where it’s converting the TTL in seconds into a specific expiration in the Unix epoch.

@btburnett3

Thx. I will try to find a cause. Probably we missed something.