Search in sources :

Example 1 with EJBTimerSchedule

use of com.sun.ejb.containers.EJBTimerSchedule in project Payara by payara.

the class PersistentEJBTimerService method getNextTimeout.

@Override
protected Date getNextTimeout(TimerPrimaryKey timerId) throws FinderException {
    // Check non-persistent timers first
    RuntimeTimerState rt = getNonPersistentTimer(timerId);
    if (rt != null) {
        return _getNextTimeout(rt);
    }
    // It's a persistent timer
    // @@@ We can't assume this server instance owns the persistent timer
    // so always ask the database.  Investigate possible use of
    // timer cache for optimization.
    TimerState timer = getPersistentTimer(timerId);
    Date initialExpiration = timer.getInitialExpiration();
    long intervalDuration = timer.getIntervalDuration();
    EJBTimerSchedule ts = timer.getTimerSchedule();
    Date nextTimeout = null;
    if (ts != null) {
        nextTimeout = getNextScheduledTimeout(ts);
    // The caller is responsible to return 0 or -1 for the time remaining....
    } else if (intervalDuration > 0) {
        nextTimeout = calcNextFixedRateExpiration(initialExpiration, intervalDuration);
    } else {
        nextTimeout = initialExpiration;
    }
    return nextTimeout;
}
Also used : RuntimeTimerState(com.sun.ejb.containers.RuntimeTimerState) EJBTimerSchedule(com.sun.ejb.containers.EJBTimerSchedule) RuntimeTimerState(com.sun.ejb.containers.RuntimeTimerState) Date(java.util.Date)

Example 2 with EJBTimerSchedule

use of com.sun.ejb.containers.EJBTimerSchedule in project Payara by payara.

the class HazelcastTimerStore method _restoreTimers.

/**
 * The portion of timer restoration that deals with registering the JDK
 * timer tasks and checking for missed expirations.
 *
 * @return the Set of restored timers
 */
