Skip to content
This repository was archived by the owner on Feb 24, 2023. It is now read-only.

Commit 3f6e9f2

Browse files
committed
Performance delivery improvements
1 parent fb191e6 commit 3f6e9f2

File tree

4 files changed

+115
-48
lines changed

4 files changed

+115
-48
lines changed

edge/src/main/java/com/scale8/AppEntity.java

+33-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.scale8;
22

3+
import com.github.benmanes.caffeine.cache.Cache;
4+
import com.github.benmanes.caffeine.cache.Caffeine;
35
import com.google.gson.Gson;
46
import com.google.gson.JsonElement;
57
import com.google.gson.JsonObject;
@@ -14,8 +16,6 @@
1416
import com.scale8.extended.types.Tuple;
1517
import com.scale8.ingest.Ingestor;
1618
import com.scale8.util.HashUtil;
17-
import io.micronaut.cache.annotation.CacheConfig;
18-
import io.micronaut.cache.annotation.Cacheable;
1919
import org.slf4j.Logger;
2020
import org.slf4j.LoggerFactory;
2121
import javax.inject.Inject;
@@ -29,14 +29,20 @@
2929
import java.util.HashMap;
3030
import java.util.List;
3131
import java.util.Map;
32+
import java.util.concurrent.TimeUnit;
3233

3334
import static io.micronaut.http.HttpHeaders.ACCEPT;
3435
import static io.micronaut.http.MediaType.APPLICATION_JSON;
3536

3637
@Singleton
37-
@CacheConfig("app")
3838
public class AppEntity {
3939

40+
private final Cache<String, String> configCache =
41+
Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).maximumSize(100).build();
42+
43+
private final Cache<String, String> assetCache =
44+
Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).maximumSize(100).build();
45+
4046
private final String PUBLIC_PATH = "http://127.0.0.1:3123";
4147

4248
private static final Logger LOG = LoggerFactory.getLogger(AppEntity.class);
@@ -55,12 +61,19 @@ public AppSettings getConfig(ExtendedRequest request) throws Exception {
5561
return new Gson().fromJson(getRawConfig(request), AppSettings.class);
5662
}
5763

