Skip to content
Permalink
Browse files

implemented issue JPPF-587

  • Loading branch information...
lolocohen committed Jul 28, 2019
1 parent 38de3ab commit 25244ceb702ec6b2697e50bf1cecbe330d790424
BIN +309 Bytes (100%) JPPF/docs/manual/JPPF-User-Guide.odt
Binary file not shown.
@@ -20,6 +20,7 @@

import java.io.Serializable;
import java.text.*;
import java.time.*;
import java.util.Date;

/**
@@ -44,20 +45,26 @@
/**
* Schedule date format as a string.
*/
private String format;
private final String format;
/**
* Format describing the schedule date.
*/
private transient SimpleDateFormat dateFormat;
/**
* A date expressed as a {@link ZonedDateTime} instance.
*/
private final ZonedDateTime zonedDateTime;
/**
* A duration expressed as a {@link Duration} instance.
*/
private final Duration durationObject;

/**
* Initialize this schedule configuration with the specified duration.
* @param duration the duration in milliseconds.
*/
public JPPFSchedule(final long duration) {
this.duration = duration;
this.date = null;
this.format = null;
this(duration, null, null, null, null);
}

/**
@@ -67,9 +74,39 @@ public JPPFSchedule(final long duration) {
* as specified in the description of {@link SimpleDateFormat}.
*/
public JPPFSchedule(final String date, final String format) {
this.duration = 0L;
this(0L, date, format, null, null);
}

/**
* Initialize this schedule configuration with the specified date.
* @param zonedDateTime the schedule date.
*/
public JPPFSchedule(final ZonedDateTime zonedDateTime) {
this(0L, null, null, zonedDateTime, null);
}

/**
* Initialize this schedule configuration with the specified duration.
* @param duration the duration before this schedule expires or times out.
*/
public JPPFSchedule(final Duration duration) {
this(0L, null, null, null, duration);
}

/**
* Genric constructor invoked by all other constructors.
* @param duration the duration in milliseconds, or a value <= 0.
* @param date the schedule date provided as a string, or {@code null}.
* @param format the format in which the date is expressed, or {@code null}.
* @param zonedDateTime the schedule date and time, or {@code null}.
* @param durationObject the duration before this schedule expires or times out, or {@code null}.
*/
private JPPFSchedule(final long duration, final String date, final String format, final ZonedDateTime zonedDateTime, final Duration durationObject) {
this.duration = duration;
this.date = date;
this.format = format;
this.zonedDateTime = zonedDateTime;
this.durationObject = durationObject;
}

/**
@@ -98,11 +135,28 @@ public String getFormat() {
return format;
}

/**
* Get the schedule date expressed as a {@link ZonedDateTime} instance.
* @return a {@link ZonedDateTime} if this schedule was constructed with a {@link ZonedDateTime}, otherwise {@code null}.
*/
public ZonedDateTime getZonedDateTime() {
return zonedDateTime;
}

/**
* Get the schedule duration expressed as a {@link Duration} instance.
* @return a {@link Duration} if this schedule was constructed with a a {@link Duration}, otherwise {@code null}.
*/
public Duration getDurationObject() {
return durationObject;
}

