mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 22:15:26 +00:00
bug 3533: deadlock in CompetitorDeregistrator: fixed by separating finding the events from revoking them
Change-Id: I52a0d149edcb89914e6847fd4c81f3796eb6f318
This commit is contained in:
1 parent
5ece6b257a
commit
b59db4943d
2 files changed
+29
-15
No files matched your search
Executable → Regular
+2
-1
@@ -28,7 +28,8 @@ public class CompetitorDeregistrationTest extends AbstractRegattaLogTrackingTest
|
||||
log.add(new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), author, competitor2));
|
||||
final CompetitorDeregistrator<RegattaLog, RegattaLogEvent, RegattaLogEventVisitor> deregistrator = new CompetitorDeregistrator<>(log,
|
||||
Collections.singleton(competitor2), author);
|
||||
deregistrator.analyze();
|
||||
final Set<RegattaLogEvent> events = deregistrator.analyze();
|
||||
deregistrator.deregister(events);
|
||||
final Set<Competitor> competitors = new CompetitorsInLogAnalyzer<>(log).analyze();
|
||||
assertEquals(1, competitors.size());
|
||||
assertSame(competitor, competitors.iterator().next());
|
||||
|
||||
+27
-14
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.abstractlog.shared.analyzing;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -14,14 +15,21 @@ import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* Generates events that close the events that are responsible for the {@link #mapping} that is passed to the
|
||||
* constructor.
|
||||
* Finds the competitor registration events for a given set of {@link Competitor competitors} that must be
|
||||
* {@link AbstractLog#revokeEvent(AbstractLogEventAuthor, AbstractLogEvent) revoked} in order to deregister the
|
||||
* competitors. Note that the de-registration cannot be performed during analysis because
|
||||
* {@link BaseLogAnalyzer#analyze()} obtains a read lock on the log whereas
|
||||
* {@link AbstractLog#revokeEvent(AbstractLogEventAuthor, AbstractLogEvent)} requires a write lock, and upgrading from a
|
||||
* read to a write lock is not possible.<p>
|
||||
*
|
||||
* Clients must call {@link #deregister} with the result of {@link #analyze()} in order to actually perform the
|
||||
* deregistration.
|
||||
*
|
||||
* @author Jan Bross
|
||||
*
|
||||
*/
|
||||
public class CompetitorDeregistrator<LogT extends AbstractLog<EventT, VisitorT>, EventT extends AbstractLogEvent<VisitorT>, VisitorT>
|
||||
extends BaseLogAnalyzer<LogT, EventT, VisitorT, Void> {
|
||||
extends BaseLogAnalyzer<LogT, EventT, VisitorT, Set<EventT>> {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CompetitorDeregistrator.class.getName());
|
||||
protected final Iterable<Competitor> competitorsToDeregister;
|
||||
@@ -34,24 +42,29 @@ extends BaseLogAnalyzer<LogT, EventT, VisitorT, Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void performAnalysis() {
|
||||
HashSet<Competitor> competitorSet = new HashSet<Competitor>();
|
||||
protected Set<EventT> performAnalysis() {
|
||||
final Set<EventT> result = new HashSet<>();
|
||||
final HashSet<Competitor> competitorSet = new HashSet<Competitor>();
|
||||
Util.addAll(competitorsToDeregister, competitorSet);
|
||||
|
||||
for (EventT event : log.getUnrevokedEventsDescending()) {
|
||||
if (event instanceof RegisterCompetitorEvent) {
|
||||
RegisterCompetitorEvent<?> registerEvent = (RegisterCompetitorEvent<?>) event;
|
||||
if (competitorSet.contains(registerEvent.getCompetitor())) {
|
||||
try {
|
||||
log.revokeEvent(eventAuthor, event,
|
||||
"unregistering competitor because no longer selected for registration");
|
||||
} catch (NotRevokableException e) {
|
||||
logger.log(Level.WARNING, "could not unregister competitor by adding RevokeEvent", e);
|
||||
}
|
||||
result.add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void deregister(final Set<EventT> competitorRegistrationEvents) {
|
||||
for (final EventT event : competitorRegistrationEvents) {
|
||||
try {
|
||||
log.revokeEvent(eventAuthor, event,
|
||||
"unregistering competitor because no longer selected for registration");
|
||||
} catch (NotRevokableException e) {
|
||||
logger.log(Level.WARNING, "could not unregister competitor by adding RevokeEvent", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user