Skip to content

Commit 832417d

Browse files
committed
make the schema cache seperate to avoid serialization/deserialization
1 parent 5bfd481 commit 832417d

File tree

3 files changed

+106
-65
lines changed

3 files changed

+106
-65
lines changed

src/Controllers/SchemaCache.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const MAIN_SCHEMA = "__MAIN_SCHEMA";
2+
const SCHEMA_INFO = "__SCHEMA_INFO";
23
const SCHEMA_CACHE_PREFIX = "__SCHEMA";
34
const ALL_KEYS = "__ALL_KEYS";
45

@@ -39,6 +40,20 @@ export default class SchemaCache {
3940
return this.put(this.prefix+MAIN_SCHEMA, schema);
4041
}
4142

43+
getSchemaInfo() {
44+
if (!this.ttl) {
45+
return Promise.resolve(null);
46+
}
47+
return this.cache.get(this.prefix+SCHEMA_INFO);
48+
}
49+
50+
setSchemaInfo(info) {
51+
if (!this.ttl) {
52+
return Promise.resolve(null);
53+
}
54+
return this.put(this.prefix+SCHEMA_INFO, info);
55+
}
56+
4257
setOneSchema(className, schema) {
4358
if (!this.ttl) {
4459
return Promise.resolve(null);

src/Controllers/SchemaController.js

Lines changed: 86 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -323,74 +323,99 @@ export default class SchemaController {
323323
}
324324

325325
reloadData(options = {clearCache: false}) {
326-
if (options.clearCache) {
327-
this._cache.clear();
328-
}
329326
if (this.reloadDataPromise && !options.clearCache) {
330327
return this.reloadDataPromise;
331328
}
332-
this.data = {};
333-
this.perms = {};
334-
this.reloadDataPromise = this.getAllClasses(options)
335-
.then(allSchemas => {
336-
allSchemas.forEach(schema => {
337-
this.data[schema.className] = injectDefaultSchema(schema).fields;
338-
this.perms[schema.className] = schema.classLevelPermissions;
339-
});
340-
341-
// Inject the in-memory classes
342-
volatileClasses.forEach(className => {
343-
this.data[className] = injectDefaultSchema({
344-
className,
345-
fields: {},
346-
classLevelPermissions: {}
347-
});
329+
this.reloadDataPromise = Promise.resolve()
330+
.then(() => {
331+
if (options.clearCache) {
332+
return this._cache.clear().then(() => {});
333+
}
334+
return this._cache.getSchemaInfo()
335+
})
336+
.then(schemaInfo => {
337+
if (schemaInfo) {
338+
return schemaInfo;
339+
}
340+
return this.getAllClasses(options)
341+
.then(allSchemas => {
342+
const data = {};
343+
const perms = {}
344+
allSchemas.forEach(schema => {
345+
data[schema.className] = injectDefaultSchema(schema).fields;
346+
perms[schema.className] = schema.classLevelPermissions;
347+
});
348+
349+
// Inject the in-memory classes
350+
volatileClasses.forEach(className => {
351+
data[className] = injectDefaultSchema({
352+
className,
353+
fields: {},
354+
classLevelPermissions: {}
355+
});
356+
});
357+
const schemaInfo = {data: Object.freeze(data), perms: Object.freeze(perms)};
358+
this._cache.setSchemaInfo(schemaInfo);
359+
return schemaInfo;
360+
});
361+
})
362+
.then(schemaInfo => {
363+
this.data = schemaInfo.data;
364+
this.perms = schemaInfo.perms;
365+
delete this.reloadDataPromise;
366+
}, (err) => {
367+
delete this.reloadDataPromise;
368+
throw err;
348369
});
349-
delete this.reloadDataPromise;
350-
}, (err) => {
351-
delete this.reloadDataPromise;
352-
throw err;
353-
});
354370
return this.reloadDataPromise;
355371
}
356372

357373
getAllClasses(options = {clearCache: false}) {
358-
if (options.clearCache) {
359-
this._cache.clear();
360-
}
361-
return this._cache.getAllClasses().then((allClasses) => {
362-
if (allClasses && allClasses.length && !options.clearCache) {
363-
return Promise.resolve(allClasses);
364-
}
365-
return this._dbAdapter.getAllClasses()
366-
.then(allSchemas => allSchemas.map(injectDefaultSchema))
367-
.then(allSchemas => {
368-
return this._cache.setAllClasses(allSchemas).then(() => {
369-
return allSchemas;
370-
});
371-
})
372-
});
374+
return Promise.resolve()
375+
.then(() => {
376+
if (options.clearCache) {
377+
return this._cache.clear();
378+
}
379+
})
380+
.then(() => this._cache.getAllClasses())
381+
.then((allClasses) => {
382+
if (allClasses && allClasses.length && !options.clearCache) {
383+
return Promise.resolve(allClasses);
384+
}
385+
return this._dbAdapter.getAllClasses()
386+
.then(allSchemas => allSchemas.map(injectDefaultSchema))
387+
.then(allSchemas => {
388+
return this._cache.setAllClasses(Object.freeze(allSchemas)).then(() => {
389+
return allSchemas;
390+
});
391+
})
392+
});
373393
}
374394

375395
getOneSchema(className, allowVolatileClasses = false, options = {clearCache: false}) {
376-
if (options.clearCache) {
377-
this._cache.clear();
378-
}
379-
if (allowVolatileClasses && volatileClasses.indexOf(className) > -1) {
380-
return Promise.resolve(this.data[className]);
381-
}
382-
return this._cache.getOneSchema(className).then((cached) => {
383-
if (cached && !options.clearCache) {
384-
return Promise.resolve(cached);
385-
}
386-
return this._dbAdapter.getClass(className)
387-
.then(injectDefaultSchema)
388-
.then((result) => {
389-
return this._cache.setOneSchema(className, result).then(() => {
390-
return result;
391-
})
396+
return Promise.resolve()
397+
.then(() => {
398+
if (options.clearCache) {
399+
return this._cache.clear();
400+
}
401+
})
402+
.then(() => {
403+
if (allowVolatileClasses && volatileClasses.indexOf(className) > -1) {
404+
return Promise.resolve(this.data[className]);
405+
}
406+
return this._cache.getOneSchema(className).then((cached) => {
407+
if (cached && !options.clearCache) {
408+
return Promise.resolve(cached);
409+
}
410+
return this._dbAdapter.getClass(className)
411+
.then(injectDefaultSchema)
412+
.then((result) => {
413+
return this._cache.setOneSchema(className, result).then(() => {
414+
return result;
415+
})
416+
});
417+
});
392418
});
393-
});
394419
}
395420

396421
// Create a new class that includes the three default fields.
@@ -409,8 +434,7 @@ export default class SchemaController {
409434
return this._dbAdapter.createClass(className, convertSchemaToAdapterSchema({ fields, classLevelPermissions, className }))
410435
.then(convertAdapterSchemaToParseSchema)
411436
.then((res) => {
412-
this._cache.clear();
413-
return res;
437+
return this._cache.clear().then(() => res);
414438
})
415439
.catch(error => {
416440
if (error && error.code === Parse.Error.DUPLICATE_VALUE) {
@@ -621,9 +645,8 @@ export default class SchemaController {
621645
throw new Parse.Error(Parse.Error.INVALID_JSON, `Could not add field ${fieldName}`);
622646
}
623647
// Remove the cached schema
624-
this._cache.clear();
625-
return this;
626-
});
648+
return this._cache.clear();
649+
}).then(() => this)
627650
});
628651
}
629652

@@ -664,9 +687,8 @@ export default class SchemaController {
664687
.then(() => database.adapter.deleteClass(`_Join:${fieldName}:${className}`));
665688
}
666689
return database.adapter.deleteFields(className, schema, [fieldName]);
667-
}).then(() => {
668-
this._cache.clear();
669-
});
690+
})
691+
.then(() => this._cache.clear());
670692
}
671693