private Set<HZTimer> _restoreTimers(Set<HZTimer> timersEligibleForRestoration) {
    // Do timer restoration in two passes.  The first pass updates
    // the timer cache with each timer.  The second pass schedules
    // the JDK timer tasks.
    Map timersToRestore = new HashMap();
    Set<TimerPrimaryKey> timerIdsToRemove = new HashSet<>();
    Set<HZTimer> result = new HashSet<HZTimer>();
    for (HZTimer timer : timersEligibleForRestoration) {
        TimerPrimaryKey timerId = timer.getKey();
        if (getTimerState(timerId) != null) {
            // Already restored. Add it to the result but do nothing else.
            logger.log(Level.FINE, "@@@ Timer already restored: " + timer);
            result.add(timer);
            continue;
        }
        long containerId = timer.getContainerId();
        // Timer might refer to an obsolete container.
        BaseContainer container = getContainer(containerId);
        if (container != null) {
            // Update applicationId if it is null (from previous version)
            long appid = timer.getApplicationId();
            if (appid == 0) {
                timer.setApplicationId(container.getApplicationId());
            }
            // End update
            Date initialExpiration = timer.getInitialExpiration();
            // Create an instance of RuntimeTimerState.
            // Only access timedObjectPrimaryKey if timed object is
            // an entity bean.  That allows us to lazily load the underlying
            // blob for stateless session and message-driven bean timers.
            Object timedObjectPrimaryKey = null;
            if (container.getContainerType() == BaseContainer.ContainerType.ENTITY) {
                timedObjectPrimaryKey = timer.getTimedObjectPk();
            }
            RuntimeTimerState timerState = new RuntimeTimerState(timerId, initialExpiration, timer.getIntervalDuration(), container, timedObjectPrimaryKey, timer.getSchedule(), // Don't need to store the info ref for persistent timer
            null, true);
            timerCache_.addTimer(timerId, timerState);
            // If a single-action timer is still in the database it never
            // successfully delivered, so always reschedule a timer task
            // for it.  For periodic timers, we use the last known
            // expiration time to decide whether we need to fire one
            // ejbTimeout to make up for any missed ones.
            Date expirationTime = initialExpiration;
            Date now = new Date();
            if (timerState.isPeriodic()) {
                // lastExpiration time, or null if we either aren't
                // tracking last expiration or an expiration hasn't
                // occurred yet for this timer.
                Date lastExpiration = timer.getLastExpiration();
                EJBTimerSchedule ts = timer.getSchedule();
                // timer expirations.
                if ((lastExpiration == null) && now.after(initialExpiration)) {
                    if (!timerState.isExpired()) {
                        // This timer didn't even expire one time.
                        logger.log(Level.INFO, "Rescheduling missed expiration for " + "periodic timer " + timerState + ". Timer expirations should " + " have been delivered starting at " + initialExpiration);
                    }
                // keep expiration time at initialExpiration.  That
                // will force an ejbTimeout almost immediately. After
                // that the timer will return to fixed rate expiration.
                } else if ((lastExpiration != null) && ((ts != null && ts.getNextTimeout(lastExpiration).getTimeInMillis() < now.getTime()) || ((ts == null) && now.getTime() - lastExpiration.getTime() > timer.getIntervalDuration()))) {
                    // Schedule-based timer is periodic
                    logger.log(Level.INFO, "Rescheduling missed expiration for " + "periodic timer " + timerState + ".  Last timer expiration " + "occurred at " + lastExpiration);
                // Timer expired at least once and at least one
                // missed expiration has occurred.
                // keep expiration time at initialExpiration.  That
                // will force an ejbTimeout almost immediately. After
                // that the timer will return to fixed rate expiration.
                } else {
                    // In this case, at least one expiration has occurred
                    // but that was less than one period ago so there were
                    // no missed expirations.
                    expirationTime = calcNextFixedRateExpiration(timerState);
                }
            } else // single-action timer
            if (now.after(initialExpiration)) {
                logger.log(Level.INFO, "Rescheduling missed expiration for " + "single-action timer " + timerState + ". Timer expiration should " + " have been delivered at " + initialExpiration);
            }
            if (expirationTime == null) {
                // Schedule-based timer will never expire again - remove it.
                logger.log(Level.INFO, "Removing schedule-based timer " + timerState + " that will never expire again");
                timerIdsToRemove.add(timerId);
            } else {
                timersToRestore.put(timerState, expirationTime);
                result.add(timer);
            }
        } else {
            // Timed object's container no longer exists - remember its id.
            logger.log(Level.FINE, "Skipping timer " + timerId + " for container that is not up: " + containerId);
        }
    }
    if (timerIdsToRemove.size() > 0) {
        removeTimers(timerIdsToRemove);
    }
    for (Iterator entries = timersToRestore.entrySet().iterator(); entries.hasNext(); ) {
        Map.Entry next = (Map.Entry) entries.next();
        RuntimeTimerState nextTimer = (RuntimeTimerState) next.getKey();
        TimerPrimaryKey timerId = nextTimer.getTimerId();
        Date expiration = (Date) next.getValue();
        scheduleTask(timerId, expiration);
        logger.log(Level.FINE, "EJBTimerService.restoreTimers(), scheduling timer " + nextTimer);
    }
    logger.log(Level.FINE, "DONE EJBTimerService.restoreTimers()");
    return result;
}
Also used : TimerPrimaryKey(com.sun.ejb.containers.TimerPrimaryKey) RuntimeTimerState(com.sun.ejb.containers.RuntimeTimerState) HashMap(java.util.HashMap) EJBTimerSchedule(com.sun.ejb.containers.EJBTimerSchedule) Date(java.util.Date) BaseContainer(com.sun.ejb.containers.BaseContainer) Iterator(java.util.Iterator) HashMap(java.util.HashMap) Map(java.util.Map) IMap(com.hazelcast.core.IMap) HashSet(java.util.HashSet)

