Quartz.NET, ASP.NET MVC i łatwa edycja wyrażeń cron przy użyciu jquery-cron.js

19.11.2013

Quartz.NET to biblioteka, tzw. scheduler służący do cyklicznego wykonywania zadań. Z grubsza rzecz ujmując, konfiguracja pracy Quartz.NET sprowadzania się do tworzeniu obiektów job/trigger w celu uruchomienia określonego zadania (kodu) w zaplanowanym czasie. Do dyspozycji mamy pojedyncze (SimpleTriggerImpl dla danego DateTime) oraz cykliczne uruchamianie zadań (CronTriggerImpl w oparciu o wyrażenia cron, ang. cron expressions).

Wizualizacja DateTime nie jest wyzwaniem. W Internecie można znaleźć dużo kontrolek typu DateTimePicker. Ciekawiej wygląda sprawa w przypadku wyrażeń cron. Można uszczęśliwić użytkownika inputem i niech sam główkuje “o co kaman w tych gwiazdkach” albo wygooglować kontrolkę jquery-cron.js. Umożliwia ona prostą wizualizację wyrażenia. Wygląda to mniej więcej tak:

 image

Zamiast:

image

Jest mały problem. Wyrażenia cron rozumiane przez Quartz.NET są trochę inne  niż te, które potrafi przyswoić/wygenerować biblioteka jquery-cron.js (dodatkowe pole sekund, specyficzna obsługa kombinacji dnia miesiąca/tygodnia, amerykańska numeracja dni tygodnia). Trochę inne, znaczy, że przy próbie stworzenia triggera na podstawie wyrażenia z jquery-cron.js dostaniemy wyjątek.

Rozwiązaniem tego problemu jest korekta wyrażenia generowanego przez jquery-cron.js przy pomocy tego kodu:

public static class StringExtensions
{
    public static string FixCronExpression(this string cronExpression)
    {
        if (string.IsNullOrWhiteSpace(cronExpression)) return cronExpression;

        cronExpression = string.Format("0 {0}", cronExpression);
        var arr = cronExpression.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
        if (arr[3] != "*") arr[5] = "?";
        else if (arr[5] != "*")
        {
            arr[3] = "?";
            arr[5] = (int.Parse(arr[5]) + 1).ToString();
        }
        else arr[5] = "?";
        return string.Join(" ", arr);
    }
}

Mała uwaga. Aplikacja wykorzystująca ten kod składuje w bazie danych wyrażenie w formacie przyswajalnym przez jquery-cron.js. Nie ma wtedy problemu z ciągłą konwersją z/do podczas wyświetlania wyrażenia. Dopiero w momencie komunikacji ze scheduler’em dokonuję konwersji wyrażenia na postać rozumianą przez Quartz.NET.

Uwaga2: Aby uzyskać teksty w języku polskim trzeba niestety zmieniać kod skryptu i wyprostować kilka rzeczy przy składaniu HTML kontrolki. Kod jest jednak na tyle czytelny, że można to spokojnie wykonać w ciągu kilku, kilkunastu minut bez zbytniego wgłębiania się w szczegóły implementacyjne kontrolki.