/**
* Convert this schedule to a {@link Date} object.
* @param startDate the starting date to use if the schedule is expressed as a duration.
* @return this schedule expressed as a {@link Date}.
* @throws ParseException if parsing using the simple date format fails.
* @deprecated use {@link #toLong(long) toLong(long startDate)} instead.
*/
public Date toDate(final long startDate) throws ParseException {
Date dt = null;
@@ -122,37 +176,57 @@ public Date toDate(final long startDate) throws ParseException {
*/
public long toLong(final long startDate) throws ParseException {
long result = 0L;
if ((date == null) || (format == null)) result = startDate + duration;
else {
if (duration > 0L) result = startDate + duration;
else if ((date != null) && (format != null)) {
if (dateFormat == null) dateFormat = new SimpleDateFormat(format);
final Date dt = dateFormat.parse(date);
result = dt.getTime();
}
else if (zonedDateTime != null) result = zonedDateTime.toInstant().toEpochMilli();
else if (durationObject != null) result = startDate + durationObject.toMillis();
return result;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("schedule[");
final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
if (date != null) sb.append("date=").append(date).append(", format=").append(format == null ? "null" : format);
else sb.append("delay=").append(duration);
else if (duration > 0L) sb.append("delay=").append(duration);
else if (zonedDateTime != null) sb.append("date=").append(zonedDateTime);
else if (durationObject != null) sb.append("delay=").append(durationObject);
sb.append(']');
return sb.toString();
}

/**
* Determine whether this schedule was initialized with a date or not.
* @return true if a date was specified when constructing this schedule, false otherwise.
* Determine whether this schedule was initialized with a {@link Date}.
* @return {@code true} if a {@link Date} was specified when constructing this schedule, {@code false} otherwise.
*/
public boolean hasDate() {
return (date != null) && (format != null);
}

/**
* Determine whether this schedule was initialized with a duration or not.
* @return true if a duration (or timeout) was specified when constructing this schedule, false otherwise.
* Determine whether this schedule was initialized with a duration.
* @return {@code true} if a {@code long} duration was specified when constructing this schedule, {@code false} otherwise.
*/
public boolean hasDuration() {
return duration > 0;
}

/**
* Determine whether this schedule was initialized with a {@link ZonedDateTime}.
* @return {@code true} if a {@link ZonedDateTime} was specified when constructing this schedule, {@code false} otherwise.
*/
public boolean hasZonedDateTime() {
return zonedDateTime != null;
}

/**
* Determine whether this schedule was initialized with a {@link Duration}.
* @return {@code true} if a {@link Duration} was specified when constructing this schedule, {@code false} otherwise.
*/
public boolean hasDurationObject() {
return durationObject != null;
}
}
@@ -103,12 +103,12 @@ public void scheduleAction(final Object key, final JPPFSchedule schedule, final
log.debug(name + " : scheduling action[key=" + key + ", " + schedule + ", action=" + action + ", start=" + sdf.format(new Date(start)));
}
}
final Date date = schedule.toDate(start);
final ScheduledFuture<?> future = executor.schedule(action, date.getTime() - start, TimeUnit.MILLISECONDS);
final long epoch = schedule.toLong(start);
final ScheduledFuture<?> future = executor.schedule(new ScheduledAction(key, action), epoch - start, TimeUnit.MILLISECONDS);
futureMap.put(key, future);
if (debugEnabled) {
synchronized(sdf) {
log.debug(name + " : date=" + sdf.format(date) + ", key=" + key + ", future=" + future);
log.debug(name + " : date=" + sdf.format(new Date(schedule.toLong(start))) + ", key=" + key + ", future=" + future);
}
}
}
@@ -154,10 +154,9 @@ public void clear() {
* @param shutdown flag indicating whether this schedule handler should be shutdown.
*/
public void clear(final boolean shutdown) {
for (final Map.Entry<Object, ScheduledFuture<?>> entry: futureMap.entrySet()) {
final ScheduledFuture<?> f = entry.getValue();
if (f != null) f.cancel(true);
}
futureMap.forEach((key, future) -> {
if (future != null) future.cancel(true);
});
futureMap.clear();
if (shutdown) executor.shutdownNow();
}
@@ -169,4 +168,34 @@ private void createExecutor() {
executor = Executors.newScheduledThreadPool(1, new JPPFThreadFactory(this.name));
if (debugEnabled) log.debug("created executor with name=" + name);
}

/**
*
*/
private final class ScheduledAction implements Runnable {
/**
* The key associated with the action.
*/
private final Object key;
/**
* The action to run upon expiration.
*/
private final Runnable action;

/**
* Initialize this scheduled action.
* @param key the key associated with the action.
* @param action the action to run upon expiration.
*/
private ScheduledAction(final Object key, final Runnable action) {
this.key = key;
this.action = action;
}

@Override
public void run() {
futureMap.remove(key);
action.run();
}
}
}

0 comments on commit 25244ce

Please sign in to comment.
You can’t perform that action at this time.