Skip to content

Commit

Permalink
LDEV-4721 - add Harakiri controller thread
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeloffner committed Oct 10, 2023
1 parent e67b646 commit 0010427
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 36 deletions.
4 changes: 2 additions & 2 deletions build.number
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#Build Number for ANT. Do not edit!
#Fri Oct 06 12:02:49 CEST 2023
build.number=26
#Tue Oct 10 13:30:49 CEST 2023
build.number=1
2 changes: 1 addition & 1 deletion build.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
bundlename: s3.extension
filename: s3-extension
bundleversion: 2.0.1.
bundleversion: 2.0.2.
id: 17AB52DE-B300-A94B-E058BD978511E39E
luceeCoreVersion: 5.0.0.157
releaseType: server
Expand Down
55 changes: 22 additions & 33 deletions source/java/src/org/lucee/extension/resource/s3/S3.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import lucee.loader.engine.CFMLEngine;
import lucee.loader.engine.CFMLEngineFactory;
import lucee.loader.util.Util;
import lucee.runtime.config.Config;
import lucee.runtime.exp.PageException;
import lucee.runtime.net.s3.Properties;
import lucee.runtime.type.Array;
Expand Down Expand Up @@ -102,7 +103,6 @@ public class S3 {
public static final String[] PROVIDERS = new String[] { AWS, WASABI, BACKBLAZE, ".digitaloceanspaces.com", DREAM_IO, GOOGLE };

private static final ConcurrentHashMap<String, Object> tokens = new ConcurrentHashMap<String, Object>();
private static final int CHECK_INTERVALL = 1000;

private static Map<String, S3> instances = new ConcurrentHashMap<String, S3>();
private static Map<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
Expand All @@ -115,25 +115,26 @@ public class S3 {
private final long cacheTimeout;
private final long liveTimeout;

private int existCheckIntervall = 0;
private final Cache cache;

private Log log;
/////////////////////// CACHE ////////////////

private static class Cache {

public Cache() {
regions.put("US", RegionFactory.US_EAST_1);
}
static class Cache {

private final Harakiri harakiri;
private ValidUntilMap<S3BucketWrapper> buckets;
private Map<String, S3BucketExists> existBuckets;
private final Map<String, ValidUntilMap<S3Info>> objects = new ConcurrentHashMap<String, ValidUntilMap<S3Info>>();
private Map<String, ValidUntilElement<AccessControlList>> accessControlLists = new ConcurrentHashMap<String, ValidUntilElement<AccessControlList>>();
private Map<String, Region> regions = new ConcurrentHashMap<String, Region>();
private final Map<String, Region> bucketRegions = new ConcurrentHashMap<String, Region>();
private Map<String, S3Info> exists = new ConcurrentHashMap<String, S3Info>();
Map<String, S3Info> exists = new ConcurrentHashMap<String, S3Info>();

public Cache(Log log) {
regions.put("US", RegionFactory.US_EAST_1);
harakiri = new Harakiri(this, log);
}
}

public static S3 getInstance(S3Properties props, long cache) {
Expand All @@ -144,15 +145,17 @@ public static S3 getInstance(S3Properties props, long cache) {
synchronized (instances) {
s3 = instances.get(keyS3);
if (s3 == null) {
// print.ds("s3:" + key);
// same cache for all locations

String keyCache = props.getAccessKeyId() + ":" + props.getSecretAccessKey() + ":" + props.getHostWithoutRegion() + ":" + cache;
Cache c = caches.get(keyCache);
if (c == null) {
synchronized (caches) {
Log log = null;
Config config = CFMLEngineFactory.getInstance().getThreadConfig();
if (config != null) log = config.getLog("application");
c = caches.get(keyCache);
if (c == null) {
caches.put(keyCache, c = new Cache());
caches.put(keyCache, c = new Cache(log));
}
}
}
Expand All @@ -176,7 +179,6 @@ public static S3 getInstance(S3Properties props, long cache) {
*/
private S3(Cache cache, String accessKeyId, String secretAccessKey, String host, String defaultLocation, long cacheTimeout, long liveTimeout, boolean cacheRegions, Log log) {
this.cache = cache;

this.accessKeyId = accessKeyId;
this.secretAccessKey = secretAccessKey;
this.host = host;
Expand Down Expand Up @@ -946,12 +948,12 @@ private ValidUntilMap<S3Info> _list(String bucketName, String objectName, boolea

if (!hasObjName || name.equals(nameFile) || name.startsWith(nameDir)) _list.put(kid.getKey(), tmp);
cache.exists.put(toKey(bucketName, name), tmp);
_flush(cache.exists);
cache.harakiri.touch();
int index;
while ((index = name.lastIndexOf('/')) != -1) {
name = name.substring(0, index);
cache.exists.put(toKey(bucketName, name), new ParentObject(this, bucketName, name, validUntil, log));
_flush(cache.exists);
cache.harakiri.touch();
}
}

Expand Down Expand Up @@ -1144,21 +1146,21 @@ public S3Info get(String bucketName, final String objectName) throws S3Exception
targetName = summary.getKey();
if (nameFile.equals(targetName) || nameDir.equals(targetName)) {
cache.exists.put(toKey(bucketName, nameFile), info = new StorageObjectWrapper(this, stoObj = summary, validUntil, log));
_flush(cache.exists);
cache.harakiri.touch();
}

// pseudo directory?
// if (info == null) {
targetName = summary.getKey();
if (nameDir.length() < targetName.length() && targetName.startsWith(nameDir)) {
cache.exists.put(toKey(bucketName, nameFile), info = new ParentObject(this, bucketName, nameDir, validUntil, log));
_flush(cache.exists);
cache.harakiri.touch();
}

// set the value to exist when not a match
if (!(stoObj != null && stoObj.equals(summary))) {
cache.exists.put(toKey(bucketName, summary.getKey()), new StorageObjectWrapper(this, summary, validUntil, log));
_flush(cache.exists);
cache.harakiri.touch();
}
// set all the parents when not exist
// TODO handle that also a file with that name can exist at the same time
Expand All @@ -1167,7 +1169,7 @@ public S3Info get(String bucketName, final String objectName) throws S3Exception
while ((index = parent.lastIndexOf('/')) != -1) {
parent = parent.substring(0, index);
cache.exists.put(toKey(bucketName, parent), new ParentObject(this, bucketName, parent, validUntil, log));
_flush(cache.exists);
cache.harakiri.touch();
}

}
Expand All @@ -1181,7 +1183,7 @@ public S3Info get(String bucketName, final String objectName) throws S3Exception
// does
// not exis
);
_flush(cache.exists);
cache.harakiri.touch();
}
return info;
}
Expand Down Expand Up @@ -1547,20 +1549,6 @@ else if (isS3Info.booleanValue() && ((S3Info) e.getValue()).validUntil() < now)
}
}

private void _flush(Map<String, S3Info> map) {
if (++existCheckIntervall < CHECK_INTERVALL) return;
existCheckIntervall = 0;
Iterator<Entry<String, S3Info>> it = map.entrySet().iterator();
Entry<String, S3Info> e;
long now = System.currentTimeMillis();
while (it.hasNext()) {
e = it.next();
if (e.getValue().validUntil() < now) {
map.remove(e.getKey());
}
}
}

/**
*
* @param bucketName target bucket to create if not already exists
Expand Down Expand Up @@ -2717,4 +2705,5 @@ public void shutdown() throws S3Exception {
public long getLiveTimeout() {
return liveTimeout;
}

}

0 comments on commit 0010427

Please sign in to comment.