use of org.jboss.as.ejb3.timerservice.TimerImpl in project wildfly by wildfly.
the class TimerServiceImpl method restoreTimers.
/**
* 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>
* <li>{@link TimerState#EXPIRED}</li>
* </ul>
* </p>
* <p>
* All such restored timers will be schedule for their next timeouts.
* </p>
*
* @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);
if (EJB3_TIMER_LOGGER.isDebugEnabled()) {
EJB3_TIMER_LOGGER.debug("Found " + restorableTimers.size() + " active persistentTimers for timedObjectId: " + getInvoker().getTimedObjectId());
}
// 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)) {
// 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 {
// ensure state switch to active if was TIMEOUT in the DB
// if the persistence is shared it must be ensured to not update
// timers of other nodes in the cluster
activeTimer.setTimerState(TimerState.ACTIVE);
}
this.persistTimer(activeTimer, false);
if (found) {
startTimer(activeTimer);
EJB3_TIMER_LOGGER.debugv("Started timer: {0}", activeTimer);
}
} else if (!ineligibleTimerStates.contains(activeTimer.getState())) {
startTimer(activeTimer);
}
EJB3_TIMER_LOGGER.debugv("Started timer: {0}", activeTimer);
}
for (ScheduleTimer timer : newAutoTimers) {
this.loadAutoTimer(timer.getScheduleExpression(), timer.getTimerConfig(), timer.getMethod());
}
}
use of org.jboss.as.ejb3.timerservice.TimerImpl in project wildfly by wildfly.
the class DatabaseTimerPersistence method loadActiveTimers.
@Override
public List<TimerImpl> loadActiveTimers(final String timedObjectId, final TimerServiceImpl timerService) {
if (!knownTimerIds.containsKey(timedObjectId)) {
// if the timedObjectId has not being deployed
EjbLogger.EJB3_TIMER_LOGGER.timerNotDeployed(timedObjectId);
return Collections.emptyList();
}
String loadTimer = sql.getProperty(LOAD_ALL_TIMERS);
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareStatement(loadTimer);
statement.setString(1, timedObjectId);
statement.setString(2, partition);
resultSet = statement.executeQuery();
final List<Holder> timers = new ArrayList<>();
while (resultSet.next()) {
String timerId = null;
try {
timerId = resultSet.getString(1);
final Holder timerImpl = timerFromResult(resultSet, timerService, timerId, null);
if (timerImpl != null) {
timers.add(timerImpl);
} else {
final String deleteTimer = sql.getProperty(DELETE_TIMER);
try (PreparedStatement deleteStatement = connection.prepareStatement(deleteTimer)) {
deleteStatement.setString(1, resultSet.getString(2));
deleteStatement.setString(2, timerId);
deleteStatement.setString(3, partition);
deleteStatement.execute();
}
}
} catch (Exception e) {
EjbLogger.EJB3_TIMER_LOGGER.timerReinstatementFailed(resultSet.getString(2), timerId, e);
}
}
synchronized (this) {
// ids should be always be not null
Set<String> ids = knownTimerIds.get(timedObjectId);
for (Holder timer : timers) {
ids.add(timer.timer.getId());
}
for (Holder timer : timers) {
if (timer.requiresReset) {
TimerImpl ret = timer.timer;
EjbLogger.DEPLOYMENT_LOGGER.loadedPersistentTimerInTimeout(ret.getId(), ret.getTimedObjectId());
if (ret.getNextExpiration() == null) {
ret.setTimerState(TimerState.CANCELED, null);
persistTimer(ret);
} else {
ret.setTimerState(TimerState.ACTIVE, null);
persistTimer(ret);
}
}
}
}
List<TimerImpl> ret = new ArrayList<>();
for (Holder timer : timers) {
ret.add(timer.timer);
}
return ret;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
safeClose(resultSet);
safeClose(statement);
safeClose(connection);
}
}
use of org.jboss.as.ejb3.timerservice.TimerImpl in project wildfly by wildfly.
the class LegacyFileStore method loadTimersFromFile.
static Map<String, TimerImpl> loadTimersFromFile(final String timedObjectId, final TimerServiceImpl timerService, String directory, MarshallerFactory factory, MarshallingConfiguration configuration) {
final Map<String, TimerImpl> timers = new HashMap<String, TimerImpl>();
Unmarshaller unmarshaller = null;
try {
final File file = new File(directory);
if (!file.exists()) {
// no timers exist yet
return timers;
} else if (!file.isDirectory()) {
EJB3_TIMER_LOGGER.failToRestoreTimers(file);
return timers;
}
File marker = new File(file, MIGRATION_MARKER);
if (marker.exists()) {
return timers;
}
unmarshaller = factory.createUnmarshaller(configuration);
for (File timerFile : file.listFiles()) {
if (timerFile.getName().endsWith(".xml")) {
continue;
}
FileInputStream in = null;
try {
in = new FileInputStream(timerFile);
unmarshaller.start(new InputStreamByteInput(in));
final TimerEntity entity = unmarshaller.readObject(TimerEntity.class);
// we load the legacy timer entity class, and turn it into a timer state
TimerImpl.Builder builder;
if (entity instanceof CalendarTimerEntity) {
CalendarTimerEntity c = (CalendarTimerEntity) entity;
final ScheduleExpression scheduleExpression = new ScheduleExpression();
scheduleExpression.second(c.getSecond()).minute(c.getMinute()).hour(c.getHour()).dayOfWeek(c.getDayOfWeek()).dayOfMonth(c.getDayOfMonth()).month(c.getMonth()).year(c.getYear()).start(c.getStartDate()).end(c.getEndDate()).timezone(c.getTimezone());
builder = CalendarTimer.builder().setScheduleExpression(scheduleExpression).setAutoTimer(c.isAutoTimer()).setTimeoutMethod(CalendarTimer.getTimeoutMethod(c.getTimeoutMethod(), timerService.getTimedObjectInvoker().getValue().getClassLoader()));
} else {
builder = TimerImpl.builder();
}
builder.setId(entity.getId()).setTimedObjectId(entity.getTimedObjectId()).setInitialDate(entity.getInitialDate()).setRepeatInterval(entity.getInterval()).setNextDate(entity.getNextDate()).setPreviousRun(entity.getPreviousRun()).setInfo(entity.getInfo()).setTimerState(entity.getTimerState()).setPersistent(true);
timers.put(entity.getId(), builder.build(timerService));
unmarshaller.finish();
} catch (Exception e) {
EJB3_TIMER_LOGGER.failToRestoreTimersFromFile(timerFile, e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
EJB3_TIMER_LOGGER.failToCloseFile(e);
}
}
}
}
if (!timers.isEmpty()) {
Files.write(marker.toPath(), new Date().toString().getBytes(StandardCharsets.UTF_8));
}
} catch (Exception e) {
EJB3_TIMER_LOGGER.failToRestoreTimersForObjectId(timedObjectId, e);
} finally {
VFSUtils.safeClose(unmarshaller);
}
return timers;
}
use of org.jboss.as.ejb3.timerservice.TimerImpl in project wildfly by wildfly.
the class FileTimerPersistence method persistTimer.
private void persistTimer(final TimerImpl timer, boolean newTimer) {
final Lock lock = getLock(timer.getTimedObjectId());
try {
final int status = ContextTransactionManager.getInstance().getStatus();
if (status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLEDBACK || status == Status.STATUS_ROLLING_BACK) {
// no need to persist anyway
return;
}
lock.lock();
if (status == Status.STATUS_NO_TRANSACTION || status == Status.STATUS_UNKNOWN || isBeforeCompletion() || status == Status.STATUS_COMMITTED) {
Map<String, TimerImpl> map = getTimers(timer.getTimedObjectId(), timer.getTimerService());
if (timer.getState() == TimerState.CANCELED || timer.getState() == TimerState.EXPIRED) {
map.remove(timer.getId());
writeFile(timer);
} else if (newTimer || map.containsKey(timer.getId())) {
// if it is not a new timer and is not in the map then it has
// been removed by another thread.
map.put(timer.getId(), timer);
writeFile(timer);
}
} else {
final String key = timerTransactionKey(timer);
Object existing = transactionSynchronizationRegistry.getValue().getResource(key);
// check is there is already a persist sync for this timer
if (existing == null) {
transactionSynchronizationRegistry.getValue().registerInterposedSynchronization(new PersistTransactionSynchronization(lock, key, newTimer));
}
// update the most recent version of the timer to be persisted
transactionSynchronizationRegistry.getValue().putResource(key, timer);
}
} catch (SystemException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
use of org.jboss.as.ejb3.timerservice.TimerImpl in project wildfly by wildfly.
the class FileTimerPersistence method mostRecentEntityVersion.
/**
* Returns either the loaded entity or the most recent version of the entity that has
* been persisted in this transaction.
*/
private TimerImpl mostRecentEntityVersion(final TimerImpl timerImpl) {
try {
final int status = ContextTransactionManager.getInstance().getStatus();
if (status == Status.STATUS_UNKNOWN || status == Status.STATUS_NO_TRANSACTION) {
return timerImpl;
}
final String key = timerTransactionKey(timerImpl);
TimerImpl existing = (TimerImpl) transactionSynchronizationRegistry.getValue().getResource(key);
return existing != null ? existing : timerImpl;
} catch (SystemException e) {
throw new RuntimeException(e);
}
}
Aggregations