Latest fixes

This commit is contained in:
Derek
2016-08-19 10:27:51 +02:00
parent 6f501e8303
commit ccf356279f
23 changed files with 125 additions and 247 deletions
@@ -8,6 +8,7 @@ using Hangfire.Raven.Entities;
using Hangfire.Raven.Storage;
using System;
using Raven.Json.Linq;
using HangFire.Raven.Storage;
namespace Hangfire.Raven.DistributedLocks
{
@@ -57,8 +58,7 @@ namespace Hangfire.Raven.DistributedLocks
};
session.Store(_distributedLock);
session.Advanced.GetMetadataFor(_distributedLock)["Raven-Expiration-Date"] =
new RavenJValue(DateTime.UtcNow + _timeout);
session.Advanced.AddExpire(_distributedLock, DateTime.UtcNow + _timeout);
try
{
@@ -97,13 +97,13 @@ namespace Hangfire.Raven.DistributedLocks
}
_distributedLock = null;
}
// Stop timer
if (_heartbeatTimer != null)
{
_heartbeatTimer.Dispose();
_heartbeatTimer = null;
}
// Stop timer
if (_heartbeatTimer != null)
{
_heartbeatTimer.Dispose();
_heartbeatTimer = null;
}
}
}
@@ -121,10 +121,8 @@ namespace Hangfire.Raven.DistributedLocks
using (var session = _storage.Repository.OpenSession())
{
var distributedLock = session.Load<DistributedLock>(_distributedLock.Id);
session.Advanced.GetMetadataFor(distributedLock)["Raven-Expiration-Date"] =
new RavenJValue(DateTime.UtcNow + _timeout);
session.Advanced.AddExpire(distributedLock, DateTime.UtcNow + _timeout);
session.SaveChanges();
}
}
+1 -4
View File
@@ -1,5 +1,4 @@
using Hangfire.Raven.Entities.Identity;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -12,7 +11,5 @@ namespace Hangfire.Raven.Entities
public string Id { get; set; }
public int Value { get; set; }
public DateTime? ExpireAt { get; set; }
}
}
@@ -1,5 +1,4 @@
using Hangfire.Raven.Entities.Identity;
using System;
using System;
namespace Hangfire.Raven.Entities
{
@@ -1,7 +0,0 @@
namespace Hangfire.Raven.Entities.Identity
{
public class BaseEntity
{
public string Id { get; set; }
}
}
+1 -2
View File
@@ -1,5 +1,4 @@
using Hangfire.Raven.Entities.Identity;
using System;
using System;
namespace Hangfire.Raven.Entities
{
+1 -17
View File
@@ -1,20 +1,4 @@
// This file is part of Hangfire.
// Copyright © 2013-2014 Sergey Odinokov.
//
// Hangfire is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3
// of the License, or any later version.
//
// Hangfire is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with Hangfire. If not, see <http://www.gnu.org/licenses/>.
using Hangfire.Annotations;
using Hangfire.Annotations;
using Hangfire.Storage;
using HangFire.Raven;
using Hangfire.Raven.Storage;
+1 -19
View File
@@ -1,21 +1,4 @@
// This file is part of Hangfire.
// Copyright © 2013-2014 Sergey Odinokov.
//
// Hangfire is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3
// of the License, or any later version.
//
// Hangfire is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with Hangfire. If not, see <http://www.gnu.org/licenses/>.
using Hangfire.Raven.Entities.Identity;
using System;
using System;
using System.Collections.Generic;
namespace Hangfire.Raven.Entities
@@ -29,6 +12,5 @@ namespace Hangfire.Raven.Entities
public string Id { get; set; }
public Dictionary<string, string> Fields { get; set; }
public DateTime? ExpireAt { get; set; }
}
}
-18
View File
@@ -1,21 +1,4 @@
// This file is part of Hangfire.
// Copyright © 2013-2014 Sergey Odinokov.
//
// Hangfire is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3
// of the License, or any later version.
//
// Hangfire is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with Hangfire. If not, see <http://www.gnu.org/licenses/>.
using Hangfire.Common;
using Hangfire.Raven.Entities.Identity;
using Hangfire.Storage;
using System;
using System.Collections.Generic;
@@ -35,7 +18,6 @@ namespace Hangfire.Raven.Entities
public InvocationData InvocationData { get; set; }
public IDictionary<string, string> Parameters { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? ExpireAt { get; set; }
public StateData StateData { get; set; }
public List<StateHistoryDto> History { get; set; }
+4 -5
View File
@@ -1,14 +1,13 @@
using Hangfire.Raven.Entities.Identity;
using System;
using System;
namespace Hangfire.Raven.Entities
{
public class RavenList : BaseEntity
public class RavenList
{
public string Id { get; set; }
public string Key { get; set; }
public string Value { get; set; }
public DateTime ExpireAt { get; set; }
}
}
+1 -18
View File
@@ -1,21 +1,4 @@
// This file is part of Hangfire.
// Copyright © 2013-2014 Sergey Odinokov.
//
// Hangfire is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3
// of the License, or any later version.
//
// Hangfire is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with Hangfire. If not, see <http://www.gnu.org/licenses/>.
using Hangfire.Raven.Entities.Identity;
using System;
using System;
using System.Collections.Generic;
namespace Hangfire.Raven.Entities
+1 -3
View File
@@ -1,5 +1,4 @@
using Hangfire.Raven.Entities.Identity;
using System;
using System;
using System.Collections.Generic;
namespace Hangfire.Raven.Entities
@@ -13,6 +12,5 @@ namespace Hangfire.Raven.Entities
public string Id { get; set; }
public Dictionary<string, double> Scores { get; set; }
public DateTime? ExpireAt { get; set; }
}
}
-80
View File
@@ -1,80 +0,0 @@
// This file is part of Hangfire.
// Copyright © 2013-2014 Sergey Odinokov.
//
// Hangfire is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3
// of the License, or any later version.
//
// Hangfire is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with Hangfire. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Threading;
using Hangfire.Logging;
using Hangfire.Server;
using System.Linq;
using HangFire.Raven;
using Hangfire.Raven.Entities;
using Hangfire.Annotations;
using Hangfire.Raven.Storage;
namespace Hangfire.Raven
{
public class ExpirationManager
: IBackgroundProcess, IServerComponent
{
private static readonly ILog Logger = LogProvider.GetCurrentClassLogger();
private readonly TimeSpan _checkInterval;
private RavenStorage _storage;
public ExpirationManager(RavenStorage storage, TimeSpan checkInterval)
{
_checkInterval = checkInterval;
_storage = storage;
}
public void Execute(CancellationToken cancellationToken)
{
using (var repository = _storage.Repository.OpenSession())
{
var now = DateTime.UtcNow;
var counters = repository.Query<Counter>().Where(t => t.ExpireAt <= now).ToList();
counters.ForEach(t => repository.Delete(t));
var jobs = repository.Query<RavenJob>().Where(t => t.ExpireAt <= now).ToList();
jobs.ForEach(t => repository.Delete(t));
var hashes = repository.Query<RavenHash>().Where(t => t.ExpireAt <= now).ToList();
hashes.ForEach(t => repository.Delete(t));
var lists = repository.Query<RavenList>().Where(t => t.ExpireAt <= now).ToList();
lists.ForEach(t => repository.Delete(t));
var sets = repository.Query<RavenSet>().Where(t => t.ExpireAt <= now).ToList();
sets.ForEach(t => repository.Delete(t));
repository.SaveChanges();
}
cancellationToken.WaitHandle.WaitOne(_checkInterval);
}
public void Execute([NotNull] BackgroundProcessContext context)
{
this.Execute(context.CancellationToken);
}
public override string ToString()
{
return "Raven Expiration Manager";
}
}
}
-2
View File
@@ -93,10 +93,8 @@
<Compile Include="Entities\EnqueuedAndFetchedCount.cs" />
<Compile Include="Entities\JobQueue.cs" />
<Compile Include="Entities\RavenHash.cs" />
<Compile Include="Entities\Identity\BaseEntity.cs" />
<Compile Include="Entities\RavenList.cs" />
<Compile Include="Entities\RavenSet.cs" />
<Compile Include="ExpirationManager.cs" />
<Compile Include="Entities\RavenJob.cs" />
<Compile Include="Entities\RavenServer.cs" />
<Compile Include="Extensions\DatabaseExtensions.cs" />
@@ -24,8 +24,7 @@ namespace Hangfire.Raven.Indexes
select new Mapping
{
StateName = result.StateData.Name,
CreatedAt = result.CreatedAt,
ExpireAt = result.ExpireAt
CreatedAt = result.CreatedAt
};
this.Analyze("StateName", "WhitespaceAnalyzer");
}
@@ -38,11 +38,12 @@ namespace Hangfire.Raven.JobQueues
using (var repository = _storage.Repository.OpenSession())
{
var jobs = repository.Query<JobQueue>().Where(t => t.Queue == queue && t.FetchedAt == null)
.Select((data, i) => new { Index = i + 1, Data = data })
.Where(_ => (_.Index >= start) && (_.Index <= end))
.Select(x => x.Data)
.ToList();
var jobs = repository.Query<JobQueue>()
.Where(t => t.Queue == queue && t.FetchedAt == null)
.Select((data, i) => new { Index = i + 1, Data = data })
.Where(_ => (_.Index >= start) && (_.Index <= end))
.Select(x => x.Data)
.ToList();
var results = new List<RavenJob>();
@@ -90,7 +91,6 @@ namespace Hangfire.Raven.JobQueues
using (var repository = _storage.Repository.OpenSession())
{
int enqueuedCount = repository.Query<JobQueue>().Where(t => t.Queue == queue && t.FetchedAt == null).Count();
int fetchedCount = repository.Query<JobQueue>().Where(t => t.Queue == queue && t.FetchedAt != null).Count();
return new EnqueuedAndFetchedCount
@@ -4,7 +4,8 @@ using System.Linq;
namespace Hangfire.Raven.Listeners
{
public class TakeNewestConflictResolutionListener : IDocumentConflictListener
public class TakeNewestConflictResolutionListener
: IDocumentConflictListener
{
public bool TryResolveConflict(string key, JsonDocument[] conflictedDocs, out JsonDocument resolvedDocument)
{
+14 -17
View File
@@ -26,6 +26,7 @@ using HangFire.Raven;
using Hangfire.Raven.Entities;
using Hangfire.Raven.Storage;
using Hangfire.Raven.DistributedLocks;
using HangFire.Raven.Storage;
namespace Hangfire.Raven
{
@@ -93,11 +94,12 @@ namespace Hangfire.Raven
Id = Repository.GetId(typeof(RavenJob), guid),
InvocationData = invocationData,
CreatedAt = createdAt,
ExpireAt = createdAt.Add(expireIn),
Parameters = parameters
};
repository.Store(ravenJob);
repository.Advanced.AddExpire(ravenJob, createdAt + expireIn);
repository.SaveChanges();
return guid;
@@ -133,7 +135,7 @@ namespace Hangfire.Raven
return new JobData
{
Job = job,
State = jobData.StateData.Name,
State = jobData.StateData?.Name,
CreatedAt = jobData.CreatedAt,
LoadException = loadException
};
@@ -406,10 +408,12 @@ namespace Hangfire.Raven
var id = Repository.GetId(typeof(RavenSet), key);
var set = repository.Load<RavenSet>(id);
if(set.ExpireAt == null)
var expireAt = repository.Advanced.GetExpire(set);
if(expireAt == null)
return TimeSpan.FromSeconds(-1);
return set.ExpireAt.Value - DateTime.UtcNow;
return expireAt.Value - DateTime.UtcNow;
}
}
@@ -447,12 +451,13 @@ namespace Hangfire.Raven
using (var repository = _storage.Repository.OpenSession())
{
var ravenHash = repository.Load<RavenHash>(Repository.GetId(typeof(RavenHash), key));
if (!ravenHash.ExpireAt.HasValue) {
var expireAt = repository.Advanced.GetExpire(ravenHash);
if (!expireAt.HasValue) {
return TimeSpan.FromSeconds(-1);
}
return ravenHash.ExpireAt.Value - DateTime.UtcNow;
return expireAt.Value - DateTime.UtcNow;
}
}
@@ -493,17 +498,9 @@ namespace Hangfire.Raven
using (var repository = _storage.Repository.OpenSession())
{
var results = repository.Query<RavenList>()
.Where(t => t.Key == key)
.ToList();
// TODO: Implement!
DateTime? ttl = results.Any() ? results.Min(t => t.ExpireAt) : (DateTime?)null;
if (!ttl.HasValue) {
return TimeSpan.FromSeconds(-1);
}
return ttl.Value - DateTime.UtcNow;
return TimeSpan.FromSeconds(-1);
}
}
+44 -10
View File
@@ -11,6 +11,7 @@ using Hangfire.Raven.Storage;
using Hangfire.Storage.Monitoring;
using Raven.Client;
using Raven.Abstractions.Data;
using HangFire.Raven.Storage;
namespace Hangfire.Raven
{
@@ -56,7 +57,7 @@ namespace Hangfire.Raven
var id = Repository.GetId(typeof(RavenJob), jobId);
var result = _session.Load<RavenJob>(id);
result.ExpireAt = DateTime.UtcNow.Add(expireIn);
_session.Advanced.AddExpire(result, DateTime.UtcNow + expireIn);
}
public override void PersistJob(string jobId)
@@ -64,7 +65,7 @@ namespace Hangfire.Raven
var id = Repository.GetId(typeof(RavenJob), jobId);
var result = _session.Load<RavenJob>(id);
result.ExpireAt = null;
_session.Advanced.RemoveExpire(result);
}
public override void SetJobState(string jobId, IState state)
@@ -72,7 +73,7 @@ namespace Hangfire.Raven
var id = Repository.GetId(typeof(RavenJob), jobId);
var result = _session.Load<RavenJob>(id);
result.History.Add(new StateHistoryDto()
result.History.Insert(0, new StateHistoryDto()
{
StateName = state.Name,
Data = state.SerializeData(),
@@ -114,11 +115,11 @@ namespace Hangfire.Raven
var counter = new Counter()
{
Id = id,
ExpireAt = expireIn != TimeSpan.MinValue ?
DateTime.UtcNow.Add(expireIn) : (DateTime?)null,
Value = 1
};
_session.Store(counter);
if (expireIn != TimeSpan.MinValue)
_session.Advanced.AddExpire(counter, DateTime.UtcNow + expireIn);
}
else
{
@@ -144,11 +145,11 @@ namespace Hangfire.Raven
var counter = new Counter()
{
Id = id,
ExpireAt = expireIn != TimeSpan.MinValue ?
DateTime.UtcNow.Add(expireIn) : (DateTime?)null,
Value = -1
};
_session.Store(counter);
if (expireIn != TimeSpan.MinValue)
_session.Advanced.AddExpire(counter, DateTime.UtcNow + expireIn);
}
else
{
@@ -199,6 +200,27 @@ namespace Hangfire.Raven
_session.Delete(id);
}
public override void ExpireSet([NotNull] string key, TimeSpan expireIn)
{
key.ThrowIfNull("key");
var id = Repository.GetId(typeof(RavenSet), key);
var set = _session.Load<RavenSet>(id);
_session.Advanced.AddExpire(set, DateTime.UtcNow + expireIn);
}
public override void PersistSet([NotNull] string key)
{
key.ThrowIfNull("key");
var id = Repository.GetId(typeof(RavenSet), key);
var set = _session.Load<RavenSet>(id);
_session.Advanced.RemoveExpire(set);
}
public override void InsertToList(string key, string value)
{
var list = _session.Query<RavenList>().FirstOrDefault(t => t.Key == key && t.Value == value);
@@ -243,6 +265,8 @@ namespace Hangfire.Raven
}
}
public override void SetRangeInHash(string key, IEnumerable<KeyValuePair<string, string>> keyValuePairs)
{
key.ThrowIfNull("key");
@@ -278,10 +302,20 @@ namespace Hangfire.Raven
{
key.ThrowIfNull("key");
var id = Repository.GetId(typeof(RavenSet), key);
var set = _session.Load<RavenSet>(id);
var id = Repository.GetId(typeof(RavenHash), key);
var set = _session.Load<RavenHash>(id);
set.ExpireAt = DateTime.UtcNow.Add(expireIn);
_session.Advanced.AddExpire(set, DateTime.UtcNow + expireIn);
}
public override void PersistHash([NotNull] string key)
{
key.ThrowIfNull("key");
var id = Repository.GetId(typeof(RavenHash), key);
var set = _session.Load<RavenHash>(id);
_session.Advanced.RemoveExpire(set);
}
}
}
-1
View File
@@ -10,7 +10,6 @@ using System.Collections.Concurrent;
using Raven.Client.Linq;
using System.Linq;
using System.Linq.Expressions;
using Hangfire.Raven.Entities.Identity;
using Hangfire.Raven.Extensions;
using Hangfire.Raven.Listeners;
using Hangfire.Raven.Storage;
@@ -56,11 +56,6 @@ namespace Hangfire.Raven.Storage
return new RavenConnection(this);
}
public override IEnumerable<IServerComponent> GetComponents()
{
yield return new ExpirationManager(this, _options.JobExpirationCheckInterval);
}
public override void WriteOptionsToLog(ILog logger)
{
logger.Info("Using the following options for Raven job storage:");
@@ -2,11 +2,32 @@
using Hangfire;
using Hangfire.Raven.Storage;
using Hangfire.Raven;
using Raven.Client;
using Raven.Json.Linq;
namespace HangFire.Raven.Storage
{
public static class SqlServerStorageExtensions
public static class RavenServerStorageExtensions
{
public static void AddExpire<T>(this ISyncAdvancedSessionOperation advanced, T obj, DateTime dateTime)
{
advanced.GetMetadataFor(obj)["Raven-Expiration-Date"] = new RavenJValue(dateTime);
}
public static void RemoveExpire<T>(this ISyncAdvancedSessionOperation advanced, T obj)
{
advanced.GetMetadataFor(obj).Remove("Raven-Expiration-Date");
}
public static DateTime? GetExpire<T>(this ISyncAdvancedSessionOperation advanced, T obj)
{
RavenJToken token;
if (advanced.GetMetadataFor(obj).TryGetValue("Raven-Expiration-Date", out token))
{
var date = token.Value<DateTime>();
return date;
}
return null;
}
public static IGlobalConfiguration<RavenStorage> UseRavenStorage(this IGlobalConfiguration configuration, RavenStorage storage)
{
storage.ThrowIfNull("storage");
@@ -14,6 +14,7 @@ using Raven.Client.Indexes;
using Raven.Abstractions.Indexing;
using Raven.Abstractions.Data;
using Hangfire.Raven.Indexes;
using HangFire.Raven.Storage;
namespace Hangfire.Raven.Storage
{
@@ -137,21 +138,22 @@ namespace Hangfire.Raven.Storage
private Dictionary<DateTime, long> GetTimelineStats(List<DateTime> dates,
Func<DateTime, string> formatorAction)
{
/*
var counters = Data.GetEnumeration<AggregatedCounterDto>();
var keyMap = dates.ToDictionary(formatorAction, x => x);
var valuesMap = (from c in counters
where keyMap.Keys.Contains(c.Key)
select c).ToDictionary(o => o.Key, o => o.Value);
foreach (var key in keyMap.Keys.Where(key => !valuesMap.ContainsKey(key)))
var stats = new Dictionary<DateTime, long>();
using (var repository = _storage.Repository.OpenSession())
{
valuesMap.Add(key, 0);
foreach(var item in dates)
{
var id = Repository.GetId(typeof(Counter), formatorAction(item));
var counters = repository.Load<Counter>(id);
if (counters != null)
stats.Add(item, counters.Value);
else
stats.Add(item, 0);
}
}
return keyMap.ToDictionary(k => k.Value, k => valuesMap[k.Key]);*/
return new Dictionary<DateTime, long>();
return stats;
}
public StatisticsDto GetStatistics()
{
@@ -304,7 +306,7 @@ namespace Hangfire.Raven.Storage
return new JobDetailsDto
{
CreatedAt = job.CreatedAt,
ExpireAt = job.ExpireAt,
ExpireAt = repository.Advanced.GetExpire(job),
Job = DeserializeJob(job.InvocationData),
History = job.History,
Properties = job.Parameters
@@ -11,7 +11,6 @@ namespace Hangfire.Raven.Storage
{
JobExpirationCheckInterval = TimeSpan.FromHours(1);
CountersAggregateInterval = TimeSpan.FromMinutes(5);
DashboardJobListLimit = 50000;
TransactionTimeout = TimeSpan.FromMinutes(1);
_clientId = Guid.NewGuid().ToString().Replace("-", String.Empty);
@@ -22,7 +21,6 @@ namespace Hangfire.Raven.Storage
public TimeSpan JobExpirationCheckInterval { get; set; }
public TimeSpan CountersAggregateInterval { get; set; }
public int? DashboardJobListLimit { get; set; }
public TimeSpan TransactionTimeout { get; set; }
public IEnumerable<string> QueueNames { get; set; }