Merge pull request #3770 from strapi/chore/boostrap-async

make boostrap functions async only
This commit is contained in:
Alexandre BODIN 2019-08-12 17:33:27 +02:00 committed by GitHub
commit 5bd4b0d747
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 128 additions and 127 deletions

View File

@ -83,9 +83,36 @@ The `bootstrap` function is called at every server start. You can use it to add
Here are some use cases:
- Create an admin user if there isn't.
- Create an admin user if there isn't one.
- Fill the database with some necessary data.
- Check that the database is up-and-running.
- Load some envrionments variables.
The bootstrap function can be synchronous or asynchronous
**Synchronous**
```js
module.exports = () => {
// some sync code
};
```
**Return a promise**
```js
module.exports = () => {
return new Promise(/* some code */);
};
```
**Be async**
```js
module.exports = async () => {
await someSetup();
};
```
### CRON tasks

View File

@ -8,6 +8,4 @@
* run jobs, or perform some special logic.
*/
module.exports = cb => {
cb();
};
module.exports = () => {};

View File

@ -6,8 +6,8 @@
*
* This gives you an opportunity to set up your data model,
* run jobs, or perform some special logic.
*
* See more details here: https://strapi.io/documentation/3.0.0-beta.x/configurations/configurations.html#bootstrap
*/
module.exports = cb => {
cb();
};
module.exports = () => {};

View File

