Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit a37ede3

Browse files
authored
Avoid using temporary directory if possible (#720)
Miniflare 2 persisted data in-memory between `setOptions()` calls when `*Persist` options were disabled. Whilst `workerd` has in-memory storage for Durable Objects, this is reset when `workerd` is restarted (i.e. when `setOptions()` is called). To retain Miniflare 2 behaviour in Miniflare 3, we actually persist to a temporary directory when `*Persist` options are disabled. There are cases where we don't need the temporary directory though: if we have no storage bindings configured, `cache` is `false`, and `unsafeEphemeralDurableObjects` is `true`. This change ensures we don't write to the temporary directory in these cases.
1 parent 4248f72 commit a37ede3

File tree

4 files changed

+63
-48
lines changed

4 files changed

+63
-48
lines changed

packages/miniflare/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,8 @@ export class Miniflare {
943943
}
944944

945945
// Collect all services required by this worker
946+
const unsafeEphemeralDurableObjects =
947+
workerOpts.core.unsafeEphemeralDurableObjects ?? false;
946948
const pluginServicesOptionsBase: Omit<
947949
PluginServicesOptions<z.ZodTypeAny, undefined>,
948950
"options" | "sharedOptions"
@@ -954,6 +956,7 @@ export class Miniflare {
954956
tmpPath: this.#tmpPath,
955957
workerNames,
956958
durableObjectClassNames,
959+
unsafeEphemeralDurableObjects,
957960
queueConsumers,
958961
};
959962
for (const [key, plugin] of PLUGIN_ENTRIES) {

packages/miniflare/src/plugins/cache/index.ts

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -85,57 +85,58 @@ export const CACHE_PLUGIN: Plugin<
8585
],
8686
};
8787
}
88+
const services: Service[] = [
89+
{ name: getCacheServiceName(workerIndex), worker: entryWorker },
90+
];
8891

89-
const uniqueKey = `miniflare-${CACHE_OBJECT_CLASS_NAME}`;
92+
if (cache) {
93+
const uniqueKey = `miniflare-${CACHE_OBJECT_CLASS_NAME}`;
9094

91-
const persist = sharedOptions.cachePersist;
92-
const persistPath = getPersistPath(CACHE_PLUGIN_NAME, tmpPath, persist);
93-
await fs.mkdir(persistPath, { recursive: true });
94-
const storageService: Service = {
95-
name: CACHE_STORAGE_SERVICE_NAME,
96-
disk: { path: persistPath, writable: true },
97-
};
98-
const objectService: Service = {
99-
name: CACHE_SERVICE_PREFIX,
100-
worker: {
101-
compatibilityDate: "2023-07-24",
102-
compatibilityFlags: ["nodejs_compat", "experimental"],
103-
modules: [
104-
{
105-
name: "cache.worker.js",
106-
esModule: SCRIPT_CACHE_OBJECT(),
107-
},
108-
],
109-
durableObjectNamespaces: [
110-
{
111-
className: CACHE_OBJECT_CLASS_NAME,
112-
uniqueKey,
113-
},
114-
],
115-
// Store Durable Object SQL databases in persist path
116-
durableObjectStorage: { localDisk: CACHE_STORAGE_SERVICE_NAME },
117-
// Bind blob disk directory service to object
118-
bindings: [
119-
{
120-
name: SharedBindings.MAYBE_SERVICE_BLOBS,
121-
service: { name: CACHE_STORAGE_SERVICE_NAME },
122-
},
123-
{
124-
name: SharedBindings.MAYBE_SERVICE_LOOPBACK,
125-
service: { name: SERVICE_LOOPBACK },
126-
},
127-
],
128-
},
129-
};
95+
const persist = sharedOptions.cachePersist;
96+
const persistPath = getPersistPath(CACHE_PLUGIN_NAME, tmpPath, persist);
97+
await fs.mkdir(persistPath, { recursive: true });
98+
const storageService: Service = {
99+
name: CACHE_STORAGE_SERVICE_NAME,
100+
disk: { path: persistPath, writable: true },
101+
};
102+
const objectService: Service = {
103+
name: CACHE_SERVICE_PREFIX,
104+
worker: {
105+
compatibilityDate: "2023-07-24",
106+
compatibilityFlags: ["nodejs_compat", "experimental"],
107+
modules: [
108+
{
109+
name: "cache.worker.js",
110+
esModule: SCRIPT_CACHE_OBJECT(),
111+
},
112+
],
113+
durableObjectNamespaces: [
114+
{
115+
className: CACHE_OBJECT_CLASS_NAME,
116+
uniqueKey,
117+
},
118+
],
119+
// Store Durable Object SQL databases in persist path
120+
durableObjectStorage: { localDisk: CACHE_STORAGE_SERVICE_NAME },
121+
// Bind blob disk directory service to object
122+
bindings: [
123+
{
124+
name: SharedBindings.MAYBE_SERVICE_BLOBS,
125+
service: { name: CACHE_STORAGE_SERVICE_NAME },
126+
},
127+
{
128+
name: SharedBindings.MAYBE_SERVICE_LOOPBACK,
129+
service: { name: SERVICE_LOOPBACK },
130+
},
131+
],
132+
},
133+
};
134+
services.push(storageService, objectService);
130135

131-
// NOTE: not migrating here as applications should be able to recover from
132-
// cache evictions, and we'd need to locate all named caches
136+
// NOTE: not migrating here as applications should be able to recover from
137+
// cache evictions, and we'd need to locate all named caches
138+
}
133139

134-
const services: Service[] = [
135-
{ name: getCacheServiceName(workerIndex), worker: entryWorker },
136-
storageService,
137-
objectService,
138-
];
139140
return services;
140141
},
141142
};

packages/miniflare/src/plugins/do/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ export const DURABLE_OBJECTS_PLUGIN: Plugin<
7171
const objects = Object.keys(options.durableObjects ?? {});
7272
return Object.fromEntries(objects.map((name) => [name, kProxyNodeBinding]));
7373
},
74-
async getServices({ sharedOptions, tmpPath, durableObjectClassNames }) {
74+
async getServices({
75+
sharedOptions,
76+
tmpPath,
77+
durableObjectClassNames,
78+
unsafeEphemeralDurableObjects,
79+
}) {
7580
// Check if we even have any Durable Object bindings, if we don't, we can
7681
// skip creating the storage directory
7782
let hasDurableObjects = false;
@@ -83,6 +88,11 @@ export const DURABLE_OBJECTS_PLUGIN: Plugin<
8388
}
8489
if (!hasDurableObjects) return;
8590

91+
// If this worker has enabled `unsafeEphemeralDurableObjects`, it won't need
92+
// the Durable Object storage service. If all workers have this enabled, we
93+
// don't need to create the storage service at all.
94+
if (unsafeEphemeralDurableObjects) return;
95+
8696
const storagePath = getPersistPath(
8797
DURABLE_OBJECTS_PLUGIN_NAME,
8898
tmpPath,

packages/miniflare/src/plugins/shared/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export interface PluginServicesOptions<
4040

4141
// ~~Leaky abstractions~~ "Plugin specific options" :)
4242
durableObjectClassNames: DurableObjectClassNames;
43+
unsafeEphemeralDurableObjects: boolean;
4344
queueConsumers: QueueConsumers;
4445
}
4546

0 commit comments

Comments
 (0)