Example 3 with EJBTimerSchedule

use of com.sun.ejb.containers.EJBTimerSchedule in project Payara by payara.

the class HazelcastTimerStore method _restoreTimers.

/**
 * The portion of timer restoration that deals with registering the JDK
 * timer tasks and checking for missed expirations.
 *
 * @return the Set of restored timers
 */
private Collection<HZTimer> _restoreTimers(Collection<HZTimer> timersEligibleForRestoration) {
    // Do timer restoration in two passes.  The first pass updates
    // the timer cache with each timer.  The second pass schedules
    // the JDK timer tasks.
    Map timersToRestore = new HashMap();
    Set<TimerPrimaryKey> timerIdsToRemove = new HashSet<>();
    Set<HZTimer> result = new HashSet<HZTimer>();
    for (HZTimer timer : timersEligibleForRestoration) {
        TimerPrimaryKey timerId = timer.getKey();
        if (getTimerState(timerId) != null) {
            // Already restored. Add it to the result but do nothing else.
            logger.log(Level.FINE, "@@@ Timer already restored: " + timer);
            result.add(timer);
            continue;
        }
        long containerId = timer.getContainerId();
        // Timer might refer to an obsolete container.
        BaseContainer container = getContainer(containerId);
        if (container != null) {
            // Update applicationId if it is null (from previous version)
            long appid = timer.getApplicationId();
            if (appid == 0) {
                timer.setApplicationId(container.getApplicationId());
            }
            // End update
            Date initialExpiration = timer.getInitialExpiration();
            // Create an instance of RuntimeTimerState.
            // Only access timedObjectPrimaryKey if timed object is
            // an entity bean.  That allows us to lazily load the underlying
            // blob for stateless session and message-driven bean timers.
            Object timedObjectPrimaryKey = null;
            if (container.getContainerType() == BaseContainer.ContainerType.ENTITY) {
                timedObjectPrimaryKey = timer.getTimedObjectPk();
            }
            RuntimeTimerState timerState = new RuntimeTimerState(timerId, initialExpiration, timer.getIntervalDuration(), container, timedObjectPrimaryKey, timer.getSchedule(), // Don't need to store the info ref for persistent timer
            null, true);
            timerCache_.addTimer(timerId, timerState);
            // If a single-action timer is still in the database it never
            // successfully delivered, so always reschedule a timer task
            // for it.  For periodic timers, we use the last known
            // expiration time to decide whether we need to fire one
            // ejbTimeout to make up for any missed ones.
            Date expirationTime = initialExpiration;
            Date now = new Date();
            if (timerState.isPeriodic()) {
                // lastExpiration time, or null if we either aren't
                // tracking last expiration or an expiration hasn't
                // occurred yet for this timer.
                Date lastExpiration = timer.getLastExpiration();
                EJBTimerSchedule ts = timer.getSchedule();
                // timer expirations.
                if ((lastExpiration == null) && now.after(initialExpiration)) {
                    if (!timerState.isExpired()) {
                        // This timer didn't even expire one time.
                        logger.log(Level.INFO, "Rescheduling missed expiration for " + "periodic timer " + timerState + ". Timer expirations should " + " have been delivered starting at " + initialExpiration);
                    }
                // keep expiration time at initialExpiration.  That
                // will force an ejbTimeout almost immediately. After
                // that the timer will return to fixed rate expiration.
                } else if ((lastExpiration != null) && ((ts != null && ts.getNextTimeout(lastExpiration).getTimeInMillis() < now.getTime()) || ((ts == null) && now.getTime() - lastExpiration.getTime() > timer.getIntervalDuration()))) {
                    // Schedule-based timer is periodic
                    logger.log(Level.INFO, "Rescheduling missed expiration for " + "periodic timer " + timerState + ".  Last timer expiration " + "occurred at " + lastExpiration);
                // Timer expired at least once and at least one
                // missed expiration has occurred.
                // keep expiration time at initialExpiration.  That
                // will force an ejbTimeout almost immediately. After
                // that the timer will return to fixed rate expiration.
                } else {
                    // In this case, at least one expiration has occurred
                    // but that was less than one period ago so there were
                    // no missed expirations.
                    expirationTime = calcNextFixedRateExpiration(timerState);
                }
            } else // single-action timer
            if (now.after(initialExpiration)) {
                logger.log(Level.INFO, "Rescheduling missed expiration for " + "single-action timer " + timerState + ". Timer expiration should " + " have been delivered at " + initialExpiration);
            }
            if (expirationTime == null) {
                // Schedule-based timer will never expire again - remove it.
                logger.log(Level.INFO, "Removing schedule-based timer " + timerState + " that will never expire again");
                timerIdsToRemove.add(timerId);
            } else {
                timersToRestore.put(timerState, expirationTime);
                result.add(timer);
            }
        } else {
            // Timed object's container no longer exists - remember its id.
            logger.log(Level.FINE, "Skipping timer " + timerId + " for container that is not up: " + containerId);
        }
    }
    if (timerIdsToRemove.size() > 0) {
        for (HZTimer hZTimer : result) {
        }
        removeTimers(timerIdsToRemove);
    }
    for (Iterator entries = timersToRestore.entrySet().iterator(); entries.hasNext(); ) {
        Map.Entry next = (Map.Entry) entries.next();
        RuntimeTimerState nextTimer = (RuntimeTimerState) next.getKey();
        TimerPrimaryKey timerId = nextTimer.getTimerId();
        Date expiration = (Date) next.getValue();
        scheduleTask(timerId, expiration);
        logger.log(Level.FINE, "EJBTimerService.restoreTimers(), scheduling timer " + nextTimer);
    }
    logger.log(Level.FINE, "DONE EJBTimerService.restoreTimers()");
    return result;
}
Also used : TimerPrimaryKey(com.sun.ejb.containers.TimerPrimaryKey) RuntimeTimerState(com.sun.ejb.containers.RuntimeTimerState) HashMap(java.util.HashMap) EJBTimerSchedule(com.sun.ejb.containers.EJBTimerSchedule) Date(java.util.Date) BaseContainer(com.sun.ejb.containers.BaseContainer) Iterator(java.util.Iterator) HashMap(java.util.HashMap) Map(java.util.Map) IMap(com.hazelcast.core.IMap) HashSet(java.util.HashSet)

