/** * Restores persisted timers, corresponding to this timerservice, which are eligible for any new * timeouts. * * <p>This includes timers whose {@link TimerState} is <b>neither</b> of the following: * * <ul> * <li>{@link TimerState#CANCELED} * <li>{@link TimerState#EXPIRED} * </ul> * * <p>All such restored timers will be schedule for their next timeouts. * * @param autoTimers */ public void restoreTimers(final List<ScheduleTimer> autoTimers) { // get the persisted timers which are considered active List<TimerImpl> restorableTimers = this.getActivePersistentTimers(); // timers are removed from the list as they are loaded final List<ScheduleTimer> newAutoTimers = new LinkedList<ScheduleTimer>(autoTimers); ROOT_LOGGER.debug( "Found " + restorableTimers.size() + " active persistentTimers for timedObjectId: " + getInvoker().getTimedObjectId()); // now "start" each of the restorable timer. This involves, moving the timer to an ACTIVE state // and scheduling the timer task for (final TimerImpl activeTimer : restorableTimers) { if (activeTimer.isAutoTimer()) { CalendarTimer calendarTimer = (CalendarTimer) activeTimer; boolean found = false; // so we know we have an auto timer. We need to try and match it up with the auto timers. ListIterator<ScheduleTimer> it = newAutoTimers.listIterator(); while (it.hasNext()) { ScheduleTimer timer = it.next(); final String methodName = timer.getMethod().getName(); final String[] params = new String[timer.getMethod().getParameterTypes().length]; for (int i = 0; i < timer.getMethod().getParameterTypes().length; ++i) { params[i] = timer.getMethod().getParameterTypes()[i].getName(); } if (doesTimeoutMethodMatch(calendarTimer.getTimeoutMethod(), methodName, params)) { // the timers have the same method. // now lets make sure the schedule is the same // and the timer does not change the persistence if (this.doesScheduleMatch( calendarTimer.getScheduleExpression(), timer.getScheduleExpression()) && timer.getTimerConfig().isPersistent()) { it.remove(); found = true; break; } } } if (!found) { activeTimer.setTimerState(TimerState.CANCELED); } else { startTimer(activeTimer); ROOT_LOGGER.debug("Started timer: " + activeTimer); } this.persistTimer(activeTimer, false); } else if (!ineligibleTimerStates.contains(activeTimer.getState())) { startTimer(activeTimer); } ROOT_LOGGER.debug("Started timer: " + activeTimer); } for (ScheduleTimer timer : newAutoTimers) { this.loadAutoTimer(timer.getScheduleExpression(), timer.getTimerConfig(), timer.getMethod()); } }
/** * Creates a calendar based {@link javax.ejb.Timer} * * @param schedule The {@link javax.ejb.ScheduleExpression} which will be used for creating * scheduled timer tasks for a calendar based timer * @param info {@link java.io.Serializable} info that will be made available through the newly * created timer's {@link javax.ejb.Timer#getInfo()} method * @param persistent True if the newly created timer has to be persistent * @return Returns the newly created timer * @throws IllegalArgumentException If the passed <code>schedule</code> is null * @throws IllegalStateException If this method was invoked during a lifecycle callback on the EJB */ private TimerImpl createCalendarTimer( ScheduleExpression schedule, Serializable info, boolean persistent, Method timeoutMethod) { if (this.isLifecycleCallbackInvocation() && !this.isSingletonBeanInvocation()) { throw EjbLogger.ROOT_LOGGER.failToCreateTimerDoLifecycle(); } if (schedule == null) { throw EjbLogger.ROOT_LOGGER.scheduleIsNull(); } // generate an id for the timer UUID uuid = UUID.randomUUID(); // create the timer TimerImpl timer = CalendarTimer.builder() .setAutoTimer(timeoutMethod != null) .setScheduleExprSecond(schedule.getSecond()) .setScheduleExprMinute(schedule.getMinute()) .setScheduleExprHour(schedule.getHour()) .setScheduleExprDayOfWeek(schedule.getDayOfWeek()) .setScheduleExprDayOfMonth(schedule.getDayOfMonth()) .setScheduleExprMonth(schedule.getMonth()) .setScheduleExprYear(schedule.getYear()) .setScheduleExprStartDate(schedule.getStart()) .setScheduleExprEndDate(schedule.getEnd()) .setScheduleExprTimezone(schedule.getTimezone()) .setTimeoutMethod(timeoutMethod) .setTimerState(TimerState.CREATED) .setId(uuid.toString()) .setPersistent(persistent) .setPrimaryKey(currentPrimaryKey()) .setTimedObjectId(getInvoker().getTimedObjectId()) .setInfo(info) .setNewTimer(true) .build(this); this.persistTimer(timer, true); // now "start" the timer. This involves, moving the timer to an ACTIVE state // and scheduling the timer task this.startTimer(timer); // return the timer return timer; }