Skip to content

Commit

Permalink
Make MemoryCache id optional, and include owner id on lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
jasnell committed Feb 14, 2024
1 parent 7110195 commit b3a28c6
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 12 deletions.
12 changes: 7 additions & 5 deletions src/workerd/api/memory-cache.c++
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ public:

// Gets an existing SharedMemoryCache instance or creates a new one if no
// cache with the given id exists.
SharedMemoryCache& getInstance(kj::StringPtr cacheId) const override;
SharedMemoryCache& getInstance(kj::StringPtr cacheId, uint32_t ownerId) const override;

private:
using HashMap = kj::HashMap<kj::String, kj::Own<SharedMemoryCache>>;
Expand All @@ -416,17 +416,19 @@ private:
// SharedMemoryCache::uuid() instead.
};

SharedMemoryCache& MemoryCacheMap::getInstance(kj::StringPtr cacheId) const {
SharedMemoryCache& MemoryCacheMap::getInstance(
kj::StringPtr cacheId, uint32_t ownerId) const {
auto lock = caches.lockExclusive();
return *lock->findOrCreate(cacheId, [this, &cacheId]() {
auto id = kj::str(cacheId, "::", ownerId);
return *lock->findOrCreate(id, [this, &id]() {
auto handler = additionalResizeMemoryLimitHandler.map([](
const SharedMemoryCache::AdditionalResizeMemoryLimitHandler& handler)
-> SharedMemoryCache::AdditionalResizeMemoryLimitHandler& {
return const_cast<SharedMemoryCache::AdditionalResizeMemoryLimitHandler&>(handler);
});
return HashMap::Entry{
kj::str(cacheId),
kj::heap<SharedMemoryCache>(cacheId, handler)
kj::str(id),
kj::heap<SharedMemoryCache>(id, handler)
};
});
}
Expand Down
3 changes: 2 additions & 1 deletion src/workerd/api/memory-cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,8 @@ class MemoryCache: public jsg::Object {
// uses a simple in-memory map to store the SharedMemoryCache instances.
class MemoryCacheProvider {
public:
virtual SharedMemoryCache& getInstance(kj::StringPtr cacheId) const = 0;
virtual ~MemoryCacheProvider() noexcept(false) = default;
virtual SharedMemoryCache& getInstance(kj::StringPtr cacheId, uint32_t ownerId) const = 0;

static kj::Own<MemoryCacheProvider> createDefault(
kj::Maybe<SharedMemoryCache::AdditionalResizeMemoryLimitHandler> additionalResizeMemoryLimitHandler = kj::none);
Expand Down
3 changes: 0 additions & 3 deletions src/workerd/api/tests/memory-cache-test.wd-test
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,20 @@ const unitTests :Workerd.Config = (
compatibilityFlags = ["nodejs_compat"],
bindings = [
(name = "CACHE", memoryCache = (
id = "abc123",
limits = (
maxKeys = 2,
maxValueSize = 1024,
maxTotalValueSize = 2056,
),
)),
(name = "CACHE2", memoryCache = (
id = "abc321",
limits = (
maxKeys = 2,
maxValueSize = 1024,
maxTotalValueSize = 2056,
),
)),
(name = "CACHE3", memoryCache = (
id = "xyz321",
limits = (
maxKeys = 2,
maxValueSize = 500,
Expand Down
13 changes: 11 additions & 2 deletions src/workerd/server/server.c++
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <workerd/util/http-util.h>
#include <workerd/api/actor-state.h>
#include <workerd/util/mimetype.h>
#include <workerd/util/uuid.h>
#include <workerd/util/use-perfetto-categories.h>
#include "workerd-api.h"
#include "workerd/io/hibernation-manager.h"
Expand Down Expand Up @@ -2423,9 +2424,17 @@ static kj::Maybe<WorkerdApi::Global> createBinding(
}
case config::Worker::Binding::MEMORY_CACHE: {
auto cache = binding.getMemoryCache();
KJ_REQUIRE(cache.hasId() && cache.hasLimits());
// TODO(cleanup): Should we have some reasonable default for these so they can
// be optional?
KJ_REQUIRE(cache.hasLimits());
Global::MemoryCache cacheCopy;
cacheCopy.cacheId = kj::str(cache.getId());
// The id is optional. If provided, then multiple bindings with the same id will
// share the same cache. Otherwise, a unique id is generated for the cache.
if (cache.hasId()) {
cacheCopy.cacheId = kj::str(cache.getId());
} else {
cacheCopy.cacheId = randomUUID(kj::none);
}
auto limits = cache.getLimits();
cacheCopy.maxKeys = limits.getMaxKeys();
cacheCopy.maxValueSize = limits.getMaxValueSize();
Expand Down
3 changes: 2 additions & 1 deletion src/workerd/server/workerd-api.c++
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,8 @@ static v8::Local<v8::Value> createBindingValue(
api::SharedMemoryCache::Limits limits = {.maxKeys = cache.maxKeys,
.maxValueSize = cache.maxValueSize,
.maxTotalValueSize = cache.maxTotalValueSize};
api::SharedMemoryCache& sharedCache = memoryCacheProvider.getInstance(cache.cacheId);
api::SharedMemoryCache& sharedCache =
memoryCacheProvider.getInstance(cache.cacheId, ownerId);
api::SharedMemoryCache::Use cacheUse(sharedCache, limits);
value = lock.wrap(context, jsg::alloc<api::MemoryCache>(kj::mv(cacheUse)));
}
Expand Down

0 comments on commit b3a28c6

Please sign in to comment.