mirror of
https://github.com/fabioformosa/quartz-manager.git
synced 2026-05-14 22:00:30 +09:00
#48 made configurable the misfire instruction
This commit is contained in:
@@ -100,18 +100,25 @@
|
||||
>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<div>
|
||||
<h5>Misfire Policy</h5>
|
||||
<div>RESCHEDULE NEXT WITH REMAINING COUNT</div>
|
||||
<div class="small">
|
||||
In case of misfire event, the trigger is re-scheduled to the next scheduled time after 'now' with the repeat count set to what it would be, if it had not missed any firings.
|
||||
<br/>
|
||||
<strong>Warning:</strong> This policy could cause the Trigger to go directly to the 'COMPLETE' state if all fire-times where missed.
|
||||
</div>
|
||||
<mat-form-field
|
||||
[appearance]="enabledTriggerForm ? 'standard': 'none'"
|
||||
class="full-size-input"
|
||||
>
|
||||
<mat-label>Misfire Instruction</mat-label>
|
||||
<mat-select id="misfireInstruction" name="misfireInstruction" [(ngModel)]="simpleTriggerForm.misfireInstruction" [disabled]="!enabledTriggerForm">
|
||||
<mat-option value="MISFIRE_INSTRUCTION_FIRE_NOW">FIRE NOW</mat-option>
|
||||
<mat-option value="MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT">RESCHEDULE NOW WITH EXISTING REPEAT COUNT</mat-option>
|
||||
<mat-option value="MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT">RESCHEDULE NOW WITH REMAINING REPEAT COUNT</mat-option>
|
||||
<mat-option value="MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT">RESCHEDULE NEXT WITH REMAINING COUNT</mat-option>
|
||||
<mat-option value="MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT">RESCHEDULE NEXT WITH EXISTING COUNT</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div class="small" [innerHTML]="getMisfireInstructionCaption()"> </div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<br><br>
|
||||
|
||||
<button mat-raised-button
|
||||
type="button"
|
||||
|
||||
@@ -7,6 +7,7 @@ import {SimpleTriggerForm} from '../../model/simple-trigger.form';
|
||||
import * as moment from 'moment';
|
||||
import {TriggerKey} from '../../model/triggerKey.model';
|
||||
import JobService from '../../services/job.service';
|
||||
import {MisfireInstruction, MisfireInstructionCaption} from '../../model/misfire-instruction.model';
|
||||
|
||||
@Component({
|
||||
selector: 'qrzmng-simple-trigger-config',
|
||||
@@ -112,6 +113,7 @@ export class SimpleTriggerConfigComponent implements OnInit {
|
||||
command.repeatInterval = simpleTrigger.repeatInterval;
|
||||
command.startDate = moment(simpleTrigger.startTime);
|
||||
command.endDate = moment(simpleTrigger.endTime);
|
||||
command.misfireInstruction = MisfireInstruction[simpleTrigger.misfireInstruction];
|
||||
return command;
|
||||
}
|
||||
|
||||
@@ -123,7 +125,12 @@ export class SimpleTriggerConfigComponent implements OnInit {
|
||||
simpleTriggerCommand.repeatInterval = simpleTriggerForm.repeatInterval;
|
||||
simpleTriggerCommand.startDate = simpleTriggerForm.startDate?.toDate();
|
||||
simpleTriggerCommand.endDate = simpleTriggerForm.endDate?.toDate();
|
||||
simpleTriggerCommand.misfireInstruction = simpleTriggerForm.misfireInstruction;
|
||||
return simpleTriggerCommand;
|
||||
}
|
||||
|
||||
getMisfireInstructionCaption(): string {
|
||||
const misfireInstructionKey = this.simpleTriggerForm.misfireInstruction as unknown as keyof typeof MisfireInstruction;
|
||||
return MisfireInstructionCaption.get(MisfireInstruction[misfireInstructionKey]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
export enum MisfireInstruction {
|
||||
MISFIRE_INSTRUCTION_FIRE_NOW = 1,
|
||||
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT = 2,
|
||||
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT = 3 ,
|
||||
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT = 4,
|
||||
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT = 5
|
||||
}
|
||||
|
||||
export function getMisfireInstructionByIndex(index: number) {
|
||||
return Object.keys(MisfireInstruction)[index];
|
||||
}
|
||||
|
||||
// function enumFromStringValue<T> (enm: { [s: string]: T}, value: string): T | undefined {
|
||||
// return (Object.values(enm) as unknown as string[]).includes(value)
|
||||
// ? value as unknown as T
|
||||
// : undefined;
|
||||
// }
|
||||
//
|
||||
// export function parseMisfireInstruction(str: string): MisfireInstruction {
|
||||
// return enumFromStringValue<MisfireInstruction>(MisfireInstruction, str);
|
||||
// // return (<any>MisfireInstruction)[str]
|
||||
// // const indexOfStr = Object.values(MisfireInstruction).indexOf(str as unknown as MisfireInstruction);
|
||||
// // const key = Object.keys(Sizes)[indexOfStr];
|
||||
// // return MisfireInstruction[k]
|
||||
// // return Object.values(MisfireInstruction).find(val => val === str);
|
||||
// }
|
||||
|
||||
export const MisfireInstructionCaption = new Map<number, string>([
|
||||
[MisfireInstruction.MISFIRE_INSTRUCTION_FIRE_NOW,
|
||||
`The job is executed immediately after the scheduler discovers misfire situation.<br/>
|
||||
In case of the trigger has been set with a repeat count, this policy is equals to RESCHEDULE NOW WITH REMAINING REPEAT COUNT`
|
||||
],
|
||||
[MisfireInstruction.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT,
|
||||
`First misfired trigger is executed immediately. Then the scheduler waits desired interval and executes all remaining triggers.<br/>
|
||||
Effectively the first fire time of the misfired trigger is moved to current time with no other changes.`
|
||||
],
|
||||
[MisfireInstruction.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT,
|
||||
`First misfired execution runs immediately. Remaining misfired executions are discarded. Remaining not-yet-fired triggers are executed
|
||||
with desired interval, starting from the recovered misfired execution.<br/>
|
||||
Use this policy if your constraint is to honor the end date time.<br/>
|
||||
<strong>Warning</strong> The actual number of job executions could be less than initially set,
|
||||
because some of the misfired triggers are ignored. The end date time you set is always `
|
||||
],
|
||||
[MisfireInstruction.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT,
|
||||
`In case of misfire event, the scheduler won't do anything immediately. Instead it will wait for next scheduled time the trigger and
|
||||
run all triggers with scheduled interval. Misfired trigger are simply post-poned but not ignored.<br/>
|
||||
Use this policy if your constraint is to execute the job for the all times equals to the repeation counter.<br/>' +
|
||||
'<strong>Warning</strong> The scheduler can completed over the end date time you set `],
|
||||
[MisfireInstruction.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT,
|
||||
`In case of misfire event, the trigger is re-scheduled to the next scheduled time after 'now'
|
||||
with the repeat count set to what it would be if it had not missed any firings.<br/>
|
||||
Use this policy if no jobs must run after the end date time.<br/>
|
||||
<strong>Warning</strong> The actual number of job executions could be less than initially set, because the misfired trigger are ignored.<br/>
|
||||
This policy could cause the Trigger to go directly to the 'COMPLETE' state if all fire-times where missed.`
|
||||
]
|
||||
]);
|
||||
@@ -5,4 +5,5 @@ export class SimpleTriggerCommand {
|
||||
endDate: Date;
|
||||
repeatCount: number;
|
||||
repeatInterval: number;
|
||||
misfireInstruction: string;
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ export class SimpleTriggerForm {
|
||||
endDate: Moment;
|
||||
repeatCount: number;
|
||||
repeatInterval: number;
|
||||
misfireInstruction: string;
|
||||
}
|
||||
|
||||
@@ -19,14 +19,38 @@ public class SimpleTriggerCommandDTOToSimpleTrigger implements Converter<SimpleT
|
||||
if(triggerCommandDTO.getSimpleTriggerInputDTO().getEndDate() != null)
|
||||
triggerTriggerBuilder.endAt(triggerCommandDTO.getSimpleTriggerInputDTO().getEndDate());
|
||||
|
||||
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
|
||||
.withIntervalInMilliseconds(triggerCommandDTO.getSimpleTriggerInputDTO().getRepeatInterval())
|
||||
.withRepeatCount(triggerCommandDTO.getSimpleTriggerInputDTO().getRepeatCount())
|
||||
.withMisfireHandlingInstructionNextWithRemainingCount();
|
||||
|
||||
setTheMisfireInstruction(triggerCommandDTO, scheduleBuilder);
|
||||
|
||||
SimpleTrigger newSimpleTrigger = triggerTriggerBuilder.withSchedule(
|
||||
SimpleScheduleBuilder.simpleSchedule()
|
||||
.withIntervalInMilliseconds(triggerCommandDTO.getSimpleTriggerInputDTO().getRepeatInterval())
|
||||
.withRepeatCount(triggerCommandDTO.getSimpleTriggerInputDTO().getRepeatCount())
|
||||
.withMisfireHandlingInstructionNextWithRemainingCount()
|
||||
scheduleBuilder
|
||||
)
|
||||
.withIdentity(triggerCommandDTO.getTriggerName())
|
||||
.build();
|
||||
.withIdentity(triggerCommandDTO.getTriggerName()).build();
|
||||
|
||||
return newSimpleTrigger;
|
||||
}
|
||||
|
||||
private static void setTheMisfireInstruction(SimpleTriggerCommandDTO triggerCommandDTO, SimpleScheduleBuilder scheduleBuilder) {
|
||||
switch (triggerCommandDTO.getSimpleTriggerInputDTO().getMisfireInstruction()){
|
||||
case MISFIRE_INSTRUCTION_FIRE_NOW:
|
||||
scheduleBuilder.withMisfireHandlingInstructionFireNow();
|
||||
break;
|
||||
case MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT:
|
||||
scheduleBuilder.withMisfireHandlingInstructionNowWithExistingCount();
|
||||
break;
|
||||
case MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT:
|
||||
scheduleBuilder.withMisfireHandlingInstructionNowWithRemainingCount();
|
||||
break;
|
||||
case MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT:
|
||||
scheduleBuilder.withMisfireHandlingInstructionNextWithRemainingCount();
|
||||
break;
|
||||
case MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT:
|
||||
scheduleBuilder.withMisfireHandlingInstructionNextWithExistingCount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public class SimpleTriggerToSimpleTriggerDTO extends TriggerToTriggerDTO<SimpleT
|
||||
target.setTimesTriggered(source.getTimesTriggered());
|
||||
target.setRepeatCount(source.getRepeatCount());
|
||||
target.setRepeatInterval(source.getRepeatInterval());
|
||||
target.setMisfireInstruction(source.getMisfireInstruction());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package it.fabioformosa.quartzmanager.api.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum MisfireInstruction {
|
||||
MISFIRE_INSTRUCTION_FIRE_NOW(1),
|
||||
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT(2),
|
||||
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT(3),
|
||||
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT(4),
|
||||
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT(5);
|
||||
|
||||
@Getter
|
||||
private int num;
|
||||
|
||||
MisfireInstruction(int num) {
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
static public MisfireInstruction parseInt(int num) {
|
||||
return Arrays.stream(MisfireInstruction.values())
|
||||
.filter(misfireInstruction -> misfireInstruction.getNum() == num)
|
||||
.findFirst().orElseThrow(() -> new IllegalArgumentException(num + " is not a valid misfire instruction code!"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,4 +23,7 @@ public class TriggerCommandDTO {
|
||||
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||
private Date endDate;
|
||||
|
||||
private MisfireInstruction misfireInstruction = MisfireInstruction.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT;
|
||||
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
<groupId>it.fabioformosa.quartz-manager</groupId>
|
||||
<artifactId>quartz-manager-starter-ui</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>it.fabioformosa.quartz-manager</groupId>
|
||||
<artifactId>quartz-manager-starter-security</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>it.fabioformosa.quartz-manager</groupId>-->
|
||||
<!-- <artifactId>quartz-manager-starter-security</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>it.fabioformosa.quartz-manager</groupId>-->
|
||||
<!-- <artifactId>quartz-manager-starter-persistence</artifactId>-->
|
||||
|
||||
Reference in New Issue
Block a user