Example 4 with EJBTimerSchedule

use of com.sun.ejb.containers.EJBTimerSchedule in project Payara by payara.

the class HazelcastTimerStore method getNextTimeout.

@Override
protected Date getNextTimeout(TimerPrimaryKey timerId) throws FinderException {
    // Check non-persistent timers first
    RuntimeTimerState rt = getNonPersistentTimer(timerId);
    if (rt != null) {
        return _getNextTimeout(rt);
    }
    // It's a persistent timer
    HZTimer timer = getPersistentTimer(timerId);
    Date initialExpiration = timer.getInitialExpiration();
    long intervalDuration = timer.getIntervalDuration();
    EJBTimerSchedule ts = timer.getSchedule();
    Date nextTimeout = null;
    if (ts != null) {
        nextTimeout = getNextScheduledTimeout(ts);
    // The caller is responsible to return 0 or -1 for the time remaining....
    } else if (intervalDuration > 0) {
        nextTimeout = calcNextFixedRateExpiration(initialExpiration, intervalDuration);
    } else {
        nextTimeout = initialExpiration;
    }
    return nextTimeout;
}
Also used : RuntimeTimerState(com.sun.ejb.containers.RuntimeTimerState) EJBTimerSchedule(com.sun.ejb.containers.EJBTimerSchedule) Date(java.util.Date)

Example 5 with EJBTimerSchedule

use of com.sun.ejb.containers.EJBTimerSchedule in project Payara by payara.

