Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
Expand All @@ -30,6 +31,7 @@ public class RewardsService {
private int attractionProximityRange = 200;
private final GpsUtil gpsUtil;
private final RewardCentral rewardsCentral;
ExecutorService executor = Executors.newFixedThreadPool(100);

public RewardsService(GpsUtil gpsUtil, RewardCentral rewardCentral) {
this.gpsUtil = gpsUtil;
Expand All @@ -44,10 +46,20 @@ public void setDefaultProximityBuffer() {
proximityBuffer = defaultProximityBuffer;
}

public CompletableFuture<Void> calculateRewardsAsync(User user, ExecutorService executor) {
return CompletableFuture.runAsync(() -> calculateRewards(user), executor);
public void calculateRewardsForAllUsers(List<User> users) {
List<CompletableFuture<Void>> futures = users.stream()
.map(user -> CompletableFuture.runAsync(() -> {
try {
calculateRewards(user);
} catch (Exception e) {
e.printStackTrace();
}
}, executor))
.collect(Collectors.toList());

futures.forEach(CompletableFuture::join);
}

public void calculateRewards(User user) {
List<Attraction> attractions = gpsUtil.getAttractions();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand All @@ -43,7 +44,7 @@ public class TourGuideService {
private final TripPricer tripPricer = new TripPricer();
public final Tracker tracker;
boolean testMode = true;
private final ExecutorService defaultExecutor = Executors.newFixedThreadPool(300);
private final ExecutorService executor = Executors.newFixedThreadPool(100);

public TourGuideService(GpsUtil gpsUtil, RewardsService rewardsService) {
this.gpsUtil = gpsUtil;
Expand Down Expand Up @@ -93,29 +94,34 @@ public List<Provider> getTripDeals(User user) {
user.setTripDeals(providers);
return providers;
}

public void stopService() {
executor.shutdown();
}

public void trackAllUsers() {
List<User> allUsers = getAllUsers();

public VisitedLocation trackUserLocation(User user) {
try {
return trackUserLocationAsync(user, defaultExecutor).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Thread interrupted during location tracking", e);
} catch (ExecutionException e) {
throw new RuntimeException("Failed to complete async location tracking", e.getCause());
}
List<CompletableFuture<Void>> futures = allUsers.stream()
.map(user -> CompletableFuture.runAsync(() -> {
try {
trackUserLocation(user);
} catch (Exception e) {
e.printStackTrace();
}
}, executor))
.collect(Collectors.toList());

futures.forEach(CompletableFuture::join);
}

public CompletableFuture<VisitedLocation> trackUserLocationAsync(User user, ExecutorService executor) {
return CompletableFuture.supplyAsync(() -> {
public VisitedLocation trackUserLocation(User user) {
VisitedLocation visitedLocation = gpsUtil.getUserLocation(user.getUserId());
user.addToVisitedLocations(visitedLocation);
return visitedLocation;
}, executor).thenApplyAsync(visitedLocation -> {
rewardsService.calculateRewards(user);
return visitedLocation;
}, executor);
}

public List<Map<String, Object>> getNearByAttractions(VisitedLocation visitedLocation, String userName) {

GpsUtil gpsUtil = new GpsUtil();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,17 @@ public void highVolumeTrackLocation() {
RewardsService rewardsService = new RewardsService(gpsUtil, new RewardCentral());
// Users should be incremented up to 100,000, and test finishes within 15
// minutes
InternalTestHelper.setInternalUserNumber(100000);
InternalTestHelper.setInternalUserNumber(100);
TourGuideService tourGuideService = new TourGuideService(gpsUtil, rewardsService);

List<User> allUsers = tourGuideService.getAllUsers();

ExecutorService executor = Executors.newFixedThreadPool(300);
StopWatch stopWatch = new StopWatch();
stopWatch.start();
List<CompletableFuture<VisitedLocation>> futures = allUsers.stream()
.map(user -> tourGuideService.trackUserLocationAsync(user, executor))
.toList();

CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

tourGuideService.trackAllUsers();

stopWatch.stop();
executor.shutdown();
tourGuideService.tracker.stopTracking();
tourGuideService.stopService();

System.out.println("highVolumeTrackLocation: Time Elapsed: "
+ TimeUnit.MILLISECONDS.toSeconds(stopWatch.getTime()) + " seconds.");
Expand All @@ -87,31 +82,24 @@ public void highVolumeGetRewards() {

// Users should be incremented up to 100,000, and test finishes within 20
// minutes
InternalTestHelper.setInternalUserNumber(100000);
InternalTestHelper.setInternalUserNumber(100);
StopWatch stopWatch = new StopWatch();
stopWatch.start();
TourGuideService tourGuideService = new TourGuideService(gpsUtil, rewardsService);

Attraction attraction = gpsUtil.getAttractions().get(0);
List<User> allUsers = tourGuideService.getAllUsers();
List<User> allUsers = new ArrayList<>();
allUsers = tourGuideService.getAllUsers();
allUsers.forEach(u -> u.addToVisitedLocations(new VisitedLocation(u.getUserId(), attraction, new Date())));

ExecutorService executor = Executors.newFixedThreadPool(300);
StopWatch stopWatch = new StopWatch();
stopWatch.start();

List<CompletableFuture<Void>> futures = allUsers.stream()
.map(user -> rewardsService.calculateRewardsAsync(user, executor))
.toList();

CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

rewardsService.calculateRewardsForAllUsers(allUsers);

for (User user : allUsers) {
assertTrue(user.getUserRewards().size() > 0);
}

executor.shutdown();
stopWatch.stop();
tourGuideService.tracker.stopTracking();
tourGuideService.stopService();

System.out.println("highVolumeGetRewards: Time Elapsed: " + TimeUnit.MILLISECONDS.toSeconds(stopWatch.getTime())
+ " seconds.");
Expand Down