Search in sources :

Example 1 with TimerPrimaryKey

use of com.sun.ejb.containers.TimerPrimaryKey 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 2 with TimerPrimaryKey

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

the class HazelcastTimerStore method destroyAllTimers.

@Override
public void destroyAllTimers(long applicationId) {
    // remove all timers
    Set<TimerPrimaryKey> timerIds = (Set<TimerPrimaryKey>) applicationCache.get(applicationId);
    if (timerIds == null || timerIds.isEmpty()) {
        if (logger.isLoggable(Level.INFO)) {
            logger.log(Level.INFO, "No timers to be deleted for id: " + applicationId);
        }
        return;
    }
    for (TimerPrimaryKey timerId : timerIds) {
        pkCache.remove(timerId.timerId);
    }
    logger.log(Level.INFO, "Destroyed {0} timers for application {1}", new Object[] { timerIds.size(), applicationId });
    timerIds.clear();
    applicationCache.remove(applicationId);
}
Also used : TimerPrimaryKey(com.sun.ejb.containers.TimerPrimaryKey) HashSet(java.util.HashSet) Set(java.util.Set)

Example 3 with TimerPrimaryKey

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

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

the class HazelcastTimerStore method getTimerIds.

@Override
protected Collection<TimerPrimaryKey> getTimerIds(long containerId, Object timedObjectPrimaryKey) {
    // The results should include all timers for the given ejb
    // and/or primary key, including timers owned by other server instances.
    // @@@ Might want to consider cases where we can use
    // timer cache to avoid some database access in PE/SE, or
    // even in EE with the appropriate consistency tradeoff.
    Collection<TimerPrimaryKey> timerIdsForTimedObject = new HashSet<TimerPrimaryKey>();
    if (timedObjectPrimaryKey == null) {
        Collection<TimerPrimaryKey> contKeys = (Collection<TimerPrimaryKey>) containerCache.get(containerId);
        if (contKeys != null) {
            timerIdsForTimedObject.addAll(contKeys);
        }
    } else {
        Collection<TimerPrimaryKey> timersForTimedObject = (Collection<TimerPrimaryKey>) containerCache.get(containerId);
        if (timersForTimedObject != null) {
            for (TimerPrimaryKey timer : timersForTimedObject) {
                HZTimer hzTimer = (HZTimer) pkCache.get(timer.timerId);
                if (hzTimer != null && hzTimer.getTimedObjectPk().equals(timedObjectPrimaryKey)) {
                    timerIdsForTimedObject.add(timer);
                }
            }
        }
    }
    // Add active non-persistent timer ids
    timerIdsForTimedObject.addAll(super.getTimerIds(containerId, null));
    return timerIdsForTimedObject;
}
Also used : TimerPrimaryKey(com.sun.ejb.containers.TimerPrimaryKey) Collection(java.util.Collection) HashSet(java.util.HashSet)

Example 5 with TimerPrimaryKey

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

the class PersistentEJBTimerService method getTimerIds.

/**
 * Use database query to retrieve persistrent timer ids of all active
 * timers.  Results must be transactionally consistent. E.g.,
 * a client calling getTimerIds within a transaction where a
 * timer has been created but not committed "sees" the timer
 * but a client in a different transaction doesn't. Called by
 * EJBTimerServiceWrapper when caller calls getTimers.
 *
 * @param timedObjectPrimaryKey can be null if not entity bean
 * @return Collection of Timer Ids.
 */
@Override
protected Collection<TimerPrimaryKey> getTimerIds(long containerId, Object timedObjectPrimaryKey) {
    // The results should include all timers for the given ejb
    // and/or primary key, including timers owned by other server instances.
    // @@@ Might want to consider cases where we can use
    // timer cache to avoid some database access in PE/SE, or
    // even in EE with the appropriate consistency tradeoff.
    Collection<TimerPrimaryKey> timerIdsForTimedObject = new HashSet<TimerPrimaryKey>();
    if (timedObjectPrimaryKey == null) {
        timerIdsForTimedObject = timerLocal_.findActiveTimerIdsByContainer(containerId);
    } else {
        // Database query itself can't do equality check on primary
        // key of timed object so perform check ourselves.
        Collection<TimerState> timersForTimedObject = getTimers(containerId, timedObjectPrimaryKey);
        for (TimerState timer : timersForTimedObject) {
            timerIdsForTimedObject.add(getPrimaryKey(timer));
        }
    }
    // Add active non-persistent timer ids
    timerIdsForTimedObject.addAll(super.getTimerIds(containerId, null));
    return timerIdsForTimedObject;
}
Also used : TimerPrimaryKey(com.sun.ejb.containers.TimerPrimaryKey) RuntimeTimerState(com.sun.ejb.containers.RuntimeTimerState) HashSet(java.util.HashSet)

Aggregations

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