58-
@Cacheable()
5964
protected String getRawConfig(ExtendedRequest request) throws IOException, InterruptedException {
6065
String previewId = request.getRevisionPreviewId();
6166
if (previewId == null) {
62-
// fetch the config from GCS against the incoming host...
63-
return storage.get(env.CONFIG_BUCKET, "tag-domain/" + request.getHost() + ".json");
67+
String uri = "tag-domain/" + request.getHost() + ".json";
68+
String config = configCache.getIfPresent(uri);
69+
if(config == null){
70+
LOG.info("Going back to " + env.CONFIG_BUCKET + " to fetch " + uri + ", not present in cache");
71+
String fetchedConfig = storage.get(env.CONFIG_BUCKET, uri);
72+
configCache.put(uri, fetchedConfig);
73+
return fetchedConfig;
74+
} else {
75+
return config;
76+
}
6477
} else {
6578
return HttpClient.newHttpClient()
6679
.send(
@@ -111,15 +124,26 @@ private String publicPath(ExtendedRequest extendedRequest, String platformId, St
111124
}
112125
}
113126

127+
private String getJsAsset(String uri) throws IOException {
128+
String jsAsset = assetCache.getIfPresent(uri);
129+
if(jsAsset == null){
130+
LOG.info("Going back to " + env.ASSETS_BUCKET + " to fetch " + uri + ", not present in cache");
131+
String freshJsAsset = storage.get(env.ASSETS_BUCKET, uri);
132+
assetCache.put(uri, freshJsAsset);
133+
return freshJsAsset;
134+
} else {
135+
return jsAsset;
136+
}
137+
}
138+
114139
public String fetchJSAsset(ExtendedRequest request, String platformId, String asset)
115140
throws Exception {
116141
AppSettings appSettings = getConfig(request);
117142
String ngp = request.getRequest().getParameters().get("ngp");
118143
if (appSettings.getCorePlatformId().equals(platformId) && ngp != null) {
119144
return doJsProxyRequest("http://" + ngp + ".ngrok.io/" + asset);
120145
} else {
121-
return storage.get(
122-
env.ASSETS_BUCKET, appSettings.getAllAssetsMap().get(platformId + "-" + asset));
146+
return getJsAsset(appSettings.getAllAssetsMap().get(platformId + "-" + asset));
123147
}
124148
}
125149

@@ -133,7 +157,7 @@ public String getPrimaryJsAsset(ExtendedRequest request, String platformId) thro
133157
String js =
134158
env.PROXY_FOR.equals(platformId)
135159
? doJsProxyRequest(env.PROXY_LOCATION)
136-
: storage.get(env.ASSETS_BUCKET, primaryAssetUri);
160+
: getJsAsset(primaryAssetUri);
137161

138162
return js.replace(
139163
PUBLIC_PATH, publicPath(request, platformId, request.getRevisionPreviewId()))

edge/src/main/java/com/scale8/IngestEntity.java

+23-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.scale8;
22

3+
import com.github.benmanes.caffeine.cache.Cache;
4+
import com.github.benmanes.caffeine.cache.Caffeine;
35
import com.google.gson.Gson;
46
import com.google.gson.JsonObject;
57
import com.google.gson.JsonPrimitive;
@@ -9,20 +11,21 @@
911
import com.scale8.config.structures.IngestSettings;
1012
import com.scale8.extended.ExtendedRequest;
1113
import com.scale8.ingest.Ingestor;
12-
import io.micronaut.cache.annotation.CacheConfig;
13-
import io.micronaut.cache.annotation.Cacheable;
1414
import org.slf4j.Logger;
1515
import org.slf4j.LoggerFactory;
1616
import javax.inject.Inject;
1717
import javax.inject.Singleton;
1818
import java.io.IOException;
1919
import java.nio.charset.StandardCharsets;
2020
import java.util.List;
21+
import java.util.concurrent.TimeUnit;
2122

2223
@Singleton
23-
@CacheConfig("ingest")
2424
public class IngestEntity {
2525

26+
private final Cache<String, IngestSettings> cache =
27+
Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).maximumSize(100).build();
28+
2629
private static final Logger LOG = LoggerFactory.getLogger(IngestEntity.class);
2730

2831
@Inject Env env;
@@ -33,10 +36,17 @@ public class IngestEntity {
3336

3437
@Inject Payload payload;
3538

36-
@Cacheable()
3739
protected IngestSettings getConfig(String uri) throws IOException {
38-
String data = storage.get(env.CONFIG_BUCKET, uri);
39-
return new Gson().fromJson(data, IngestSettings.class);
40+
IngestSettings ingestSettings = cache.getIfPresent(uri);
41+
if (ingestSettings == null) {
42+
LOG.info("Going back to " + env.CONFIG_BUCKET + " to fetch " + uri + ", not present in cache");
43+
IngestSettings freshIngestSettings =
44+
new Gson().fromJson(storage.get(env.CONFIG_BUCKET, uri), IngestSettings.class);
45+
cache.put(uri, freshIngestSettings);
46+
return freshIngestSettings;
47+
} else {
48+
return ingestSettings;
49+
}
4050
}
4151

4252
public IngestSettings getConfigByHost(String host) throws IOException {
@@ -86,7 +96,8 @@ protected void trackUsage(
8696
}
8797

8898
protected List<String> offerToIngestor(
89-
ExtendedRequest extendedRequest, JsonObject jsonObject, IngestSettings ingestSettings) throws IOException {
99+
ExtendedRequest extendedRequest, JsonObject jsonObject, IngestSettings ingestSettings)
100+
throws IOException {
90101
JsonObject data =
91102
payload.applyDefaultValues(
92103
jsonObject,
@@ -97,8 +108,9 @@ protected List<String> offerToIngestor(
97108
payload.validateSchemaAgainstPayload(data, ingestSettings.getSchemaAsMap());
98109

99110
if (issues.isEmpty()) {
100-
if(!ingestSettings.getUsageIngestEnvId().isEmpty() && ingestSettings.getIsAnalyticsEnabled()){
101-
//we need to track usage...
111+
if (!ingestSettings.getUsageIngestEnvId().isEmpty()
112+
&& ingestSettings.getIsAnalyticsEnabled()) {
113+
// we need to track usage...
102114
ingestor.add(data, ingestSettings, getConfigById(ingestSettings.getUsageIngestEnvId()));
103115
} else {
104116
ingestor.add(data, ingestSettings);
@@ -109,7 +121,8 @@ protected List<String> offerToIngestor(
109121
}
110122

111123
public List<String> add(
112-
ExtendedRequest extendedRequest, IngestSettings ingestSettings, JsonObject jsonObject) throws IOException {
124+
ExtendedRequest extendedRequest, IngestSettings ingestSettings, JsonObject jsonObject)
125+
throws IOException {
113126
return offerToIngestor(extendedRequest, jsonObject, ingestSettings);
114127
}
115128

edge/src/main/java/com/scale8/extended/ExtendedRequest.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.scale8.extended;
22

3+
import com.github.benmanes.caffeine.cache.Cache;
4+
import com.github.benmanes.caffeine.cache.Caffeine;
35
import com.google.gson.Gson;
46
import com.google.gson.JsonElement;
57
import com.google.gson.JsonObject;
@@ -10,14 +12,14 @@
1012
import com.scale8.util.HashUtil;
1113
import io.micronaut.http.HttpHeaders;
1214
import io.micronaut.http.HttpRequest;
13-
import ua_parser.Client;
1415
import ua_parser.Parser;
1516
import java.security.NoSuchAlgorithmException;
1617
import java.time.LocalDateTime;
1718
import java.time.ZoneId;
1819
import java.time.format.DateTimeFormatter;
1920
import java.util.Map;
2021
import java.util.Optional;
22+
import java.util.concurrent.TimeUnit;
2123
import java.util.stream.Stream;
2224

2325
import static java.lang.Math.abs;
@@ -31,6 +33,9 @@ public class ExtendedRequest {
3133
final Map<String, String> allParameters;
3234
final String id;
3335

36+
private final Cache<String, ua_parser.Client> uaCache =
37+
Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).maximumSize(1000).build();
38+
3439
public ExtendedRequest(HttpRequest<String> request, Env env, Geo geo, String id) {
3540
this.env = env;
3641
this.geo = geo;
@@ -167,8 +172,23 @@ public String getRevisionPreviewId() {
167172
return getAllParameters().get("preview");
168173
}
169174

170-
public Client getUserAgent() {
171-
return new Parser().parse(request.getHeaders().get(HttpHeaders.USER_AGENT));
175+
public ua_parser.Client getUserAgent() {
176+
String uaHeader = request.getHeaders().get(HttpHeaders.USER_AGENT);
177+
String ua = uaHeader == null? "" : uaHeader;
178+
String uaHash;
179+
try {
180+
uaHash = HashUtil.createHash(ua);
181+
} catch (NoSuchAlgorithmException noSuchAlgorithmException) {
182+
uaHash = "--";
183+
}
184+
ua_parser.Client client = uaCache.getIfPresent(uaHash);
185+
if(client == null){
186+
ua_parser.Client freshClient = new Parser().parse(ua);
187+
uaCache.put(uaHash, freshClient);
188+
return freshClient;
189+
} else {
190+
return client;
191+
}
172192
}
173193

174194
public String getUserAgentAsString() {
+36-26
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
package com.scale8.mmdb;
22

33
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.github.benmanes.caffeine.cache.Cache;
5+
import com.github.benmanes.caffeine.cache.Caffeine;
46
import com.maxmind.db.Reader;
57
import com.scale8.Env;
6-
import io.micronaut.cache.annotation.CacheConfig;
7-
import io.micronaut.cache.annotation.Cacheable;
88
import org.slf4j.Logger;
99
import org.slf4j.LoggerFactory;
1010
import javax.inject.Singleton;
1111
import java.io.FileInputStream;
1212
import java.io.IOException;
1313
import java.net.InetAddress;
1414
import java.net.URL;
15+
import java.util.concurrent.TimeUnit;
1516

1617
@Singleton
17-
@CacheConfig("geo")
1818
public class Geo {
1919

20+
private final Cache<String, GeoData> cache =
21+
Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).maximumSize(1000).build();
22+
2023
private static final Logger LOG = LoggerFactory.getLogger(Geo.class);
2124

2225
Reader GEO_DB;
@@ -45,33 +48,40 @@ private JsonNode getLookUp(String host) {
4548
}
4649
}
4750

48-
@Cacheable()
4951
public GeoData getGeoData(String host) {
50-
String countryCode = null;
51-
String region = null;
52-
String city = null;
53-
JsonNode lookup = getLookUp(host);
54-
if (lookup != null) {
55-
JsonNode countryNode = lookup.findValue("country");
56-
if (countryNode != null) {
57-
countryCode = countryNode.findValue("iso_code").asText();
58-
}
59-
JsonNode subdivisionsNode = lookup.findValue("subdivisions");
60-
if(subdivisionsNode != null && subdivisionsNode.isArray() && subdivisionsNode.has(0)){
61-
JsonNode first = subdivisionsNode.get(0);
62-
JsonNode name = first.findValue("names");
63-
if(name != null){
64-
region = name.findValue("en").asText();
52+
GeoData geoData = cache.getIfPresent(host);
53+
if (geoData == null) {
54+
LOG.info("Going back to " + GEO_DB + " to fetch " + host + ", not present in cache");
55+
String countryCode = null;
56+
String region = null;
57+
String city = null;
58+
JsonNode lookup = getLookUp(host);
59+
if (lookup != null) {
60+
JsonNode countryNode = lookup.findValue("country");
61+
if (countryNode != null) {
62+
countryCode = countryNode.findValue("iso_code").asText();
6563
}
66-
}
67-
JsonNode cityNode = lookup.findValue("city");
68-
if(cityNode != null){
69-
JsonNode name = cityNode.findValue("names");
70-
if(name != null){
71-
city = name.findValue("en").asText();
64+
JsonNode subdivisionsNode = lookup.findValue("subdivisions");
65+
if (subdivisionsNode != null && subdivisionsNode.isArray() && subdivisionsNode.has(0)) {
66+
JsonNode first = subdivisionsNode.get(0);
67+
JsonNode name = first.findValue("names");
68+
if (name != null) {
69+
region = name.findValue("en").asText();
70+
}
71+
}
72+
JsonNode cityNode = lookup.findValue("city");
73+
if (cityNode != null) {
74+
JsonNode name = cityNode.findValue("names");
75+
if (name != null) {
76+
city = name.findValue("en").asText();
77+
}
7278
}
7379
}
80+
GeoData freshGeoData = new GeoData(countryCode, region, city);
81+
cache.put(host, freshGeoData);
82+
return freshGeoData;
83+
} else {
84+
return geoData;
7485
}
75-
return new GeoData(countryCode, region, city);
7686
}
7787
}

0 commit comments

Comments
 (0)