@ -10,8 +10,8 @@ const {
/**
* Synchronize content manager schemas
*/
module.exports = cb => {
syncSchemas().then(() => cb(), err => cb(err));
module.exports = () => {
return syncSchemas();
};
async function syncSchemas() {

View File

@ -2,11 +2,11 @@ const fs = require('fs');
const path = require('path');
const _ = require('lodash');
module.exports = async cb => {
module.exports = async () => {
// Check if the plugin users-permissions is installed because the documentation needs it
if (Object.keys(strapi.plugins).indexOf('users-permissions') === -1) {
throw new Error(
'In order to make the documentation plugin works the users-permissions one is required',
'In order to make the documentation plugin works the users-permissions one is required'
);
}
@ -26,16 +26,24 @@ module.exports = async cb => {
// Generate plugins' documentation
const pluginsWithDocumentationNeeded = services.getPluginsWithDocumentationNeeded();
pluginsWithDocumentationNeeded.forEach(plugin => {
const isDocExisting = services.checkIfPluginDocumentationFolderExists(plugin);
const isDocExisting = services.checkIfPluginDocumentationFolderExists(
plugin
);
if (!isDocExisting) {
services.createDocumentationDirectory(services.getPluginDocumentationPath(plugin));
services.createDocumentationDirectory(
services.getPluginDocumentationPath(plugin)
);
// create the overrides directory
services.createDocumentationDirectory(services.getPluginOverrideDocumentationPath(plugin));
services.createDocumentationDirectory(
services.getPluginOverrideDocumentationPath(plugin)
);
services.createPluginDocumentationFile(plugin);
shouldUpdateFullDoc = true;
} else {
const needToUpdatePluginDoc = services.checkIfPluginDocNeedsUpdate(plugin);
const needToUpdatePluginDoc = services.checkIfPluginDocNeedsUpdate(
plugin
);
if (needToUpdatePluginDoc) {
services.createPluginDocumentationFile(plugin);
@ -54,7 +62,9 @@ module.exports = async cb => {
// If the documentation directory doesn't exist create it
services.createDocumentationDirectory(services.getDocumentationPath(api));
// Create the overrides directory
services.createDocumentationDirectory(services.getDocumentationOverridesPath(api));
services.createDocumentationDirectory(
services.getDocumentationOverridesPath(api)
);
// Create the documentation files per version
services.createDocumentationFile(api); // Then create the {api}.json documentation file
shouldUpdateFullDoc = true;
@ -96,7 +106,10 @@ module.exports = async cb => {
.sort((a, b) => a - b)
.join('.');
};
const oldDoc = require(path.resolve(documentationPath, 'full_documentation.json'));
const oldDoc = require(path.resolve(
documentationPath,
'full_documentation.json'
));
const oldDocTags = getDocTagsToString(oldDoc);
const currentDocTags = getDocTagsToString(fullDoc);
@ -113,8 +126,7 @@ module.exports = async cb => {
fs.writeFileSync(
path.resolve(documentationPath, 'full_documentation.json'),
JSON.stringify(fullDoc, null, 2),
'utf8',
'utf8'
);
}
cb();
};

View File

@ -9,7 +9,7 @@
*/
const _ = require('lodash');
module.exports = async cb => {
module.exports = async () => {
// set plugin store
const pluginStore = strapi.store({
environment: strapi.config.environment,
@ -27,25 +27,18 @@ module.exports = async cb => {
strapi.plugins.email.config.providers.push(require(installedProvider));
}
try {
// if provider config does not exist set one by default
const config = await pluginStore.get({ key: 'provider' });
// if provider config does not exist set one by default
const config = await pluginStore.get({ key: 'provider' });
if (!config) {
const provider = _.find(strapi.plugins.email.config.providers, {
provider: 'sendmail',
});
if (!config) {
const provider = _.find(strapi.plugins.email.config.providers, {
provider: 'sendmail',
});
const value = _.assign({}, provider, {
// TODO: set other default settings here
});
const value = _.assign({}, provider, {
// TODO: set other default settings here
});
await pluginStore.set({ key: 'provider', value });
}
} catch (err) {
strapi.log.error(err);
strapi.stop();
await pluginStore.set({ key: 'provider', value });
}
cb();
};

View File

@ -8,20 +8,18 @@
* run jobs, or perform some special logic.
*/
module.exports = async cb => {
module.exports = async () => {
const pluginStore = strapi.store({
environment: '',
type: 'core'
type: 'core',
});
if (!await pluginStore.get({key: 'application'})) {
if (!(await pluginStore.get({ key: 'application' }))) {
const value = {
name: 'Default Application',
description: 'This API is going to be awesome!'
description: 'This API is going to be awesome!',
};
await pluginStore.set({key: 'application', value});
await pluginStore.set({ key: 'application', value });
}
cb();
};

View File

@ -9,7 +9,7 @@
*/
const _ = require('lodash');
module.exports = async cb => {
module.exports = async () => {
// set plugin store
const pluginStore = strapi.store({
environment: strapi.config.environment,
@ -27,26 +27,20 @@ module.exports = async cb => {
strapi.plugins.upload.config.providers.push(require(installedProvider));
}
try {
// if provider config does not exist set one by default
const config = await pluginStore.get({ key: 'provider' });
// if provider config does not exist set one by default
const config = await pluginStore.get({ key: 'provider' });
if (!config) {
const provider = _.find(strapi.plugins.upload.config.providers, {
provider: 'local',
});
if (!config) {
const provider = _.find(strapi.plugins.upload.config.providers, {
provider: 'local',
});
const value = _.assign({}, provider, {
enabled: true,
// by default limit size to 1 GB
sizeLimit: 1000000,
});
const value = _.assign({}, provider, {
enabled: true,
// by default limit size to 1 GB
sizeLimit: 1000000,
});
await pluginStore.set({ key: 'provider', value });
}
} catch (err) {
strapi.log.error(err);
strapi.stop();
await pluginStore.set({ key: 'provider', value });
}
cb();
};

View File

@ -10,12 +10,16 @@
const _ = require('lodash');
const uuid = require('uuid/v4');
module.exports = async cb => {
module.exports = async () => {
if (!_.get(strapi.plugins['users-permissions'], 'config.jwtSecret')) {
const jwtSecret = uuid();
_.set(strapi.plugins['users-permissions'], 'config.jwtSecret', jwtSecret);
await strapi.fs.writePluginFile('users-permissions', 'config/jwt.json', JSON.stringify({ jwtSecret }, null, 2));
await strapi.fs.writePluginFile(
'users-permissions',
'config/jwt.json',
JSON.stringify({ jwtSecret }, null, 2)
);
}
const pluginStore = strapi.store({
@ -144,14 +148,14 @@ module.exports = async cb => {
unique_email: true,
allow_register: true,
email_confirmation: false,
email_confirmation_redirection: `http://${
strapi.config.currentEnvironment.server.host
}:${strapi.config.currentEnvironment.server.port}/admin`,
email_confirmation_redirection: `http://${strapi.config.currentEnvironment.server.host}:${strapi.config.currentEnvironment.server.port}/admin`,
default_role: 'authenticated',
};
await pluginStore.set({ key: 'advanced', value });
}
strapi.plugins['users-permissions'].services.userspermissions.initialize(cb);
return strapi.plugins[
'users-permissions'
].services.userspermissions.initialize();
};

View File

@ -462,18 +462,14 @@ module.exports = {
return Promise.resolve();
},
async initialize(cb) {
async initialize() {
const roleCount = await strapi.query('role', 'users-permissions').count();
// It has already been initialized.
if (roleCount > 0) {
try {
await this.updatePermissions();
await this.removeDuplicate();
return cb();
} catch (err) {
return cb(err);
}
await this.updatePermissions();
await this.removeDuplicate();
return;
}
// Create two first default roles.
@ -490,7 +486,7 @@ module.exports = {
}),
]);
this.updatePermissions().then(() => cb(), err => cb(err));
return this.updatePermissions();
},
async updateRole(roleID, body) {

View File

@ -366,60 +366,39 @@ class Strapi extends EventEmitter {
}
async runBootstrapFunctions() {
const execBootstrap = fn => {
if (!fn) return Promise.resolve();
const timeoutMs = this.config.bootstrapTimeout || 3500;
const warnOnTimeout = () =>
setTimeout(() => {
this.log.warn(
`The bootstrap function is taking unusually long to execute (${timeoutMs} miliseconds).`
);
this.log.warn('Make sure you call it?');
}, timeoutMs);
return new Promise((resolve, reject) => {
const timeoutMs = this.config.bootstrapTimeout || 3500;
const timer = setTimeout(() => {
this.log.warn(
`The bootstrap function is taking unusually long to execute (${timeoutMs} miliseconds).`
);
this.log.warn('Make sure you call it?');
}, timeoutMs);
async function execBootstrap(fn) {
if (!fn) return;
let ranBootstrapFn = false;
const timer = warnOnTimeout();
try {
await fn();
} finally {
clearTimeout(timer);
}
}
try {
fn(err => {
if (ranBootstrapFn) {
this.log.error(
'You called the callback in `strapi.config.boostrap` more than once!'
);
return reject();
}
ranBootstrapFn = true;
clearTimeout(timer);
if (err instanceof Error) {
return reject(err);
}
return resolve(err);
});
} catch (e) {
if (ranBootstrapFn) {
this.log.error(
'The bootstrap function threw an error after its callback was called.'
);
return reject(e);
}
ranBootstrapFn = true;
clearTimeout(timer);
return resolve(e);
}
const pluginBoostraps = Object.keys(this.plugins).map(plugin => {
return execBootstrap(
_.get(this.plugins[plugin], 'config.functions.bootstrap')
).catch(err => {
strapi.log.error(`Bootstrap function in plugin "${plugin}" failed`);
strapi.log.error(err);
strapi.stop();
});
};
});
return Promise.all(
Object.values(this.plugins).map(plugin =>
execBootstrap(_.get(plugin, 'config.functions.bootstrap'))
)
).then(() => execBootstrap(this.config.functions.bootstrap));
await Promise.all(pluginBoostraps);
return execBootstrap(_.get(this.config, ['functions', 'bootstrap']));
}
async freeze() {