4

ColdFusion 9で、スケジュールされたタスクが次に実行を試みる時刻をすばやく確認する方法はありますか?

4

1 に答える 1

5

むしろ、低レベルのAPIなどを呼び出して、CFに通常と同じ方法で計算させたいと思います。私はさまざまなサービスをダンプしましたが、それを呼び出すための明白なメソッドはありません。

AFAIK、1行の解決策はありません。CFが日付を計算するために使用する主な方法はですCronTabEntry.NextRunTimeCronTabEntryクラスは、単一のタスクの設定を表します。メソッドは、タスクの設定に基づいて、次の潜在的なNextRunTime実行日を計算します。期限切れおよび一時停止されたタスクの処理は、実行時に他の場所で行われます。

結果を複製するには、NextRunTime期限切れのタスクを処理するために呼び出してロジックを追加する必要があります。メソッドはプライベートですが、 Method.setAccessible (boolean)NextRunTimeを使用して、リフレクションを介してアクセスできます。

以下の機能をまとめてデモンストレーションしました。その大部分はリフレクション呼び出しです(これは、CFでは同等のjavaよりも少し冗長です)。とにかく、CFスケジューラーが使用するのと同じ日付を返す必要があります。

ルール:

  • タスクの終了日時が経過した場合は、空の文字列""を返します。
  • すでに実行されている1回限りのタスクの場合は、空の文字列""を返します。
  • 他のすべてのタスク(一時停止されたタスクを含む)については、次のスケジュールされた日付を返します

使用法:

result = new TaskUtil().getNextRunTime("SomeTask");
WriteDump(result);

CFC

component {
     public struct function getNextRunTime(required string scheduledTaskName) {

        // load task settings from factory
        local.cron = createobject("java","coldfusion.server.ServiceFactory").getCronService();
        local.task = local.cron.findTask( arguments.scheduledTaskName );

        // abort if we cannot find the task ..
        if ( isNull(local.task) ) {
            throw ("The specified task was not found: ["& arguments.scheduledTaskName &"]");
        }     

        // Calculate the next POTENTIAL schedule date 
        local.isRecurring = listFindNoCase("daily,weekly,monthly", local.task.interval);
        local.dateClass   = createObject("java", "java.util.Date").getClass();
        local.longClass   = createObject("java", "java.lang.Long").TYPE;
        local.stringClass = createObject("java", "java.lang.String").getClass();

        // Construct the appropriate arguments 
        // Note: must load arguments / class types into arrays for java reflection 
        if (local.isRecurring) {
            local.args  = [ local.task.getStartDate(), local.task.getStartTime(), local.task.interval ];
            local.types = [ local.dateClass, local.dateClass, local.stringClass ];
        }
        else {
            local.args  = [ local.task.getStartDate(), local.task.getStartTime(), local.task.getEndTime(), javacast("long", val(local.task.interval) * 1000) ];
            local.types = [ local.dateClass, local.dateClass, local.dateClass, local.longClass ];
        }

        // Call CF's internal method to calculate the next date (UNDOCUMENTED)    
        local.internalMethod = local.task.getClass().getDeclaredMethod("NextRunTime", local.types );
        local.internalMethod.setAccessible( true );
        local.nextRunOnDate = local.internalMethod.invoke( local.task, local.args );

        // Determine if the task will be rescheduled
        local.isExpired   = false;
        if ( local.task.interval != "once" && structKeyExists( local.task, "end_date") ) {
            // It is non-recurring, so determine if it already expired
            local.expiresOnDate = local.task.mergeDates( local.task.getEndDate(), local.task.getEndTime() );
            local.isExpired   = dateCompare( local.nextRunOnDate, local.expiresOnDate, "s") >= 0;
        }
        else if ( local.task.interval == "once" && local.task.disabled) {
            // It is a one time task that already executed
            local.isExpired   = true;
        }

        // construct and return results    
        local.result = {};
        local.result.name          = local.task.task;
        local.result.isPaused    = local.task.paused;
        local.result.isExpired   = local.isExpired;
        local.result.nextRunTime = local.isExpired ? "" : local.nextRunOnDate;

        return local.result;
    }    
}
于 2012-05-25T08:20:17.160 に答える