672694
// Validates an object provided in REST format.

src/ParseServer.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { AnalyticsRouter } from './Routers/AnalyticsRouter';
2424
import { ClassesRouter } from './Routers/ClassesRouter';
2525
import { FeaturesRouter } from './Routers/FeaturesRouter';
2626
import { InMemoryCacheAdapter } from './Adapters/Cache/InMemoryCacheAdapter';
27+
import { InMemoryObjectCacheAdapter } from './Adapters/Cache/InMemoryObjectCacheAdapter';
2728
import { AnalyticsController } from './Controllers/AnalyticsController';
2829
import { CacheController } from './Controllers/CacheController';
2930
import { AnalyticsAdapter } from './Adapters/Analytics/AnalyticsAdapter';
@@ -183,11 +184,14 @@ class ParseServer {
183184
const cacheControllerAdapter = loadAdapter(cacheAdapter, InMemoryCacheAdapter, {appId: appId});
184185
const cacheController = new CacheController(cacheControllerAdapter, appId);
185186

187+
const schemaCacheControllerAdapter = loadAdapter(null, InMemoryObjectCacheAdapter, {appId: appId, ttl: schemaCacheTTL});
188+
const schemaCacheController = new CacheController(schemaCacheControllerAdapter, appId);
189+
186190
const analyticsControllerAdapter = loadAdapter(analyticsAdapter, AnalyticsAdapter);
187191
const analyticsController = new AnalyticsController(analyticsControllerAdapter);
188192

189193
const liveQueryController = new LiveQueryController(liveQuery);
190-
const databaseController = new DatabaseController(databaseAdapter, new SchemaCache(cacheController, schemaCacheTTL));
194+
const databaseController = new DatabaseController(databaseAdapter, new SchemaCache(schemaCacheController, schemaCacheTTL));
191195
const hooksController = new HooksController(appId, databaseController, webhookKey);
192196

193197
const dbInitPromise = databaseController.performInitizalization();

0 commit comments

Comments
 (0)