From 7aa06fe914cd996c36b855b632bf312e557ac94c Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Fri, 9 Dec 2016 12:52:17 +1100 Subject: [PATCH] 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 --- src/Hangfire.Raven/Assemblies.cs | 54 ------- src/Hangfire.Raven/Entities/RavenJob.cs | 26 +--- src/Hangfire.Raven/RavenConnection.cs | 19 ++- src/Hangfire.Raven/RavenJsonConverters.cs | 133 ------------------ src/Hangfire.Raven/Repository.cs | 17 +-- .../Storage/RavenStorageMonitoringApi.cs | 4 +- 6 files changed, 21 insertions(+), 232 deletions(-) delete mode 100644 src/Hangfire.Raven/Assemblies.cs delete mode 100644 src/Hangfire.Raven/RavenJsonConverters.cs diff --git a/src/Hangfire.Raven/Assemblies.cs b/src/Hangfire.Raven/Assemblies.cs deleted file mode 100644 index b01f9f9..0000000 --- a/src/Hangfire.Raven/Assemblies.cs +++ /dev/null @@ -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 -{ - /// - /// Helper class for getting assemblies - /// - public static class Assemblies - { - /// - /// Get all loaded assemblies - /// - /// - public static IEnumerable 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 - } - - /// - /// Get class by name within an assembly - /// - /// Assembly - /// Name of type - /// - 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 - } - } -} diff --git a/src/Hangfire.Raven/Entities/RavenJob.cs b/src/Hangfire.Raven/Entities/RavenJob.cs index fda6666..8cc4876 100644 --- a/src/Hangfire.Raven/Entities/RavenJob.cs +++ b/src/Hangfire.Raven/Entities/RavenJob.cs @@ -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(); this.History = new List(); } - public class JobWrapper - { - public IEnumerable 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 Parameters { get; set; } public DateTime CreatedAt { get; set; } diff --git a/src/Hangfire.Raven/RavenConnection.cs b/src/Hangfire.Raven/RavenConnection.cs index 2b65272..0a29764 100644 --- a/src/Hangfire.Raven/RavenConnection.cs +++ b/src/Hangfire.Raven/RavenConnection.cs @@ -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 }; } } diff --git a/src/Hangfire.Raven/RavenJsonConverters.cs b/src/Hangfire.Raven/RavenJsonConverters.cs deleted file mode 100644 index 7c6d90b..0000000 --- a/src/Hangfire.Raven/RavenJsonConverters.cs +++ /dev/null @@ -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 -{ - /// - /// Base class for Raven Json Converters - /// - /// - public abstract class RavenJsonConverterBase - : JsonConverter - { - public RavenJsonConverterBase() - { - } - - /// - /// Read Json and convert to T - /// - /// - /// Object to convert - /// JsonSerializer - /// Object - protected abstract T Read(Type type, object value, JsonSerializer serializer); - - /// - /// Write Json and convert T to text - /// - /// Input - /// Input as text - protected abstract object Write(T value, JsonSerializer serializer); - - /// - /// Overriding the CanConvert of JsonConvert - /// - /// - /// - public override bool CanConvert(Type type) => typeof(T).IsAssignableFrom(type); - - /// - /// Overriding the ReadJson of JsonConvert - /// - /// - /// - /// - /// - /// - 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; - } - - /// - /// Overriding the WriteJson of JsonConvert - /// - /// - /// - /// - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - serializer.Serialize(writer, Write((T)value, serializer)); - } - } - - public class RavenJsonMethodConverter - : RavenJsonConverterBase - { - 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 - { - 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}"; - } -} diff --git a/src/Hangfire.Raven/Repository.cs b/src/Hangfire.Raven/Repository.cs index a3555bb..f11f0bf 100644 --- a/src/Hangfire.Raven/Repository.cs +++ b/src/Hangfire.Raven/Repository.cs @@ -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 }; } diff --git a/src/Hangfire.Raven/Storage/RavenStorageMonitoringApi.cs b/src/Hangfire.Raven/Storage/RavenStorageMonitoringApi.cs index abe2124..8a01441 100644 --- a/src/Hangfire.Raven/Storage/RavenStorageMonitoringApi.cs +++ b/src/Hangfire.Raven/Storage/RavenStorageMonitoringApi.cs @@ -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(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(job.Id.Split(new char[] { '/' }, 2)[1], dto); return new JobList(result);