ItEr57S15RecalculosConexionEscenarios: Do notifications asynchronously.
This commit is contained in:
parent
8b9221c439
commit
bc1ee4e33b
1 changed files with 128 additions and 22 deletions
|
|
@ -27,6 +27,11 @@ import java.util.Date;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.navalplanner.business.common.IAdHocTransactionService;
|
||||
|
|
@ -45,12 +50,15 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
|||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.zkoss.ganttz.adapters.IDomainAndBeansMapper;
|
||||
import org.zkoss.ganttz.data.GanttDiagramGraph;
|
||||
import org.zkoss.ganttz.data.Task;
|
||||
import org.zkoss.ganttz.data.GanttDiagramGraph.DeferedNotifier;
|
||||
import org.zkoss.ganttz.extensions.IContext;
|
||||
import org.zkoss.ganttz.util.LongOperationFeedback;
|
||||
import org.zkoss.ganttz.util.LongOperationFeedback.IBackGroundOperation;
|
||||
import org.zkoss.ganttz.util.LongOperationFeedback.IDesktopUpdate;
|
||||
import org.zkoss.ganttz.util.LongOperationFeedback.IDesktopUpdatesEmitter;
|
||||
import org.zkoss.ganttz.util.PreAndPostNotReentrantActionsWrapper.IAction;
|
||||
import org.zkoss.zk.ui.Desktop;
|
||||
import org.zkoss.zk.ui.util.Clients;
|
||||
|
||||
|
|
@ -99,6 +107,71 @@ public class ReassignCommand implements IReassignCommand {
|
|||
});
|
||||
}
|
||||
|
||||
private class NotBlockingDesktopUpdates implements
|
||||
IDesktopUpdatesEmitter<IDesktopUpdate>, Runnable {
|
||||
private BlockingQueue<IDesktopUpdate> queue = new LinkedBlockingQueue<IDesktopUpdate>();
|
||||
private final IDesktopUpdatesEmitter<IDesktopUpdate> original;
|
||||
|
||||
private final IDesktopUpdate END_MARK = new IDesktopUpdate() {
|
||||
|
||||
@Override
|
||||
public void doUpdate() {
|
||||
}
|
||||
};
|
||||
|
||||
NotBlockingDesktopUpdates(
|
||||
IDesktopUpdatesEmitter<IDesktopUpdate> original) {
|
||||
this.original = original;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doUpdate(IDesktopUpdate value) {
|
||||
queue.add(value);
|
||||
}
|
||||
|
||||
void finish() {
|
||||
queue.add(END_MARK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<IDesktopUpdate> batch = new ArrayList<IDesktopUpdate>();
|
||||
while (true) {
|
||||
batch.clear();
|
||||
IDesktopUpdate current = null;
|
||||
try {
|
||||
current = queue.take();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (current == END_MARK) {
|
||||
return;
|
||||
}
|
||||
batch.add(current);
|
||||
while ((current = queue.poll()) != null) {
|
||||
if (current == END_MARK) {
|
||||
break;
|
||||
}
|
||||
batch.add(current);
|
||||
}
|
||||
if (!batch.isEmpty()) {
|
||||
original
|
||||
.doUpdate(asOneUpdate(batch));
|
||||
}
|
||||
if (current == END_MARK) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IDesktopUpdate asOneUpdate(List<IDesktopUpdate> batch) {
|
||||
return and(batch.toArray(new IDesktopUpdate[0]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
|
||||
private IBackGroundOperation<IDesktopUpdate> reassignations(
|
||||
final IContext<TaskElement> context,
|
||||
final List<WithAssociatedEntity> reassignations) {
|
||||
|
|
@ -106,39 +179,63 @@ public class ReassignCommand implements IReassignCommand {
|
|||
|
||||
@Override
|
||||
public void doOperation(
|
||||
IDesktopUpdatesEmitter<IDesktopUpdate> updater) {
|
||||
final IDesktopUpdatesEmitter<IDesktopUpdate> updater) {
|
||||
updater.doUpdate(showStart(reassignations.size()));
|
||||
DeferedNotifier notifications = null;
|
||||
NotBlockingDesktopUpdates notBlockingDesktopUpdates = new NotBlockingDesktopUpdates(
|
||||
updater);
|
||||
Future<?> previousNotifications = executorService
|
||||
.submit(notBlockingDesktopUpdates);
|
||||
try {
|
||||
doReassignations(reassignations, updater);
|
||||
GanttDiagramGraph ganttDiagramGraph = context.getGanttDiagramGraph();
|
||||
notifications = ganttDiagramGraph
|
||||
.manualNotificationOn(doReassignations(
|
||||
ganttDiagramGraph, reassignations,
|
||||
notBlockingDesktopUpdates));
|
||||
} finally {
|
||||
updater.doUpdate(and(reloadCharts(context), showEnd()));
|
||||
notBlockingDesktopUpdates.finish();
|
||||
waitUntilFinish(previousNotifications);
|
||||
if (notifications != null) {
|
||||
// null if error
|
||||
updater.doUpdate(and(doNotifications(notifications),
|
||||
reloadCharts(context), showEnd()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void waitUntilFinish(Future<?> showingProgress){
|
||||
try {
|
||||
showingProgress.get();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void doReassignations(
|
||||
private IAction doReassignations(final GanttDiagramGraph diagramGraph,
|
||||
final List<WithAssociatedEntity> reassignations,
|
||||
IDesktopUpdatesEmitter<IDesktopUpdate> updater) {
|
||||
int i = 1;
|
||||
final int total = reassignations.size();
|
||||
for (final WithAssociatedEntity each : reassignations) {
|
||||
IDesktopUpdate notifyChanges = changesNotificatorFor(each.ganntTask);
|
||||
transactionService
|
||||
.runOnReadOnlyTransaction(reassignmentTransaction(each));
|
||||
updater.doUpdate(and(notifyChanges, showCompleted(i, total)));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
final IDesktopUpdatesEmitter<IDesktopUpdate> updater) {
|
||||
return new IAction() {
|
||||
|
||||
private IDesktopUpdate changesNotificatorFor(final Task ganttTask) {
|
||||
final Date previousBeginDate = ganttTask.getBeginDate();
|
||||
final long previousLength = ganttTask.getLengthMilliseconds();
|
||||
return new IDesktopUpdate() {
|
||||
@Override
|
||||
public void doUpdate() {
|
||||
ganttTask.fireChangesForPreviousValues(previousBeginDate,
|
||||
previousLength);
|
||||
public void doAction() {
|
||||
int i = 1;
|
||||
final int total = reassignations.size();
|
||||
for (final WithAssociatedEntity each : reassignations) {
|
||||
Task ganttTask = each.ganntTask;
|
||||
final Date previousBeginDate = ganttTask.getBeginDate();
|
||||
final long previousLength = ganttTask
|
||||
.getLengthMilliseconds();
|
||||
|
||||
transactionService
|
||||
.runOnReadOnlyTransaction(reassignmentTransaction(each));
|
||||
diagramGraph.enforceRestrictions(each.ganntTask);
|
||||
ganttTask.fireChangesForPreviousValues(previousBeginDate,
|
||||
previousLength);
|
||||
updater.doUpdate(showCompleted(i, total));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -171,6 +268,15 @@ public class ReassignCommand implements IReassignCommand {
|
|||
};
|
||||
}
|
||||
|
||||
private IDesktopUpdate doNotifications(final DeferedNotifier notifier) {
|
||||
return new IDesktopUpdate() {
|
||||
@Override
|
||||
public void doUpdate() {
|
||||
notifier.doNotifications();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IDesktopUpdate showEnd() {
|
||||
return new IDesktopUpdate() {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue