mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-15 05:41:51 +08:00
Refactored AsyncJSONResolverService to reduce duplicate code
This commit is contained in:
parent
92e98948ec
commit
2c9c691b4f
@ -61,118 +61,47 @@ public class AsyncJSONResolverService {
|
|||||||
accessLock = new UnitSemaphoreAccessLock();
|
accessLock = new UnitSemaphoreAccessLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> JSONStorage.StoredJSON resolve(long newerThanTimestamp, DataID dataID, UUID serverUUID, Function<UUID, T> creator) {
|
public <T> JSONStorage.StoredJSON resolve(
|
||||||
|
long newerThanTimestamp, DataID dataID, UUID serverUUID, Function<UUID, T> creator
|
||||||
|
) {
|
||||||
String identifier = dataID.of(serverUUID);
|
String identifier = dataID.of(serverUUID);
|
||||||
|
Supplier<T> jsonCreator = () -> creator.apply(serverUUID);
|
||||||
// Attempt to find a newer version of the json file from cache
|
return getStoredOrCreateJSON(newerThanTimestamp, identifier, jsonCreator);
|
||||||
JSONStorage.StoredJSON storedJSON = jsonStorage.fetchExactJson(identifier, newerThanTimestamp)
|
|
||||||
.orElseGet(() -> jsonStorage.fetchJsonMadeAfter(identifier, newerThanTimestamp)
|
|
||||||
.orElse(null));
|
|
||||||
if (storedJSON != null) {
|
|
||||||
return storedJSON;
|
|
||||||
}
|
|
||||||
// No new enough version, let's refresh and send old version of the file
|
|
||||||
|
|
||||||
long updateThreshold = config.get(WebserverSettings.REDUCED_REFRESH_BARRIER);
|
|
||||||
|
|
||||||
// Check if the json is already being created
|
|
||||||
Future<JSONStorage.StoredJSON> updatedJSON;
|
|
||||||
accessLock.enter();
|
|
||||||
try {
|
|
||||||
updatedJSON = currentlyProcessing.get(identifier);
|
|
||||||
if (updatedJSON == null && previousUpdates.getOrDefault(identifier, 0L) < newerThanTimestamp - updateThreshold) {
|
|
||||||
// Submit a task to refresh the data if the json is old
|
|
||||||
updatedJSON = processing.submitNonCritical(() -> {
|
|
||||||
JSONStorage.StoredJSON created = jsonStorage.storeJson(identifier, creator.apply(serverUUID));
|
|
||||||
currentlyProcessing.remove(identifier);
|
|
||||||
jsonStorage.invalidateOlder(identifier, created.timestamp);
|
|
||||||
previousUpdates.put(identifier, created.timestamp);
|
|
||||||
return created;
|
|
||||||
});
|
|
||||||
currentlyProcessing.put(identifier, updatedJSON);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
accessLock.exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get an old version from cache
|
|
||||||
storedJSON = jsonStorage.fetchJsonMadeBefore(identifier, newerThanTimestamp).orElse(null);
|
|
||||||
if (storedJSON != null) {
|
|
||||||
return storedJSON;
|
|
||||||
} else {
|
|
||||||
// If there is no version available, block thread until the new finishes being generated.
|
|
||||||
try {
|
|
||||||
// Can be null if the last update was recent and the file is deleted before next update
|
|
||||||
if (updatedJSON == null) {
|
|
||||||
updatedJSON = processing.submitNonCritical(() -> {
|
|
||||||
JSONStorage.StoredJSON created = jsonStorage.storeJson(identifier, creator.apply(serverUUID));
|
|
||||||
currentlyProcessing.remove(identifier);
|
|
||||||
jsonStorage.invalidateOlder(identifier, created.timestamp);
|
|
||||||
previousUpdates.put(identifier, created.timestamp);
|
|
||||||
return created;
|
|
||||||
}); // TODO Refactor this spaghetti code
|
|
||||||
}
|
|
||||||
return updatedJSON.get();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
return null;
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new IllegalStateException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> JSONStorage.StoredJSON resolve(long newerThanTimestamp, DataID dataID, Supplier<T> creator) {
|
public <T> JSONStorage.StoredJSON resolve(
|
||||||
|
long newerThanTimestamp, DataID dataID, Supplier<T> jsonCreator
|
||||||
|
) {
|
||||||
String identifier = dataID.name();
|
String identifier = dataID.name();
|
||||||
|
return getStoredOrCreateJSON(newerThanTimestamp, identifier, jsonCreator);
|
||||||
// Attempt to find a newer version of the json file from cache
|
|
||||||
JSONStorage.StoredJSON storedJSON = jsonStorage.fetchExactJson(identifier, newerThanTimestamp)
|
|
||||||
.orElseGet(() -> jsonStorage.fetchJsonMadeAfter(identifier, newerThanTimestamp)
|
|
||||||
.orElse(null));
|
|
||||||
if (storedJSON != null) {
|
|
||||||
return storedJSON;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> JSONStorage.StoredJSON getStoredOrCreateJSON(
|
||||||
|
long timestamp, String identifier, Supplier<T> jsonCreator
|
||||||
|
) {
|
||||||
|
JSONStorage.StoredJSON storedJSON = getNewFromCache(timestamp, identifier);
|
||||||
|
if (storedJSON != null) return storedJSON;
|
||||||
|
|
||||||
// No new enough version, let's refresh and send old version of the file
|
// No new enough version, let's refresh and send old version of the file
|
||||||
|
Future<JSONStorage.StoredJSON> updatedJSON = scheduleJSONForUpdate(timestamp, identifier, jsonCreator);
|
||||||
|
|
||||||
long updateThreshold = config.get(WebserverSettings.REDUCED_REFRESH_BARRIER);
|
storedJSON = getOldFromCache(timestamp, identifier);
|
||||||
|
|
||||||
// Check if the json is already being created
|
|
||||||
Future<JSONStorage.StoredJSON> updatedJSON;
|
|
||||||
accessLock.enter();
|
|
||||||
try {
|
|
||||||
updatedJSON = currentlyProcessing.get(identifier);
|
|
||||||
if (updatedJSON == null && previousUpdates.getOrDefault(identifier, 0L) < newerThanTimestamp - updateThreshold) {
|
|
||||||
// Submit a task to refresh the data if the json is old
|
|
||||||
updatedJSON = processing.submitNonCritical(() -> {
|
|
||||||
JSONStorage.StoredJSON created = jsonStorage.storeJson(identifier, creator.get());
|
|
||||||
currentlyProcessing.remove(identifier);
|
|
||||||
jsonStorage.invalidateOlder(identifier, created.timestamp);
|
|
||||||
previousUpdates.put(identifier, created.timestamp);
|
|
||||||
return created;
|
|
||||||
});
|
|
||||||
currentlyProcessing.put(identifier, updatedJSON);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
accessLock.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get an old version from cache
|
|
||||||
storedJSON = jsonStorage.fetchJsonMadeBefore(identifier, newerThanTimestamp).orElse(null);
|
|
||||||
if (storedJSON != null) {
|
if (storedJSON != null) {
|
||||||
return storedJSON;
|
return storedJSON;
|
||||||
} else {
|
} else {
|
||||||
|
// Update not performed if the last update was recent and the file is deleted before next update
|
||||||
|
// Fall back to waiting for the updated file if old version of the file doesn't exist.
|
||||||
|
if (updatedJSON == null) {
|
||||||
|
updatedJSON = submitToProcessing(identifier, jsonCreator);
|
||||||
|
}
|
||||||
|
return waitAndGetUpdated(updatedJSON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONStorage.StoredJSON waitAndGetUpdated(Future<JSONStorage.StoredJSON> updatedJSON) {
|
||||||
// If there is no version available, block thread until the new finishes being generated.
|
// If there is no version available, block thread until the new finishes being generated.
|
||||||
try {
|
try {
|
||||||
// Can be null if the last update was recent and the file is deleted before next update.
|
|
||||||
if (updatedJSON == null) {
|
|
||||||
updatedJSON = processing.submitNonCritical(() -> {
|
|
||||||
JSONStorage.StoredJSON created = jsonStorage.storeJson(identifier, creator.get());
|
|
||||||
currentlyProcessing.remove(identifier);
|
|
||||||
jsonStorage.invalidateOlder(identifier, created.timestamp);
|
|
||||||
previousUpdates.put(identifier, created.timestamp);
|
|
||||||
return created;
|
|
||||||
}); // TODO Refactor this spaghetti code
|
|
||||||
}
|
|
||||||
return updatedJSON.get();
|
return updatedJSON.get();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
@ -181,6 +110,43 @@ public class AsyncJSONResolverService {
|
|||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JSONStorage.StoredJSON getOldFromCache(long newerThanTimestamp, String identifier) {
|
||||||
|
return jsonStorage.fetchJsonMadeBefore(identifier, newerThanTimestamp).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JSONStorage.StoredJSON getNewFromCache(long newerThanTimestamp, String identifier) {
|
||||||
|
return jsonStorage.fetchExactJson(identifier, newerThanTimestamp)
|
||||||
|
.orElseGet(() -> jsonStorage.fetchJsonMadeAfter(identifier, newerThanTimestamp)
|
||||||
|
.orElse(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Future<JSONStorage.StoredJSON> scheduleJSONForUpdate(long newerThanTimestamp, String identifier, Supplier<T> jsonCreator) {
|
||||||
|
long updateThreshold = config.get(WebserverSettings.REDUCED_REFRESH_BARRIER);
|
||||||
|
|
||||||
|
Future<JSONStorage.StoredJSON> updatedJSON;
|
||||||
|
accessLock.enter();
|
||||||
|
try {
|
||||||
|
// Check if the json is already being created
|
||||||
|
updatedJSON = currentlyProcessing.get(identifier);
|
||||||
|
if (updatedJSON == null && previousUpdates.getOrDefault(identifier, 0L) < newerThanTimestamp - updateThreshold) {
|
||||||
|
// Submit a task to refresh the data if the json is old
|
||||||
|
updatedJSON = submitToProcessing(identifier, jsonCreator);
|
||||||
|
currentlyProcessing.put(identifier, updatedJSON);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
accessLock.exit();
|
||||||
|
}
|
||||||
|
return updatedJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Future<JSONStorage.StoredJSON> submitToProcessing(String identifier, Supplier<T> jsonCreator) {
|
||||||
|
return processing.submitNonCritical(() -> {
|
||||||
|
JSONStorage.StoredJSON created = jsonStorage.storeJson(identifier, jsonCreator.get());
|
||||||
|
currentlyProcessing.remove(identifier);
|
||||||
|
jsonStorage.invalidateOlder(identifier, created.timestamp);
|
||||||
|
previousUpdates.put(identifier, created.timestamp);
|
||||||
|
return created;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user