the class PersistentEJBTimerService method recoverAndCreateSchedules.

/**
 * Recover pre-existing timers associated with the Container identified
 * by the containerId, and create automatic timers defined by the @Schedule
 * annotation on the EJB bean.
 *
 * If it is called from deploy on a non-clustered instance, both
 * persistent and non-persistent timers will be created.
 * Otherwise only non-persistent timers are created by this method.
 *
 * @return a Map of both, restored and created timers, where the key is TimerPrimaryKey
 * and the value is the Method to be executed by the container when the timer with
 * this PK times out.
 */
@Override
protected Map<TimerPrimaryKey, Method> recoverAndCreateSchedules(long containerId, long applicationId, Map<Method, List<ScheduledTimerDescriptor>> schedules, boolean deploy) {
    Map<TimerPrimaryKey, Method> result = new HashMap<TimerPrimaryKey, Method>();
    TransactionManager tm = ejbContainerUtil.getTransactionManager();
    try {
        tm.begin();
        Set<TimerState> timers = _restoreTimers((Set<TimerState>) timerLocal_.findActiveTimersOwnedByThisServerByContainer(containerId));
        if (timers.size() > 0) {
            logger.log(Level.FINE, "Found " + timers.size() + " persistent timers for containerId: " + containerId);
        }
        boolean schedulesExist = (schedules.size() > 0);
        for (TimerState timer : timers) {
            EJBTimerSchedule ts = timer.getTimerSchedule();
            if (ts != null && ts.isAutomatic() && schedulesExist) {
                for (Map.Entry<Method, List<ScheduledTimerDescriptor>> entry : schedules.entrySet()) {
                    Method m = entry.getKey();
                    if (m.getName().equals(ts.getTimerMethodName()) && m.getParameterTypes().length == ts.getMethodParamCount()) {
                        result.put(new TimerPrimaryKey(timer.getTimerId()), m);
                        if (logger.isLoggable(Level.FINE)) {
                            logger.log(Level.FINE, "@@@ FOUND existing schedule: " + ts.getScheduleAsString() + " FOR method: " + m);
                        }
                    }
                }
            }
        }
        createSchedules(containerId, applicationId, schedules, result, ownerIdOfThisServer_, true, (deploy && isDas));
        tm.commit();
    } catch (Exception e) {
        recoverAndCreateSchedulesError(e, tm);
    }
    return result;
}
Also used : TimerPrimaryKey(com.sun.ejb.containers.TimerPrimaryKey) HashMap(java.util.HashMap) EJBTimerSchedule(com.sun.ejb.containers.EJBTimerSchedule) Method(java.lang.reflect.Method) PropertyVetoException(java.beans.PropertyVetoException) EJBException(javax.ejb.EJBException) FinderException(javax.ejb.FinderException) CreateException(javax.ejb.CreateException) TransactionManager(javax.transaction.TransactionManager) List(java.util.List) ArrayList(java.util.ArrayList) RuntimeTimerState(com.sun.ejb.containers.RuntimeTimerState) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

EJBTimerSchedule (com.sun.ejb.containers.EJBTimerSchedule)10 RuntimeTimerState (com.sun.ejb.containers.RuntimeTimerState)7 Date (java.util.Date)6 TimerPrimaryKey (com.sun.ejb.containers.TimerPrimaryKey)5 HashMap (java.util.HashMap)5 Map (java.util.Map)5 HashSet (java.util.HashSet)4 IMap (com.hazelcast.core.IMap)3 BaseContainer (com.sun.ejb.containers.BaseContainer)3 Iterator (java.util.Iterator)3 Method (java.lang.reflect.Method)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 EJBException (javax.ejb.EJBException)2 FinderException (javax.ejb.FinderException)2 PropertyVetoException (java.beans.PropertyVetoException)1 Collection (java.util.Collection)1 Set (java.util.Set)1 CreateException (javax.ejb.CreateException)1 PostLoad (javax.persistence.PostLoad)1