diff --git a/docs/installation.md b/docs/installation.md index 9e92b8558..f97c0a4cf 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -156,12 +156,17 @@ MONGOOSE_HOST = localhost MONGOOSE_HOST_READ = localhost MONGOOSE_PORT = 27017 MONGOOSE_PORT_READ = 27018 +MONGOOSE_READ_PREFERENCE = secondaryPreferred +REPLICASET = rs0 REDIS_HOST = localhost REDIS_HOST_READ = localhost WHISPR_AUTH_CONFIG_SECRET = (change to your auth server - see [Security](./security.md)) ``` +You can specify a different hosts to spread read access to mongodb replica using MONGOOSE_HOST_READ,MONGOOSE_PORT_READ,REPLICASET and MONGOOSE_READ_PREFERENCE +see https://www.mongodb.com/docs/manual/core/read-preference/ for more details + ### Setup a local AWS instance with localstack (optional) If you want to work with a local file storage instead of AWS use this: diff --git a/src/config/config.service.ts b/src/config/config.service.ts index 4e1b72764..d8fe3c853 100644 --- a/src/config/config.service.ts +++ b/src/config/config.service.ts @@ -58,20 +58,21 @@ export class ConfigService { getMongooseURI(): string { return this.get('REPLICASET') !== undefined - ? `mongodb://${this.get('MONGOOSE_HOST')}:${this.get('MONGOOSE_PORT')},${this.get( - 'MONGOOSE_HOST_READ', - )}:${this.get('MONGOOSE_PORT_READ')}` + ? `mongodb://${this.get('MONGOOSE_HOST')}:${this.get('MONGOOSE_PORT')},` + + `${this.get('MONGOOSE_HOST_READ')}:${this.get('MONGOOSE_PORT_READ')}` : `mongodb://${this.get('MONGOOSE_HOST')}:${this.get('MONGOOSE_PORT')}`; } getMongooseOptions(): MongooseModuleOptions { + const readPreference = this.get('MONGOOSE_READ_PREFERENCE') + ? this.get('MONGOOSE_READ_PREFERENCE') + : 'secondaryPreferred'; let options: MongooseModuleOptions = { uri: this.getMongooseURI(), dbName: 'whisps', - readPreference: this.get('REPLICASET') !== undefined ? 'primary' : null, + readPreference: this.get('REPLICASET') !== undefined ? readPreference : null, user: this.get('MONGOOSE_USERNAME'), pass: this.get('MONGOOSE_PASSWORD'), - replicaSet: this.get('REPLICASET'), }; if (this.get('SSL_VALIDATE') === true) { options = { diff --git a/src/config/environmentValidationSchema.ts b/src/config/environmentValidationSchema.ts index 842b8a3c6..045a0dc5e 100644 --- a/src/config/environmentValidationSchema.ts +++ b/src/config/environmentValidationSchema.ts @@ -84,6 +84,7 @@ export default Joi.object({ MONGOOSE_PORT_READ: Joi.number().default(27017), MONGOOSE_USERNAME: Joi.string(), MONGOOSE_PASSWORD: Joi.string(), + MONGOOSE_READ_PREFERENCE: Joi.string(), REDIS_HOST: Joi.string().required(), REDIS_PORT: Joi.number().default(6379), diff --git a/tests/load/whisp-create.load.js b/tests/load/whisp-create.load.js index 48db37809..e78d37081 100644 --- a/tests/load/whisp-create.load.js +++ b/tests/load/whisp-create.load.js @@ -51,29 +51,64 @@ export default function () { } `; + const query = ` + query Whisps( $sortTimestamp: JSONObject,$filter:JSONObject) { + whisps(sort:$sortTimestamp,filter:$filter,limit:1000) { + _id + #readableID + type + description + updated + timestamp + applicationID + #data + #openedById + #openedBy + expirationDate + timeToLiveSec + + + } + } + `; + + const variables = ` + { + "sortUpdated": { + "updated": "desc" + }, + "sortTimestamp": { + "timestamp": "desc" + }, + "filter": { + "type": "ACTION" + } + } + `; + const url = __ENV.ENVIRONMENT_URL || 'http://127.0.0.1:3000/graphql'; const headers = { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }; const response = http.post(url, - JSON.stringify({ query: mutationOpen }), + JSON.stringify({ query: query,variables:variables }), { headers }); - // const result = check(response, { - // 'response has status code 200': (r) => r.status === 200, - // 'repsonse does not contain error': (r) => r.headers['Retry-After'] === undefined, - // 'response does contain data': (r) => { - // try { - // return (r.json() as any).data; - // } catch (error) { - // return false; - // } - // }, - // }); + const result = check(response, { + 'response has status code 200': (r) => r.status === 200, + 'repsonse does not contain error': (r) => !(r.json().errors && r.json().errors.length !== 0), + 'response does contain data': (r) => { + try { + return (r.json() ).data; + } catch (error) { + return false; + } + }, + }); // // This allows us to have a global check to display the succeeded request ratio in the results - // check(response, { 'request succeed': () => result }); + //check(response, { 'request succeed': () => result }); sleep(1); }