Search in sources :

Example 1 with RuntimeTimerState

use of com.sun.ejb.containers.RuntimeTimerState 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 RuntimeTimerState

use of com.sun.ejb.containers.RuntimeTimerState 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 RuntimeTimerState

use of com.sun.ejb.containers.RuntimeTimerState 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 RuntimeTimerState

use of com.sun.ejb.containers.RuntimeTimerState 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 RuntimeTimerState

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

the class PersistentEJBTimerService method resetLastExpiration.

/**
 * Update database for a persistent timer
 */
@Override
protected void resetLastExpiration(TimerPrimaryKey timerId, RuntimeTimerState timerState) {
    if (timerState.isPersistent()) {
        TimerState timer = getValidTimerFromDB(timerId);
        if (null == timer) {
            return;
        }
        Date now = new Date();
        timer.setLastExpiration(now);
        // @@@ add configuration for update-db-on-delivery
        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "Setting last expiration " + " for periodic timer " + timerState + " to " + now);
        }
    }
}
Also used : RuntimeTimerState(com.sun.ejb.containers.RuntimeTimerState) Date(java.util.Date)

Aggregations

RuntimeTimerState (com.sun.ejb.containers.RuntimeTimerState)6 Date (java.util.Date)6 EJBTimerSchedule (com.sun.ejb.containers.EJBTimerSchedule)5 BaseContainer (com.sun.ejb.containers.BaseContainer)3 TimerPrimaryKey (com.sun.ejb.containers.TimerPrimaryKey)3 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 Iterator (java.util.Iterator)3 Map (java.util.Map)3 IMap (com.hazelcast.core.IMap)2 Set (java.util.Set)1