abpframework / abp

Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
https://abp.io
GNU Lesser General Public License v3.0
12.86k stars 3.43k forks source link

Update to Quartz 3.1.0 #4775

Closed olicooper closed 4 years ago

olicooper commented 4 years ago

Version 3 is not official yet but there is a beta out with some great improvements v3.1.0-beta2

Features such as DI, MySQL connector and appsettings integration would be useful to utilize in abp. There are a number of bug fixes and performance improvements too.

I have been using a nightly version in my project for a while and it's been working great so there should be too many issues with upgrading it.

realLiangshiwei commented 4 years ago

Quartz.Net v3.1.0-beta2 looks good. It contains a lot of changes, I will try integrate.

olicooper commented 4 years ago

The latest stable version of Quartz has just been released and it looks great! OpenTelemtry and TimeZoneConverter support now added too 👍

GitHub release | Changelog

Update: I have upgraded my own project to this release but there are issues when using MySql as the provider 😢 Volo.Abp.EntityFrameworkCore.MySQL uses Pomelo.EntityframeworkCore.MySql @ v3.1.1 which depends on MySqlConnector < 1.0.0, but Quartz requires MySqlConnector >= 1.0.0, which causes a dependency conflict between the packages. Pomelo are going to upgrade their MySqlConnector dependancy to >= 1.0.0 but they won't be doing it until v5.0.0 (because it is a breaking change) which I assume aligns with the release of .NET 5 - so we could be waiting until November for this to be resolved! 😢 If we upgrade this package before .NET 5, there might be a way to fix the MySQL dependency problem by using a custom provider but I haven't looked in to it yet.

olicooper commented 4 years ago

I have a few suggestions if that's okay?

  1. Remove the Microsoft.Data.SqlClient dependency and let the developer choose which provider they use (the same way that the core Quartz library does it).
  2. Add a dependency on Quartz.Plugins.TimeZoneConverter so that it integrates with the recent changes made here https://github.com/abpframework/abp/pull/3933
  3. As mentioned here https://github.com/abpframework/abp/commit/46dbe7691070d88382d8afd6e3c740e82f8d4720#r41528924, Add a custom MySqlConnector provider which allows MySql databases to work again after the Quartz 3.1.0 update. Already fixed here: https://github.com/abpframework/abp/pull/5094
  4. Don't use Configurator if Properties are specified i.e. in here: https://github.com/abpframework/abp/blob/46dbe7691070d88382d8afd6e3c740e82f8d4720/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzOptions.cs#L14-L16

Update:

I have managed to work out how to use the custom provider. I tried creating one using configuration (i.e. appsettings.json, quartz.config, AbpQuartzOptions) but these didn't work. In the end I managed to use the following:

var mySqlAvailable = System.Type.GetType("MySql.Data.MySqlClient.MySqlConnection, MySqlConnector") != null;
if (mySqlAvailable)
{
    DbProvider.RegisterDbMetadata("AbpMySqlConnector", new DbMetadata()
    {
        ProductName = "MySQL, MySqlConnector provider",
        AssemblyName = "MySqlConnector",
        ConnectionType = System.Type.GetType("MySql.Data.MySqlClient.MySqlConnection, MySqlConnector"),
        CommandType = System.Type.GetType("MySql.Data.MySqlClient.MySqlCommand, MySqlConnector"),
        ParameterType = System.Type.GetType("MySql.Data.MySqlClient.MySqlParameter, MySqlConnector"),
        ParameterDbType = System.Type.GetType("MySql.Data.MySqlClient.MySqlDbType, MySqlConnector"),
        ParameterDbTypePropertyName = "MySqlDbType",
        ParameterNamePrefix = "?",
        ExceptionType = System.Type.GetType("MySql.Data.MySqlClient.MySqlException, MySqlConnector"),
        BindByName = true,
        DbBinaryTypeName = "Blob"
    });
}

... And then use the data source using the Configurator options:

PreConfigure<AbpQuartzOptions>(options =>
{
    options.Configurator = configure =>
    {
        configure.UsePersistentStore(storeOptions =>
        {
            storeOptions.UseGenericDatabase("AbpMySqlConnector", providerOptions =>
            {
                providerOptions.ConnectionString = configuration.GetConnectionString("Quartz");
                providerOptions.TablePrefix = "QRTZ_";
            });
        });
    };
});

I think this is more elegant and is easy to add to Abp too.

realLiangshiwei commented 4 years ago

Hi @olicooper ,

  1. https://github.com/quartznet/quartznet/pull/912 Quartz has removed the Microsoft.Data.SqlClient dependency, we will update when quartz version 3.2 is released
  2. https://github.com/abpframework/abp/issues/5096
  3. https://github.com/abpframework/abp/pull/5094/commits/c535194fd187b710e503ba75058da55aa7e74e7d