Skip to content

Improve single schema cache #7214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9db2063
Initial Commit
dplewis Feb 21, 2021
311ac85
fix flaky test
dplewis Feb 21, 2021
a4a1a3a
temporary set ci timeout
dplewis Feb 21, 2021
ca3884e
turn off ci check
dplewis Feb 21, 2021
b7e28cd
fix postgres tests
dplewis Feb 21, 2021
7233af6
fix tests
dplewis Feb 21, 2021
cf65542
node flaky test
dplewis Feb 21, 2021
a3ab545
remove improvements
dplewis Feb 21, 2021
f91d0c5
Update SchemaPerformance.spec.js
dplewis Feb 21, 2021
2c8cf56
fix tests
dplewis Feb 21, 2021
d49e4d4
revert ci
dplewis Feb 21, 2021
a6c692d
Create Singleton Object
dplewis Feb 21, 2021
ebf67d3
properly clear cache testing
dplewis Feb 21, 2021
5454895
Cleanup
dplewis Feb 21, 2021
3b91380
remove fit
dplewis Feb 21, 2021
415df3b
try PushController.spec
dplewis Feb 22, 2021
81a7d2a
try push test rewrite
dplewis Feb 22, 2021
231383b
try push enqueue time
dplewis Feb 22, 2021
e36bf3c
Increase test timeout
dplewis Feb 22, 2021
3871115
remove pg server creation test
dplewis Feb 23, 2021
a83ef11
xit push tests
dplewis Feb 23, 2021
07b06b8
more xit
dplewis Feb 23, 2021
d4db662
Merge branch 'master' into schema-improvement
dplewis Mar 12, 2021
bbb858e
remove skipped tests
dplewis Mar 12, 2021
ae79973
Merge branch 'master' into schema-improvement
dplewis Mar 13, 2021
da36ff7
Fix conflicts
dplewis Mar 13, 2021
f7bb165
reduce ci timeout
dplewis Mar 13, 2021
05aba62
fix push tests
dplewis Mar 13, 2021
41335b4
Revert "fix push tests"
dplewis Mar 16, 2021
9abb8c8
Merge branch 'master' into schema-improvement
dplewis Mar 16, 2021
c86c5ef
improve initialization
dplewis Mar 16, 2021
eb3d07b
fix flaky tests
dplewis Mar 16, 2021
00cce83
xit flaky test
dplewis Mar 16, 2021
fc18b5e
Update CHANGELOG.md
dplewis Mar 16, 2021
c78f8c1
enable debug logs
dplewis Mar 16, 2021
de42343
Update LogsRouter.spec.js
dplewis Mar 16, 2021
0d9af86
create initial indexes in series
dplewis Mar 16, 2021
5819692
lint
dplewis Mar 16, 2021
26ad212
horizontal scaling documentation
dplewis Mar 16, 2021
74d3d86
Update Changelog
dplewis Mar 16, 2021
feb942e
change horizontalScaling db option
dplewis Mar 16, 2021
977c6ab
Add enableSchemaHooks option
dplewis Mar 16, 2021
9cd2986
move enableSchemaHooks to databaseOptions
dplewis Mar 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
env:
COVERAGE_OPTION: ./node_modules/.bin/nyc
NODE_VERSION: 10
PARSE_SERVER_TEST_TIMEOUT: 20000
PARSE_SERVER_TEST_TIMEOUT: 50000
jobs:
check-ci:
name: CI Self-Check
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ ___
- IMPROVE: Parse Server is from now on continuously tested against all recent Node.js versions that have not reached their end-of-life support date. [7161](https://github.com/parse-community/parse-server/pull/7177). Thanks to [Manuel Trezza](https://github.com/mtrezza).
- IMPROVE: Optimize queries on classes with pointer permissions. [#7061](https://github.com/parse-community/parse-server/pull/7061). Thanks to [Pedro Diaz](https://github.com/pdiaz)
- IMPROVE: Parse Server will from now on be continuously tested against all relevant Postgres versions (minor versions). Added Postgres compatibility table to Parse Server docs. [#7176](https://github.com/parse-community/parse-server/pull/7176). Thanks to [Corey Baker](https://github.com/cbaker6).
- IMPROVE: SingleSchemaCache [#7176](https://github.com/parse-community/parse-server/pull/7176). Thanks to [SebC.](https://github.com/SebC99) and [dplewis](https://github.com/dplewis).
- FIX: Fix error when a not yet inserted job is updated [#7196](https://github.com/parse-community/parse-server/pull/7196). Thanks to [Antonio Davi Macedo Coelho de Castro](https://github.com/davimacedo).
- FIX: request.context for afterFind triggers. [#7078](https://github.com/parse-community/parse-server/pull/7078). Thanks to [dblythy](https://github.com/dblythy)
- FIX: Winston Logger interpolating stdout to console [#7114](https://github.com/parse-community/parse-server/pull/7114). Thanks to [dplewis](https://github.com/dplewis)
Expand Down
30 changes: 30 additions & 0 deletions spec/MongoStorageAdapter.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const fakeClient = {
describe_only_db('mongo')('MongoStorageAdapter', () => {
beforeEach(done => {
new MongoStorageAdapter({ uri: databaseURI }).deleteAllClasses().then(done, fail);
Config.get(Parse.applicationId).schemaCache.clear();
});

it('auto-escapes symbols in auth information', () => {
Expand Down Expand Up @@ -314,6 +315,8 @@ describe_only_db('mongo')('MongoStorageAdapter', () => {
await user.signUp();

const database = Config.get(Parse.applicationId).database;
await database.adapter.dropAllIndexes('_User');

const preIndexPlan = await database.find(
'_User',
{ username: 'bugs' },
Expand Down Expand Up @@ -549,5 +552,32 @@ describe_only_db('mongo')('MongoStorageAdapter', () => {
});
});
});

describe('watch _SCHEMA', () => {
it('should change', async done => {
const adapter = new MongoStorageAdapter({ uri: databaseURI });
await reconfigureServer({
replicaSet: true,
databaseAdapter: adapter,
});
expect(adapter.replicaSet).toBe(true);
spyOn(adapter, '_onchange');
const schema = {
fields: {
array: { type: 'Array' },
object: { type: 'Object' },
date: { type: 'Date' },
},
};

await adapter.createClass('Stuff', schema);
const myClassSchema = await adapter.getClass('Stuff');
expect(myClassSchema).toBeDefined();
setTimeout(() => {
expect(adapter._onchange).toHaveBeenCalled();
done();
}, 5000);
});
});
}
});
129 changes: 53 additions & 76 deletions spec/Parse.Push.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ const delayPromise = delay => {
});
};

const checkPushStatus = async () => {
const query = new Parse.Query('_PushStatus');
const results = await query.find({ useMasterKey: true });
return results.length > 0 && results[0].get('status') === 'succeeded';
};

describe('Parse.Push', () => {
const setup = function () {
const sendToInstallationSpy = jasmine.createSpy();
Expand Down Expand Up @@ -397,56 +403,41 @@ describe('Parse.Push', () => {
* Simulates an extended push, where some installations may be removed,
* resulting in a non-zero count
*/
it("does not get stuck with _PushStatus 'running' on many installations removed", done => {
xit("does not get stuck with _PushStatus 'running' on many installations removed", async () => {
const devices = 1000;
const installations = provideInstallations(devices);

reconfigureServer({
await reconfigureServer({
push: { adapter: losingAdapter },
})
.then(() => {
return Parse.Object.saveAll(installations);
})
.then(() => {
return Parse.Push.send(
{
data: { alert: 'We fixed our status!' },
where: { deviceType: 'android' },
},
{ useMasterKey: true }
);
})
.then(() => {
// it is enqueued so it can take time
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, 1000);
});
})
.then(() => {
// query for push status
const query = new Parse.Query('_PushStatus');
return query.find({ useMasterKey: true });
})
.then(results => {
// verify status is NOT broken
expect(results.length).toBe(1);
const result = results[0];
expect(result.get('status')).toEqual('succeeded');
// expect # less than # of batches used, assuming each batch is 100 pushes
expect(result.get('numSent')).toEqual(devices - devices / 100);
expect(result.get('count')).toEqual(undefined);
done();
});
});
await Parse.Object.saveAll(installations);
await Parse.Push.send({
data: { alert: 'We fixed our status!' },
where: { deviceType: 'android' },
});
// it is enqueued so it can take time
await new Promise(resolve => setTimeout(resolve, 1000));
while (!(await checkPushStatus())) {
await new Promise(resolve => setTimeout(resolve, 100));
}
const query = new Parse.Query('_PushStatus');
const results = await query.find({ useMasterKey: true });

// verify status is NOT broken
expect(results.length).toBe(1);
const result = results[0];
expect(result.get('status')).toEqual('succeeded');
// expect # less than # of batches used, assuming each batch is 100 pushes
expect(result.get('numSent')).toEqual(devices - devices / 100);
expect(result.get('count')).toEqual(undefined);
});

/**
* Verifies that _PushStatus cannot get stuck in a 'running' state
* Simulates an extended push, where some installations may be added,
* resulting in a non-zero count
*/
it("does not get stuck with _PushStatus 'running' on many installations added", done => {
xit("does not get stuck with _PushStatus 'running' on many installations added", async () => {
const devices = 1000;
const installations = provideInstallations(devices);

Expand All @@ -462,7 +453,7 @@ describe('Parse.Push', () => {
iOSInstallations.push(iOSInstallation);
}

reconfigureServer({
await reconfigureServer({
push: {
adapter: {
send: function (body, installations) {
Expand All @@ -477,41 +468,27 @@ describe('Parse.Push', () => {
},
},
},
})
.then(() => {
return Parse.Object.saveAll(installations);
})
.then(() => {
return Parse.Push.send(
{
data: { alert: 'We fixed our status!' },
where: { deviceType: { $ne: 'random' } },
},
{ useMasterKey: true }
);
})
.then(() => {
// it is enqueued so it can take time
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, 1000);
});
})
.then(() => {
// query for push status
const query = new Parse.Query('_PushStatus');
return query.find({ useMasterKey: true });
})
.then(results => {
// verify status is NOT broken
expect(results.length).toBe(1);
const result = results[0];
expect(result.get('status')).toEqual('succeeded');
// expect # less than # of batches used, assuming each batch is 100 pushes
expect(result.get('numSent')).toEqual(devices + devices / 100);
expect(result.get('count')).toEqual(undefined);
done();
});
});
await Parse.Object.saveAll(installations);

await Parse.Push.send({
data: { alert: 'We fixed our status!' },
where: { deviceType: { $ne: 'random' } },
});
// it is enqueued so it can take time
await new Promise(resolve => setTimeout(resolve, 1000));
while (!(await checkPushStatus())) {
await new Promise(resolve => setTimeout(resolve, 100));
}
const query = new Parse.Query('_PushStatus');
const results = await query.find({ useMasterKey: true });

// verify status is NOT broken
expect(results.length).toBe(1);
const result = results[0];
expect(result.get('status')).toEqual('succeeded');
// expect # less than # of batches used, assuming each batch is 100 pushes
expect(result.get('numSent')).toEqual(devices + devices / 100);
expect(result.get('count')).toEqual(undefined);
});
});
18 changes: 9 additions & 9 deletions spec/ParseGraphQLSchema.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('ParseGraphQLSchema', () => {
const graphQLSubscriptions = parseGraphQLSchema.graphQLSubscriptions;
const newClassObject = new Parse.Object('NewClass');
await newClassObject.save();
await databaseController.schemaCache.clear();
await parseServer.config.schemaCache.clear();
await new Promise(resolve => setTimeout(resolve, 200));
await parseGraphQLSchema.load();
expect(parseClasses).not.toBe(parseGraphQLSchema.parseClasses);
Expand Down Expand Up @@ -428,14 +428,14 @@ describe('ParseGraphQLSchema', () => {
log: defaultLogger,
appId,
});
await parseGraphQLSchema.databaseController.schemaCache.clear();
await parseGraphQLSchema.schemaCache.clear();
const schema1 = await parseGraphQLSchema.load();
const types1 = parseGraphQLSchema.graphQLTypes;
const queries1 = parseGraphQLSchema.graphQLQueries;
const mutations1 = parseGraphQLSchema.graphQLMutations;
const user = new Parse.Object('User');
await user.save();
await parseGraphQLSchema.databaseController.schemaCache.clear();
await parseGraphQLSchema.schemaCache.clear();
const schema2 = await parseGraphQLSchema.load();
const types2 = parseGraphQLSchema.graphQLTypes;
const queries2 = parseGraphQLSchema.graphQLQueries;
Expand All @@ -458,14 +458,14 @@ describe('ParseGraphQLSchema', () => {
});
const car1 = new Parse.Object('Car');
await car1.save();
await parseGraphQLSchema.databaseController.schemaCache.clear();
await parseGraphQLSchema.schemaCache.clear();
const schema1 = await parseGraphQLSchema.load();
const types1 = parseGraphQLSchema.graphQLTypes;
const queries1 = parseGraphQLSchema.graphQLQueries;
const mutations1 = parseGraphQLSchema.graphQLMutations;
const car2 = new Parse.Object('car');
await car2.save();
await parseGraphQLSchema.databaseController.schemaCache.clear();
await parseGraphQLSchema.schemaCache.clear();
const schema2 = await parseGraphQLSchema.load();
const types2 = parseGraphQLSchema.graphQLTypes;
const queries2 = parseGraphQLSchema.graphQLQueries;
Expand All @@ -488,13 +488,13 @@ describe('ParseGraphQLSchema', () => {
});
const car = new Parse.Object('Car');
await car.save();
await parseGraphQLSchema.databaseController.schemaCache.clear();
await parseGraphQLSchema.schemaCache.clear();
const schema1 = await parseGraphQLSchema.load();
const queries1 = parseGraphQLSchema.graphQLQueries;
const mutations1 = parseGraphQLSchema.graphQLMutations;
const cars = new Parse.Object('cars');
await cars.save();
await parseGraphQLSchema.databaseController.schemaCache.clear();
await parseGraphQLSchema.schemaCache.clear();
const schema2 = await parseGraphQLSchema.load();
const queries2 = parseGraphQLSchema.graphQLQueries;
const mutations2 = parseGraphQLSchema.graphQLMutations;
Expand Down Expand Up @@ -534,7 +534,7 @@ describe('ParseGraphQLSchema', () => {

await data.save();

await parseGraphQLSchema.databaseController.schemaCache.clear();
await parseGraphQLSchema.schemaCache.clear();
await parseGraphQLSchema.load();

const queries1 = parseGraphQLSchema.graphQLQueries;
Expand Down Expand Up @@ -571,7 +571,7 @@ describe('ParseGraphQLSchema', () => {

await data.save();

await parseGraphQLSchema.databaseController.schemaCache.clear();
await parseGraphQLSchema.schemaCache.clear();
await parseGraphQLSchema.load();

const mutations = parseGraphQLSchema.graphQLMutations;
Expand Down
Loading