wanlitao / HangfireExtension

Hangfire Extension plugins
Apache License 2.0
22 stars 32 forks source link

It should be documented that the connection string must include DateTimeFormat=Ticks #22

Closed 0xced closed 2 years ago

0xced commented 6 years ago

I was seeing jobs executed in the future! This is because of SQLite provider mapping of DateTime fields which sets the Kind property to Unspecified, leading to bad computations by Hangfire. Adding ;DateTimeFormat=Ticks to the connection string solved the issue.

This is also somewhat related to #18 as you have now a good excuse to use a ; in the connection string. ๐Ÿ˜‰

Wintereise commented 6 years ago

I set this, but it doesn't quite seem to work as intended for me:

System.ArgumentException: Keyword not supported: 'datetimeformat'.
   at Microsoft.Data.Sqlite.SqliteConnectionStringBuilder.GetIndex(String keyword)
   at Microsoft.Data.Sqlite.SqliteConnectionStringBuilder.set_Item(String keyword, Object value)
   at System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(String value)
   at Microsoft.Data.Sqlite.SqliteConnection.set_ConnectionString(String value)
   at Hangfire.SQLite.SQLiteStorage.CreateAndOpenConnection(Boolean isWriteLock)
   at Hangfire.SQLite.SQLiteStorage.UseConnection[T](Func`2 func, Boolean isWriteLock)
   at Hangfire.SQLite.SQLiteStorage.UseConnection(Action`1 action, Boolean isWriteLock)
   at Hangfire.SQLite.SQLiteStorage.Initialize()
   at Hangfire.SQLite.SQLiteStorageExtensions.UseSQLiteStorage(IGlobalConfiguration configuration, String nameOrConnectionString, SQLiteStorageOptions options)
   at Spectero.daemon.Startup.<>c__DisplayClass6_0.<ConfigureServices>b__4(IGlobalConfiguration config) in G:\Spectero\daemon\daemon\Startup.cs:line 126
   at Hangfire.HangfireServiceCollectionExtensions.GetInitializedJobStorage(IServiceProvider serviceProvider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.<RealizeService>b__0(ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Hangfire.HangfireApplicationBuilderExtensions.UseHangfireServer(IApplicationBuilder app, BackgroundJobServerOptions options, IEnumerable`1 additionalProcesses, JobStorage storage)
   at Spectero.daemon.Startup.Configure(IOptionsSnapshot`1 configMonitor, IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMigration migration, IAutoStarter autoStarter) in G:\Spectero\daemon\daemon\Startup.cs:line 160
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
   at Microsoft.AspNetCore.ApplicationInsights.HostingStartup.ApplicationInsightsLoggerStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder builder)
   at Microsoft.ApplicationInsights.AspNetCore.ApplicationInsightsStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.6\System.Diagnostics.Tools.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.Exception","time":"2018-03-23T10:06:41.1367268Z","tags":{"ai.internal.sdkVersion":"aspnet5c:2.1.1","ai.application.ver":"1.0.0.0"},"data":{"baseType":"ExceptionData","baseData":{"ver":2,"properties":{"AspNetCoreEnvironment":"local","{OriginalFormat}":"Application startup exception","DeveloperMode":"true","Exception":"System.ArgumentException: Keyword not supported: 'datetimeformat'.\r\n   at Microsoft.Data.Sqlite.SqliteConnectionStringBuilder.GetIndex(String keyword)\r\n   at Microsoft.Data.Sqlite.SqliteConnectionStringBuilder.set_Item(String keyword, Object value)\r\n   at System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(String value)\r\n   at Microsoft.Data.Sqlite.SqliteConnection.set_ConnectionString(String value)\r\n   at Hangfire.SQLite.SQLiteStorage.CreateAndOpenConnection(Boolean isWriteLock)\r\n   at Hangfire.SQLite.SQLiteStorage.UseConnection[T](Func`2 func, Boolean isWriteLock)\r\n   at Hangfire.SQLite.SQLiteStorage.UseConnection(Action`1 action, Boolean isWriteLock)\r\n   at Hangfire.SQLite.SQLiteStorage.Initialize()\r\n   at Hangfire.SQLite.SQLiteStorageExtensions.UseSQLiteStorage(IGlobalConfiguration configuration, String nameOrConnectionString, SQLiteStorageOptions options)\r\n   at Spectero.daemon.Startup.<>c__DisplayClass6_0.<ConfigureServices>b__4(IGlobalConfiguration config) in G:\\Spectero\\daemon\\daemon\\Startup.cs:line 126\r\n   at Hangfire.HangfireServiceCollectionExtensions.GetInitializedJobStorage(IServiceProvider serviceProvider)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProvider provider)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.<RealizeService>b__0(ServiceProvider provider)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)\r\n   at Hangfire.HangfireApplicationBuilderExtensions.UseHangfireServer(IApplicationBuilder app, BackgroundJobServerOptions options, IEnumerable`1 additionalProcesses, JobStorage storage)\r\n   at Spectero.daemon.Startup.Configure(IOptionsSnapshot`1 configMonitor, IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMigration migration, IAutoStarter autoStarter) in G:\\Spectero\\daemon\\daemon\\Startup.cs:line 160\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)\r\n   at Microsoft.AspNetCore.ApplicationInsights.HostingStartup.ApplicationInsightsLoggerStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder builder)\r\n   at Microsoft.ApplicationInsights.AspNetCore.ApplicationInsightsStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)\r\n   at Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder builder)\r\n   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()","CategoryName":"Microsoft.AspNetCore.Hosting.Internal.WebHost"},"exceptions":[{"id":23037620,"typeName":"System.ArgumentException","message":"Application startup exception","hasFullStack":true,"parsedStack":[{"level":0,"method":"Microsoft.Data.Sqlite.SqliteConnectionStringBuilder.GetIndex","assembly":"Microsoft.Data.Sqlite, Version=2.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":1,"method":"Microsoft.Data.Sqlite.SqliteConnectionStringBuilder.set_Item","assembly":"Microsoft.Data.Sqlite, Version=2.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":2,"method":"System.Data.Common.DbConnectionStringBuilder.set_ConnectionString","assembly":"System.Data.Common, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"},{"level":3,"method":"Microsoft.Data.Sqlite.SqliteConnection.set_ConnectionString","assembly":"Microsoft.Data.Sqlite, Version=2.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":4,"method":"Hangfire.SQLite.SQLiteStorage.CreateAndOpenConnection","assembly":"Hangfire.SQLite, Version=1.4.2.0, Culture=neutral, PublicKeyToken=null"},{"level":5,"method":"Hangfire.SQLite.SQLiteStorage.UseConnection","assembly":"Hangfire.SQLite, Version=1.4.2.0, Culture=neutral, PublicKeyToken=null"},{"level":6,"method":"Hangfire.SQLite.SQLiteStorage.UseConnection","assembly":"Hangfire.SQLite, Version=1.4.2.0, Culture=neutral, PublicKeyToken=null"},{"level":7,"method":"Hangfire.SQLite.SQLiteStorage.Initialize","assembly":"Hangfire.SQLite, Version=1.4.2.0, Culture=neutral, PublicKeyToken=null"},{"level":8,"method":"Hangfire.SQLite.SQLiteStorageExtensions.UseSQLiteStorage","assembly":"Hangfire.SQLite, Version=1.4.2.0, Culture=neutral, PublicKeyToken=null"},{"level":9,"method":"Spectero.daemon.Startup+<>c__DisplayClass6_0.<ConfigureServices>b__4","assembly":"daemon, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","fileName":"G:\\Spectero\\daemon\\daemon\\Startup.cs","line":126},{"level":10,"method":"Hangfire.HangfireServiceCollectionExtensions.GetInitializedJobStorage","assembly":"Hangfire.AspNetCore, Version=1.6.17.0, Culture=neutral, PublicKeyToken=null"},{"level":11,"method":"Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory","assembly":"Microsoft.Extensions.DependencyInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":12,"method":"Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite","assembly":"Microsoft.Extensions.DependencyInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":13,"method":"Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped","assembly":"Microsoft.Extensions.DependencyInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":14,"method":"Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton","assembly":"Microsoft.Extensions.DependencyInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":15,"method":"Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite","assembly":"Microsoft.Extensions.DependencyInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":16,"method":"Microsoft.Extensions.DependencyInjection.ServiceProvider+<>c__DisplayClass22_0.<RealizeService>b__0","assembly":"Microsoft.Extensions.DependencyInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":17,"method":"Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService","assembly":"Microsoft.Extensions.DependencyInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":18,"method":"Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService","assembly":"Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":19,"method":"Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService","assembly":"Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":20,"method":"Hangfire.HangfireApplicationBuilderExtensions.UseHangfireServer","assembly":"Hangfire.AspNetCore, Version=1.6.17.0, Culture=neutral, PublicKeyToken=null"},{"level":21,"method":"Spectero.daemon.Startup.Configure","assembly":"daemon, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","fileName":"G:\\Spectero\\daemon\\daemon\\Startup.cs","line":160},{"level":22,"method":"System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw","assembly":"System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"},{"level":23,"method":"Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure","assembly":"Microsoft.AspNetCore.Hosting, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":24,"method":"Microsoft.AspNetCore.ApplicationInsights.HostingStartup.ApplicationInsightsLoggerStartupFilter+<>c__DisplayClass0_0.<Configure>b__0","assembly":"Microsoft.AspNetCore.ApplicationInsights.HostingStartup, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":25,"method":"Microsoft.ApplicationInsights.AspNetCore.ApplicationInsightsStartupFilter+<>c__DisplayClass0_0.<Configure>b__0","assembly":"Microsoft.ApplicationInsights.AspNetCore, Version=2.1.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"},{"level":26,"method":"Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter+<>c__DisplayClass0_0.<Configure>b__0","assembly":"Microsoft.AspNetCore.Hosting, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"},{"level":27,"method":"Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication","assembly":"Microsoft.AspNetCore.Hosting, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"}]}],"severityLevel":"Critical"}}}
An unhandled exception of type 'System.ArgumentException' occurred in Microsoft.AspNetCore.Hosting.dll
Keyword not supported: 'datetimeformat'.

This is my connection string, pretty standard: "JobsConnectionString": "Data Source=Database/jobs.sqlite;DateTimeFormat=Ticks",

Though, the property itself seems standard. Anyone got ideas?

0xced commented 6 years ago

Under .NET Core (target framework .NETStandard,Version=v2.0) Hangfire.SQLite is using Microsoft.Data.Sqlite instead of System.Data.SQLite and those two packages do not support the same connection string options. (I am running on Windows .NET Framework v4.5)

For reference:

Microsoft.Data.Sqlite documentations says that DateTime mapping supports both TEXT and REAL but I donโ€™t know how to configure it.