Refactor the Async Inline Caching Spring Geode Sample Spring Boot application (code).
Change the default AEQ batch size to 25 and enable AEQ batch conflation. Synchronize the Set of players (Golfers) and List of Pairings in the GolfTournament class. Add a getPlayers() method to the GolfTournament class returning the Golfers registered to play in the GolfTournament. Simply the isFinished() method in the GolfTournament class. Add the in(:Golfer) and signScorecard() methods to the GolfTournament.Pairing class. Rename the GolfTournamentService class to PgaTourService. Rename the GolfTournamentController class to GolferController.
This commit is contained in:
@@ -32,7 +32,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import example.app.caching.inline.async.client.model.GolfTournament;
|
||||
import example.app.caching.inline.async.client.model.support.GolfCourseBuilder;
|
||||
import example.app.caching.inline.async.client.model.support.GolferBuilder;
|
||||
import example.app.caching.inline.async.client.service.GolfTournamentService;
|
||||
import example.app.caching.inline.async.client.service.PgaTourService;
|
||||
import example.app.caching.inline.async.config.AsyncInlineCachingConfiguration;
|
||||
import example.app.caching.inline.async.config.AsyncInlineCachingRegionConfiguration;
|
||||
|
||||
@@ -55,8 +55,9 @@ import example.app.caching.inline.async.config.AsyncInlineCachingRegionConfigura
|
||||
* @see example.app.caching.inline.async.client.model.GolfCourse
|
||||
* @see example.app.caching.inline.async.client.model.GolfTournament
|
||||
* @see example.app.caching.inline.async.client.model.Golfer
|
||||
* @see example.app.caching.inline.async.client.service.GolfTournamentService
|
||||
* @see example.app.caching.inline.async.client.service.PgaTourService
|
||||
* @see example.app.caching.inline.async.config.AsyncInlineCachingConfiguration
|
||||
* @see example.app.caching.inline.async.config.AsyncInlineCachingRegionConfiguration
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@@ -74,7 +75,7 @@ public class BootGeodeAsyncInlineCachingClientApplication {
|
||||
static class GolfApplicationConfiguration {
|
||||
|
||||
@Bean
|
||||
ApplicationRunner runGolfTournament(GolfTournamentService golfTournamentService) {
|
||||
ApplicationRunner runGolfTournament(PgaTourService pgaTourService) {
|
||||
|
||||
return args -> {
|
||||
|
||||
@@ -84,7 +85,7 @@ public class BootGeodeAsyncInlineCachingClientApplication {
|
||||
.buildPairings()
|
||||
.play();
|
||||
|
||||
golfTournamentService.manage(golfTournament);
|
||||
pgaTourService.manage(golfTournament);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,12 +23,14 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.data.gemfire.util.ArrayUtils;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -53,31 +55,23 @@ public class GolfTournament implements Iterable<GolfTournament.Pairing> {
|
||||
|
||||
private GolfCourse golfCourse;
|
||||
|
||||
private final List<Pairing> pairings = new ArrayList<>();
|
||||
private final List<Pairing> pairings = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
private final Set<Golfer> players = new HashSet<>();
|
||||
private final Set<Golfer> players = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
@Override
|
||||
public Iterator<GolfTournament.Pairing> iterator() {
|
||||
return Collections.unmodifiableList(this.pairings).iterator();
|
||||
public Iterable<Golfer> getPlayers() {
|
||||
return Collections.unmodifiableSet(this.players);
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
|
||||
Set<Pairing> finishedPairings = new HashSet<>(this.pairings.size());
|
||||
|
||||
for (Pairing pairing : this) {
|
||||
if (pairing.getHole() < 18) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
finishedPairings.add(pairing);
|
||||
}
|
||||
}
|
||||
|
||||
this.pairings.removeAll(finishedPairings);
|
||||
|
||||
return this.pairings.isEmpty();
|
||||
return true;
|
||||
}
|
||||
|
||||
public GolfTournament at(GolfCourse golfCourse) {
|
||||
@@ -109,6 +103,11 @@ public class GolfTournament implements Iterable<GolfTournament.Pairing> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<GolfTournament.Pairing> iterator() {
|
||||
return Collections.unmodifiableList(this.pairings).iterator();
|
||||
}
|
||||
|
||||
public GolfTournament play() {
|
||||
|
||||
Assert.state(this.golfCourse != null, "No golf course was declared");
|
||||
@@ -134,26 +133,39 @@ public class GolfTournament implements Iterable<GolfTournament.Pairing> {
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor(staticName = "of")
|
||||
public static class Pairing {
|
||||
|
||||
private final AtomicBoolean signedScorecard = new AtomicBoolean(false);
|
||||
|
||||
@NonNull
|
||||
private final Golfer playerOne;
|
||||
|
||||
@NonNull
|
||||
private final Golfer playerTwo;
|
||||
|
||||
public int getHole() {
|
||||
return getPlayerOne().getHole();
|
||||
}
|
||||
|
||||
public void setHole(int hole) {
|
||||
public synchronized void setHole(int hole) {
|
||||
this.playerOne.setHole(hole);
|
||||
this.playerTwo.setHole(hole);
|
||||
}
|
||||
|
||||
public int playNextHole() {
|
||||
public synchronized int getHole() {
|
||||
return getPlayerOne().getHole();
|
||||
}
|
||||
|
||||
public boolean in(@NonNull Golfer golfer) {
|
||||
return this.playerOne.equals(golfer) || this.playerTwo.equals(golfer);
|
||||
}
|
||||
|
||||
public synchronized int nextHole() {
|
||||
return getHole() + 1;
|
||||
}
|
||||
|
||||
public synchronized boolean signScorecard() {
|
||||
|
||||
return getHole() >= 18
|
||||
&& this.signedScorecard.compareAndSet(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
@@ -45,7 +47,7 @@ import example.app.caching.inline.async.client.model.Golfer;
|
||||
*/
|
||||
@Service
|
||||
@SuppressWarnings("unused")
|
||||
public class GolfTournamentService implements Closeable {
|
||||
public class PgaTourService implements Closeable {
|
||||
|
||||
protected static final int SCORE_DELTA_BOUND = 2;
|
||||
|
||||
@@ -55,7 +57,7 @@ public class GolfTournamentService implements Closeable {
|
||||
|
||||
private final Random random = new Random(System.currentTimeMillis());
|
||||
|
||||
public GolfTournamentService(GolferService golferService) {
|
||||
public PgaTourService(GolferService golferService) {
|
||||
|
||||
Assert.notNull(golferService, "GolferService must not be null");
|
||||
|
||||
@@ -66,12 +68,23 @@ public class GolfTournamentService implements Closeable {
|
||||
return Optional.ofNullable(this.golfTournament);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @PreDestroy
|
||||
public void close() {
|
||||
this.golfTournament = null;
|
||||
}
|
||||
|
||||
public GolfTournamentService manage(GolfTournament golfTournament) {
|
||||
public boolean isFinished() {
|
||||
|
||||
GolfTournament golfTournament = this.golfTournament;
|
||||
|
||||
return golfTournament == null || golfTournament.isFinished();
|
||||
}
|
||||
|
||||
public boolean isNotFinished() {
|
||||
return !isFinished();
|
||||
}
|
||||
|
||||
public PgaTourService manage(GolfTournament golfTournament) {
|
||||
|
||||
GolfTournament currentGolfTournament = this.golfTournament;
|
||||
|
||||
@@ -90,13 +103,13 @@ public class GolfTournamentService implements Closeable {
|
||||
|
||||
GolfTournament golfTournament = this.golfTournament;
|
||||
|
||||
if (golfTournament != null) {
|
||||
if (isNotFinished()) {
|
||||
playHole(golfTournament);
|
||||
finish(golfTournament);
|
||||
}
|
||||
}
|
||||
|
||||
private void playHole(@NonNull GolfTournament golfTournament) {
|
||||
private synchronized void playHole(@NonNull GolfTournament golfTournament) {
|
||||
|
||||
GolfCourse golfCourse = golfTournament.getGolfCourse();
|
||||
|
||||
@@ -104,7 +117,7 @@ public class GolfTournamentService implements Closeable {
|
||||
|
||||
for (GolfTournament.Pairing pairing : golfTournament) {
|
||||
|
||||
int hole = pairing.playNextHole();
|
||||
int hole = pairing.nextHole();
|
||||
|
||||
if (!occupiedHoles.contains(hole)) {
|
||||
if (golfCourse.isValidHoleNumber(hole)) {
|
||||
@@ -150,11 +163,8 @@ public class GolfTournamentService implements Closeable {
|
||||
|
||||
private void finish(@NonNull GolfTournament golfTournament) {
|
||||
|
||||
if (golfTournament.isFinished()) {
|
||||
|
||||
GolfCourse golfCourse = golfTournament.getGolfCourse();
|
||||
|
||||
for (GolfTournament.Pairing pairing : golfTournament) {
|
||||
for (GolfTournament.Pairing pairing : golfTournament) {
|
||||
if (pairing.signScorecard()) {
|
||||
updateScore(this::calculateFinalScore, pairing.getPlayerOne());
|
||||
updateScore(this::calculateFinalScore, pairing.getPlayerTwo());
|
||||
}
|
||||
@@ -25,43 +25,33 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import example.app.caching.inline.async.client.model.GolfTournament;
|
||||
import example.app.caching.inline.async.client.model.Golfer;
|
||||
import example.app.caching.inline.async.client.service.GolfTournamentService;
|
||||
import example.app.caching.inline.async.client.service.GolferService;
|
||||
|
||||
/**
|
||||
* Spring Web MVC {@link RestController} used to present a view of a {@link GolfTournament} running.
|
||||
* Spring Web MVC {@link RestController} used to present a view of {@link Golfer Golfers} standings
|
||||
* when playing in a {@link GolfTournament} on the {@literal PGA TOUR}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see example.app.caching.inline.async.client.model.Golfer
|
||||
* @see example.app.caching.inline.async.client.model.GolfTournament
|
||||
* @see example.app.caching.inline.async.client.service.GolferService
|
||||
* @see example.app.caching.inline.async.client.service.GolfTournamentService
|
||||
* @see org.springframework.web.bind.annotation.GetMapping
|
||||
* @see org.springframework.web.bind.annotation.RequestMapping
|
||||
* @see org.springframework.web.bind.annotation.RestController
|
||||
* @see example.app.caching.inline.async.client.model.Golfer
|
||||
* @see example.app.caching.inline.async.client.model.GolfTournament
|
||||
* @see example.app.caching.inline.async.client.service.GolferService
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/golf/tournament")
|
||||
@SuppressWarnings("unused")
|
||||
public class GolfTournamentController {
|
||||
public class GolferController {
|
||||
|
||||
private final GolferService golferService;
|
||||
|
||||
private final GolfTournamentService golfTournamentService;
|
||||
|
||||
public GolfTournamentController(@NonNull GolferService golferService,
|
||||
@NonNull GolfTournamentService golfTournamentService) {
|
||||
public GolferController(@NonNull GolferService golferService) {
|
||||
|
||||
Assert.notNull(golferService, "GolferService must not be null");
|
||||
Assert.notNull(golfTournamentService, "GolfTournamentService must not be null");
|
||||
|
||||
this.golferService = golferService;
|
||||
this.golfTournamentService = golfTournamentService;
|
||||
}
|
||||
|
||||
protected @NonNull GolfTournamentService getGolfTournamentService() {
|
||||
return this.golfTournamentService;
|
||||
}
|
||||
|
||||
protected @NonNull GolferService getGolferService() {
|
||||
@@ -48,10 +48,11 @@ public class AsyncInlineCachingConfiguration {
|
||||
@Bean
|
||||
@Profile("queue-batch-size")
|
||||
AsyncInlineCachingRegionConfigurer<Golfer, String> batchSizeAsyncInlineCachingConfigurer(
|
||||
@Value("${spring.geode.sample.async-inline-caching.queue.batch-size:4}") int queueBatchSize,
|
||||
@Value("${spring.geode.sample.async-inline-caching.queue.batch-size:25}") int queueBatchSize,
|
||||
GolferRepository golferRepository) {
|
||||
|
||||
return AsyncInlineCachingRegionConfigurer.create(golferRepository, GOLFERS_REGION_NAME)
|
||||
.withQueueBatchConflationEnabled()
|
||||
.withQueueBatchSize(queueBatchSize)
|
||||
.withQueueBatchTimeInterval(Duration.ofMinutes(60))
|
||||
.withQueueDispatcherThreadCount(1);
|
||||
|
||||
Reference in New Issue
Block a user