Skip to content

Commit

Permalink
[CBSE-5347] Fixes long document expiration
Browse files Browse the repository at this point in the history
Closes #1029
  • Loading branch information
borrrden committed Jul 26, 2018
1 parent ec318a6 commit 1972a49
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/Couchbase.Lite.Shared/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2175,7 +2175,11 @@ internal void SchedulePurgeExpired(TimeSpan delay)
if (nextExpiration.HasValue) {
var delta = (nextExpiration.Value - DateTime.UtcNow).Add(TimeSpan.FromSeconds(1));
var expirationTimeSpan = delta > delay ? delta : delay;
if (expirationTimeSpan.TotalSeconds <= Double.Epsilon) {
if (expirationTimeSpan.TotalMilliseconds >= UInt32.MaxValue) {
_expirePurgeTimer.Change(TimeSpan.FromMilliseconds(UInt32.MaxValue - 1), TimeSpan.FromMilliseconds(-1));
Log.To.Database.I(Tag, "{0:F3} seconds is too far in the future to schedule a document expiration," +
" will run again at the maximum value of {0:F3} seconds", expirationTimeSpan.TotalSeconds, (UInt32.MaxValue - 1) / 1000);
} else if (expirationTimeSpan.TotalSeconds <= Double.Epsilon) {
_expirePurgeTimer.Change(Timeout.Infinite, Timeout.Infinite);
PurgeExpired(null);
} else {
Expand Down
27 changes: 27 additions & 0 deletions src/Couchbase.Lite.Tests.Shared/DocumentTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,33 @@ public void TestExpireDocument()
Assert.IsTrue(Math.Abs((next.Value - future).TotalSeconds) < 1.0);
}

[Category("issue/1029")]
[Test]
public void TestLongExpiration()
{
// Before the fix this would crash because timers cannot be scheduled so far
// in the future. Now the timer will fire early, do nothing and reschedule
// itself
var now = DateTime.UtcNow;
Trace.WriteLine($"Now is {now}");
var doc = CreateDocumentWithProperties(database, new Dictionary<string, object> { { "foo", 17 } });
Assert.IsNull(doc.GetExpirationDate());
database.RunInTransaction(() =>
{
doc.ExpireAfter(TimeSpan.FromDays(60));
return true;
});

var exp = doc.GetExpirationDate();
Trace.WriteLine($"Doc expiration is {exp}");
Assert.IsNotNull(exp);
Assert.IsTrue(Math.Abs((exp.Value - now).TotalDays - 60.0) < 1.0);

var next = database.Storage.NextDocumentExpiry();
Trace.WriteLine($"Next expiry at {next}");
Assert.IsTrue(Math.Abs((next.Value - now).TotalDays - 60.0) < 1.0);
}

[Test] // #447
public void TestDocumentArraysMaintainOrder()
{
Expand Down

0 comments on commit 1972a49

Please sign in to comment.