Skip to content

Commit

Permalink
Fix download cache size metric value.
Browse files Browse the repository at this point in the history
Unify information about download/upload caches.
Add metrics to track download/upload cache file count.
  • Loading branch information
ekharkunov committed Aug 16, 2024
1 parent fd93783 commit df02c78
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 30 deletions.
16 changes: 8 additions & 8 deletions server/src/main/java/com/defold/extender/ExtenderController.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ public void buildEngine(HttpServletRequest _request,
metricsWriter.measureReceivedRequest(request);

// Get cached files from the cache service
long totalCacheDownloadSize = dataCacheService.getCachedFiles(uploadDirectory);
metricsWriter.measureCacheDownload(totalCacheDownloadSize);
DataCacheService.DataCacheServiceInfo totalCacheDownloadInfo = dataCacheService.getCachedFiles(uploadDirectory);
metricsWriter.measureCacheDownload(totalCacheDownloadInfo.cachedFileSize.longValue(), totalCacheDownloadInfo.cachedFileCount.intValue());

String[] buildEnvDescription = ExtenderUtil.getSdksForPlatform(platform, defoldSdkService.getPlatformSdkMappings(sdkVersion));
// Build engine locally or on remote builder
Expand Down Expand Up @@ -266,8 +266,8 @@ public void buildEngine(HttpServletRequest _request,
throw e;
} finally {
// Regardless of success/fail status, we want to cache the uploaded files
long totalUploadSize = dataCacheService.cacheFiles(uploadDirectory);
metricsWriter.measureCacheUpload(totalUploadSize);
DataCacheService.DataCacheServiceInfo uploadResultInfo = dataCacheService.cacheFiles(uploadDirectory);
metricsWriter.measureCacheUpload(uploadResultInfo.cachedFileSize.longValue(), uploadResultInfo.cachedFileCount.intValue());
metricsWriter.measureCounterBuild(platform, sdkVersionString, "sync", isSuccessfull);

boolean deleteDirectory = true;
Expand Down Expand Up @@ -338,8 +338,8 @@ public void buildEngineAsync(HttpServletRequest _request,
metricsWriter.measureReceivedRequest(request);

// Get cached files from the cache service
long totalCacheDownloadSize = dataCacheService.getCachedFiles(uploadDirectory);
metricsWriter.measureCacheDownload(totalCacheDownloadSize);
DataCacheService.DataCacheServiceInfo totalCacheDownloadInfo = dataCacheService.getCachedFiles(uploadDirectory);
metricsWriter.measureCacheDownload(totalCacheDownloadInfo.cachedFileSize.longValue(), totalCacheDownloadInfo.cachedFileCount.intValue());

String[] buildEnvDescription = ExtenderUtil.getSdksForPlatform(platform, defoldSdkService.getPlatformSdkMappings(sdkVersion));
// Build engine locally or on remote builder
Expand All @@ -365,8 +365,8 @@ public void buildEngineAsync(HttpServletRequest _request,
throw e;
} finally {
// Regardless of success/fail status, we want to cache the uploaded files
long totalUploadSize = dataCacheService.cacheFiles(uploadDirectory);
metricsWriter.measureCacheUpload(totalUploadSize);
DataCacheService.DataCacheServiceInfo uploadResultInfo = dataCacheService.cacheFiles(uploadDirectory);
metricsWriter.measureCacheUpload(uploadResultInfo.cachedFileSize.longValue(), uploadResultInfo.cachedFileCount.intValue());

boolean deleteDirectory = true;
if (DM_DEBUG_KEEP_JOB_FOLDER != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ public MetricsWriter(MeterRegistry registry, com.defold.extender.Timer timer) {
DistributionSummary.builder("extender.job.requestSize").baseUnit(BaseUnits.BYTES).register(registry);
DistributionSummary.builder("extender.job.zipSize").baseUnit(BaseUnits.BYTES).register(registry);
DistributionSummary.builder("extender.job.cache.uploadSize").baseUnit(BaseUnits.BYTES).register(registry);
DistributionSummary.builder("extender.job.cache.uploadCount").baseUnit(BaseUnits.FILES).register(registry);
DistributionSummary.builder("extender.job.cache.downloadSize").baseUnit(BaseUnits.BYTES).register(registry);
DistributionSummary.builder("extender.job.cache.downloadCount").baseUnit(BaseUnits.FILES).register(registry);
}

public MetricsWriter(final MeterRegistry registry) {
Expand Down Expand Up @@ -70,14 +72,16 @@ public void measureSentResponse() {
metricsTimer(this.registry, "extender.job.write", timer.start());
}

public void measureCacheUpload(long uploadSize) {
public void measureCacheUpload(long uploadSize, int uploadCount) {
metricsTimer(this.registry, "extender.job.cache.upload", timer.start());
metricsSummary(this.registry, "extender.job.cache.uploadSize", uploadSize);
metricsSummary(this.registry, "extender.job.cache.uploadCount", uploadCount);
}

public void measureCacheDownload(long downloadSize) {
public void measureCacheDownload(long downloadSize, int downloadCount) {
metricsTimer(this.registry, "extender.job.cache.download", timer.start());
metricsSummary(this.registry, "extender.job.cache.downloadSize", downloadSize);
metricsSummary(this.registry, "extender.job.cache.downloadCount", downloadCount);
}

public void measureCounterBuild(String platform, String sdk, String buildType, Boolean isSuccessfull) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

@Service
Expand All @@ -40,6 +41,11 @@ public class DataCacheService {

private DataCache dataCache;

public class DataCacheServiceInfo {
public AtomicInteger cachedFileCount = new AtomicInteger();
public AtomicLong cachedFileSize = new AtomicLong();
}

DataCacheService(final CacheKeyGenerator cacheKeyGenerator,
final CacheInfoFileParser cacheInfoFileParser,
final CacheInfoFileWriter cacheInfoFileWriter,
Expand All @@ -60,30 +66,29 @@ private boolean isCached(final String key) {
return dataCache.exists(key);
}

public long cacheFiles(final File directory) throws IOException {
public DataCacheServiceInfo cacheFiles(final File directory) throws IOException {
DataCacheServiceInfo result = new DataCacheServiceInfo();
if (! cacheIsEnabled) {
return 0;
return result;
}

LOGGER.debug(String.format("Caching files in directory %s", directory.getPath()));

final AtomicLong totalbytesCached = new AtomicLong();
final AtomicLong totalFilesCached = new AtomicLong();
Files.walk(directory.toPath())
.filter(Files::isRegularFile)
.filter(path -> ! FILE_CACHE_INFO_FILE.equals(path.getFileName().toString()))
.forEach(path -> {
try {
long fileSize = upload(path.toFile());
totalbytesCached.addAndGet(fileSize);
totalFilesCached.addAndGet(fileSize >= fileSizeThreshold ? 1 : 0);
result.cachedFileSize.addAndGet(fileSize);
result.cachedFileCount.addAndGet(fileSize >= fileSizeThreshold ? 1 : 0);
} catch (IOException e) {
LOGGER.error("Could not cache file " + path.toString(), e);
}
});

LOGGER.info(String.format("Cached %d bytes in %d files", totalbytesCached.longValue(), totalFilesCached.longValue()));
return totalbytesCached.longValue();
LOGGER.info(String.format("Cached %d bytes in %d files", result.cachedFileSize.longValue(), result.cachedFileCount.intValue()));
return result;
}

private long upload(File file) throws IOException {
Expand All @@ -102,32 +107,32 @@ private long upload(File file) throws IOException {
}

// Step through the entries in the json and download them from the key-value server
public int getCachedFiles(File directory) throws IOException, ExtenderException {
public DataCacheServiceInfo getCachedFiles(File directory) throws IOException, ExtenderException {
DataCacheServiceInfo result = new DataCacheServiceInfo();
if (! cacheIsEnabled) {
return 0;
return result;
}

File cacheInfoFile = new File(directory, FILE_CACHE_INFO_FILE);

// Support older editors that don't supply a cache info file
if (!cacheInfoFile.exists()) {
LOGGER.info("No cache info file found, skipping cache");
return 0;
return result;
}
LOGGER.info("Downloading cached files");

final CacheInfoWrapper wrapper = cacheInfoFileParser.parse(cacheInfoFile);
if (wrapper == null) {
LOGGER.info("Couldn't parse the cache info file. Ignoring");
return 0;
return result;
}

List<CacheEntry> cacheEntries = wrapper.getEntries();
// we can face null pointer in cacheEntries if client, who requestd a build, don't have access to /query endpoint
if (cacheEntries == null) {
return 0;
return result;
}
int numCachedFiles = 0;

for (CacheEntry entry : cacheEntries) {
// Check if entry is cached
Expand All @@ -139,20 +144,20 @@ public int getCachedFiles(File directory) throws IOException, ExtenderException

File destination = new File(directory, entry.getPath());
makeParentDirectories(destination);
downloadFile(entry, destination);
result.cachedFileSize.addAndGet(downloadFile(entry, destination));

if (! destination.exists()) {
throw new ExtenderException(String.format("Failed downloading '%s' (%s) from cache",
entry.getPath(), entry.getKey()));
}

verifyCacheKey(destination, entry.getKey());
numCachedFiles++;
result.cachedFileCount.addAndGet(1);
}

LOGGER.info(String.format("Downloaded %d cached files", numCachedFiles));
LOGGER.info(String.format("Downloaded %d bytes in %d cached files", result.cachedFileSize.longValue(), result.cachedFileCount.intValue()));

return numCachedFiles;
return result;
}

private void verifyCacheEntry(CacheEntry entry) throws ExtenderException {
Expand All @@ -175,13 +180,13 @@ private boolean makeParentDirectories(File file) {
return file.getParentFile().exists() || file.getParentFile().mkdirs();
}

private void downloadFile(CacheEntry entry, File destination) throws ExtenderException, IOException {
private long downloadFile(CacheEntry entry, File destination) throws ExtenderException, IOException {
try (InputStream inputStream = dataCache.get(entry.getKey())) {
if (inputStream == null) {
throw new ExtenderException(String.format("Cache object %s (%s) was not found", entry.getPath(), entry.getKey()));
}

Files.copy(
return Files.copy(
inputStream,
destination.toPath(),
StandardCopyOption.REPLACE_EXISTING);
Expand Down

0 comments on commit df02c78

Please sign in to comment.