Revert back to using InvocationData, as the following functionality has been lost, but is already handled by Hangfire

- Overloaded method calls e.g. Console.WriteLine(String) vs Console.WriteLine(Int32) Console.WriteLine(Boolean)
- Generic method calls
- Nullable parameters in method calls
- Special handling of CancellationToken arguments during serialization/deserialization
This commit is contained in:
Michael Johnson
2016-12-09 12:52:17 +11:00
parent 9ff2e53301
commit 7aa06fe914
6 changed files with 21 additions and 232 deletions
-54
View File
@@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
#if !NET45
using Microsoft.Extensions.DependencyModel;
#endif
namespace Hangfire.Raven
{
/// <summary>
/// Helper class for getting assemblies
/// </summary>
public static class Assemblies
{
/// <summary>
/// Get all loaded assemblies
/// </summary>
/// <returns></returns>
public static IEnumerable<Assembly> Get()
{
#if NET45
return AppDomain.CurrentDomain.GetAssemblies().Where(a => a != null);
#else
return (from compilationLibrary in DependencyContext.Default.CompileLibraries
where compilationLibrary.Name.Contains(typeof(Assemblies).Namespace)
select Assembly.Load(new AssemblyName(compilationLibrary.Name)))
.ToList();
#endif
}
/// <summary>
/// Get class by name within an assembly
/// </summary>
/// <param name="assembly">Assembly</param>
/// <param name="type">Name of type</param>
/// <returns></returns>
public static Type GetClass(Assembly assembly, string type)
{
return (from t in assembly.GetTypes()
where t.FullName == type //&& !t.IsAbstract && t.IsClass
select t).FirstOrDefault();
}
public static string GetAssemblyName(MemberInfo value)
{
#if NET45
return value.DeclaringType.Assembly.GetName().Name;
#else
return value.DeclaringType.GetTypeInfo().Assembly.GetName().Name;
#endif
}
}
}
+1 -25
View File
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Hangfire.Common;
using Hangfire.Storage;
using Hangfire.Storage.Monitoring;
@@ -15,31 +13,9 @@ namespace Hangfire.Raven.Entities
this.Parameters = new Dictionary<string, string>();
this.History = new List<StateHistoryDto>();
}
public class JobWrapper
{
public IEnumerable<object> Arguments { get; set; }
public Type Type { get; set; }
public MethodInfo Method { get; set; }
public Job GetJob()
{
return new Job(this.Type, this.Method, this.Arguments.ToArray());
}
public static JobWrapper Create(Job job)
{
var toReturn = new JobWrapper();
toReturn.Arguments = job.Args;
toReturn.Method = job.Method;
toReturn.Type = job.Type;
return toReturn;
}
}
public string Id { get; set; }
public JobWrapper Job { get; set; }
public InvocationData InvocationData { get; set; }
public IDictionary<string, string> Parameters { get; set; }
public DateTime CreatedAt { get; set; }
+16 -3
View File
@@ -77,11 +77,13 @@ namespace Hangfire.Raven
parameters.ThrowIfNull("parameters");
using (var repository = _storage.Repository.OpenSession()) {
var invocationData = InvocationData.Serialize(job);
var guid = Guid.NewGuid().ToString();
var ravenJob = new RavenJob {
Id = Repository.GetId(typeof(RavenJob), guid),
Job = JobWrapper.Create(job),
InvocationData = invocationData,
CreatedAt = createdAt,
Parameters = parameters
};
@@ -107,12 +109,23 @@ namespace Hangfire.Raven
return null;
}
var job = jobData.Job.GetJob();
Job job = null;
JobLoadException loadException = null;
try
{
job = jobData.InvocationData.Deserialize();
}
catch (JobLoadException ex)
{
loadException = ex;
}
return new JobData {
Job = job,
State = jobData.StateData?.Name,
CreatedAt = jobData.CreatedAt
CreatedAt = jobData.CreatedAt,
LoadException = loadException
};
}
}
-133
View File
@@ -1,133 +0,0 @@
using System;
using System.Linq;
using System.Reflection;
using Raven.Imports.Newtonsoft.Json;
using Raven.Imports.Newtonsoft.Json.Linq;
namespace Hangfire.Raven
{
/// <summary>
/// Base class for Raven Json Converters
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class RavenJsonConverterBase<T>
: JsonConverter
{
public RavenJsonConverterBase()
{
}
/// <summary>
/// Read Json and convert to T
/// </summary>
/// <param name="type"></param>
/// <param name="value">Object to convert</param>
/// <param name="serializer">JsonSerializer</param>
/// <returns>Object</returns>
protected abstract T Read(Type type, object value, JsonSerializer serializer);
/// <summary>
/// Write Json and convert T to text
/// </summary>
/// <param name="value">Input</param>
/// <returns>Input as text</returns>
protected abstract object Write(T value, JsonSerializer serializer);
/// <summary>
/// Overriding the CanConvert of JsonConvert
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public override bool CanConvert(Type type) => typeof(T).IsAssignableFrom(type);
/// <summary>
/// Overriding the ReadJson of JsonConvert
/// </summary>
/// <param name="reader"></param>
/// <param name="type"></param>
/// <param name="existingValue"></param>
/// <param name="serializer"></param>
/// <returns></returns>
public override object ReadJson(JsonReader reader, Type type, object existingValue, JsonSerializer serializer)
{
T toReturn;
switch (reader.TokenType) {
case JsonToken.StartArray:
toReturn = Read(type, JArray.Load(reader), serializer);
break;
case JsonToken.StartObject:
toReturn = Read(type, JObject.Load(reader), serializer);
break;
default:
toReturn = Read(type, reader.Value, serializer);
break;
}
return toReturn;
}
/// <summary>
/// Overriding the WriteJson of JsonConvert
/// </summary>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="serializer"></param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, Write((T)value, serializer));
}
}
public class RavenJsonMethodConverter
: RavenJsonConverterBase<MethodInfo>
{
protected override MethodInfo Read(Type type, object value, JsonSerializer serializer)
{
if (value == null) {
return null;
}
var splitted = value.ToString().Split(';');
if (splitted.Count() == 3) {
var assembly = Assemblies.Get().Where(a => a.GetName().Name == splitted[0]).First();
var assemblyClass = Assemblies.GetClass(assembly, splitted[1]);
if (assemblyClass != null) {
return assemblyClass.GetMethod(splitted[2]);
}
}
return null;
}
protected override object Write(MethodInfo value, JsonSerializer serializer) => $"{value.DeclaringType.GetTypeInfo().Assembly.GetName().Name};{value.DeclaringType.FullName};{value.Name}";
}
public class RavenJsonPropertyConverter
: RavenJsonConverterBase<PropertyInfo>
{
protected override PropertyInfo Read(Type type, object value, JsonSerializer serializer)
{
if (value == null) {
return null;
}
var splitted = value.ToString().Split(';');
if (splitted.Count() == 3) {
var assembly = Assemblies.Get().Where(a => a.GetName().Name == splitted[0]).First();
var assemblyType = Assemblies.GetClass(assembly, splitted[1]);
if (assemblyType != null) {
return assemblyType.GetProperty(splitted[2]);
}
}
return null;
}
protected override object Write(PropertyInfo value, JsonSerializer serializer) => $"{value.DeclaringType.GetTypeInfo().Assembly.GetName().Name};{value.DeclaringType.FullName};{value.Name}";
}
}
+2 -15
View File
@@ -7,7 +7,6 @@ using Raven.Abstractions.Data;
using Raven.Client;
using Raven.Client.Document;
using Raven.Client.Indexes;
using Raven.Imports.Newtonsoft.Json;
namespace Hangfire.Raven
{
@@ -56,25 +55,13 @@ namespace Hangfire.Raven
if (!string.IsNullOrEmpty(_config.ConnectionStringName)) {
_documentStore = new DocumentStore {
ConnectionStringName = _config.ConnectionStringName,
Conventions = new DocumentConvention() {
CustomizeJsonSerializer = delegate (JsonSerializer input) {
input.Converters.Add(new RavenJsonPropertyConverter());
input.Converters.Add(new RavenJsonMethodConverter());
}
}
ConnectionStringName = _config.ConnectionStringName
};
} else {
_documentStore = new DocumentStore {
Url = _config.ConnectionUrl,
ApiKey = _config.ApiKey,
DefaultDatabase = _config.Database,
Conventions = new DocumentConvention() {
CustomizeJsonSerializer = delegate (JsonSerializer input) {
input.Converters.Add(new RavenJsonPropertyConverter());
input.Converters.Add(new RavenJsonMethodConverter());
}
}
DefaultDatabase = _config.Database
};
}
@@ -285,7 +285,7 @@ namespace Hangfire.Raven.Storage
return new JobDetailsDto {
CreatedAt = job.CreatedAt,
ExpireAt = repository.Advanced.GetExpire(job),
Job = job.Job.GetJob(),
Job = DeserializeJob(job.InvocationData),
History = job.History,
Properties = job.Parameters
};
@@ -399,7 +399,7 @@ namespace Hangfire.Raven.Storage
let stateData = job.StateData.Data != null
? new Dictionary<string, string>(job.StateData.Data, StringComparer.OrdinalIgnoreCase)
: null
let dto = selector(job, job.Job.GetJob(), stateData)
let dto = selector(job, DeserializeJob(job.InvocationData), stateData)
select new KeyValuePair<string, TDto>(job.Id.Split(new char[] { '/' }, 2)[1], dto);
return new JobList<TDto>(result);