surge
November 8, 2017, 6:31pm
1
Can you please verify the commit that fixed the Memcache expiration?
https://issues.couchbase.com/browse/NCBC-1538
When passing in a TimeSpan here
/// </summary>
/// <typeparam name="T">The Type of the value to be inserted.</typeparam>
/// <param name="key">The unique key for indexing.</param>
/// <param name="value">The value for the key.</param>
/// <param name="expiration">The time-to-live (ttl) for the key.</param>
/// <returns>
/// An object implementing the <see cref="IOperationResult{T}" />interface.
/// </returns>
public IOperationResult<T> Upsert<T>(string key, T value, TimeSpan expiration)
{
return Upsert(key, value, expiration.ToTtl(), GlobalTimeout);
}
/// <summary>
/// Inserts or replaces an existing document into Couchbase Server.
/// </summary>
/// <typeparam name="T">The Type of the value to be inserted.</typeparam>
/// <param name="key">The unique key for indexing.</param>
/// <param name="value">The value for the key.</param>
/// <param name="expiration">The time-to-live (ttl) for the key.</param>
/// <param name="timeout">The maximum time allowed for an operation to live before timing out.</param>
It calls the ToTtl(this TimeSpan timespan) extension method. This extension method returns the (uint)Timespan.TotalSeconds.
/// Converts a <see cref="TimeSpan" /> into an uint correctly representing a Time-To-Live,
/// that is expressed in seconds.
/// Durations strictly bigger than 30 days are converted to a unix-syle timestamp (seconds since the Epoch),
/// as described in the couchbase TTL documentation.
/// </summary>
/// <returns>The TTL, expressed as a suitable uint.</returns>
public static uint ToTtl(this TimeSpan duration)
{
if (duration <= TimeSpan.FromDays(30))
{
return (uint)duration.TotalSeconds;
}
else
{
var dateExpiry = DateTime.UtcNow + duration;
var unixTimeStamp = (uint) (dateExpiry.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
return unixTimeStamp;
}
}
/// <summary>
This is then passed to the Upsert which accepts the uint param, and this value calls the extension ToTtl(this uint duration).
/// An object implementing the <see cref="T:Couchbase.IOperationResult`1" />interface.
/// </returns>
/// <remarks>
/// Expirations over 30 * 24 * 60 * 60 (the amount of seconds in 30 days) are interpreted as a UNIX timestamp of the date at which the document expires.
/// see <see href="http://docs.couchbase.com/couchbase-devguide-2.5/#about-document-expiration">documentation section about expiration</see>.
/// </remarks>
public IOperationResult<T> Upsert<T>(string key, T value, uint expiration, TimeSpan timeout)
{
var operation = new Set<T>(key, value, null, _transcoder, timeout.GetSeconds())
{
Expires = expiration.ToTtl()
};
return _requestExecuter.SendWithRetry(operation);
}
/// <summary>
/// Inserts or replaces an existing document into Couchbase Server as an asynchronous operation.
/// </summary>
/// <typeparam name="T">The Type of the value to be inserted.</typeparam>
/// <param name="key">The unique key for indexing.</param>
/// <param name="value">The value for the key.</param>
}
}
/// <summary>
/// Converts a duration expressed as milliseconds to a unix-based TTL.
/// </summary>
/// <param name="duration">Milliseconds to use as TTL.</param>
/// <returns>The TTL, expressed as a unix-based TTL in milliseconds.</returns>
public static uint ToTtl(this uint duration)
{
return ToTtl(TimeSpan.FromMilliseconds(duration));
}
/// <summary>
/// Retrieves the number of seconds expressed in a <see cref="TimeSpan"/> as an <see cref="uint"/>.
/// </summary>
/// <param name="timeSpan">The timespan.</param>
/// <returns>An <see cref="uint"/> that is the total number of seconds in the <see cref="TimeSpan"/>.</returns>
public static uint GetSeconds(this TimeSpan timeSpan)
{
return (uint) timeSpan.TotalSeconds;
The issue is that the extension method is expecting an uint value in milliseconds. With the value of seconds passed in, the expiration is off by a factor of 1000.
I have used the uint upsert overload for the memcache bucket for the time being.
Thanks
If you look in the lower right of the web view of JIRA, you’ll see a link to the commit in code review that should have addressed this issue.
surge
November 8, 2017, 8:10pm
3
I am not sure what I should be looking for in this review.
http://review.couchbase.org/#/c/83941/1/Src/Couchbase.IntegrationTests/MemcachedBucketTests.cs
After upserting with a 1 second expiration a Get is immediately performed. The document is not given a chance to expire so the first Get is successful. A thread sleep for 1200 milliseconds was performed. The document was retrieved a second time via a Get and the response asserted as equal to KeyNotFound.
But it doesn’t cover the gap in tests. The object is expiring too quickly.
I think if you set the sleep to 500 milliseconds the unit test would still be successful.
@surge @ingenthr -
Indeed it is a regression. The cast from double to uint ends up setting the expiration to 0 which is infinite. I’ll push a patch in a few minutes.
Thanks,
Jeff
surge
November 8, 2017, 8:29pm
5
Cool, thanks for looking into it.
1 Like
surge
November 8, 2017, 9:37pm
6
@jmorris Is there an eta when this will be posted as a Nuget package?
It’s scheduled for v2.5.3 on or around Dec 5th, 2017. Note, once the patch has made it through code review on Gerrit and has been merged, you can always build from source on Github if you need immediately.
-Jeff
1 Like
@surge - we also generate pre-release nuget packages for each change that has been accepted. The pre-release nuget feed is here .
2 Likes