diff --git a/app.js b/app.js index 2989ae00a..d9b7ed5e1 100644 --- a/app.js +++ b/app.js @@ -11,6 +11,7 @@ const {MOUNT_PATH} = require('./url'); const {applyLocals} = require('./services/locals'); const routes = require('./routes'); const debug = require('debug')('talk:app'); +const {ENABLE_TRACING, APOLLO_ENGINE_KEY, PORT} = require('./config'); const app = express(); @@ -23,6 +24,22 @@ if (process.env.NODE_ENV !== 'test') { app.use(morgan('dev')); } +if (process.env.NODE_ENV === 'development' && ENABLE_TRACING && APOLLO_ENGINE_KEY) { + const {Engine} = require('apollo-engine'); + + const engine = new Engine({ + engineConfig: { + apiKey: APOLLO_ENGINE_KEY + }, + graphqlPort: PORT, + endpoint: '/api/v1/graph/ql', + }); + + engine.start(); + + app.use(engine.expressMiddleware()); +} + // Trust the first proxy in front of us, this will enable us to trust the fact // that SSL was terminated correctly. app.set('trust proxy', 1); diff --git a/config.js b/config.js index 4601683c1..046b278e3 100644 --- a/config.js +++ b/config.js @@ -20,6 +20,9 @@ const CONFIG = { // WEBPACK indicates when webpack is currently building. WEBPACK: process.env.WEBPACK === 'TRUE', + APOLLO_ENGINE_KEY: process.env.APOLLO_ENGINE_KEY || null, + ENABLE_TRACING: Boolean(process.env.APOLLO_ENGINE_KEY), + //------------------------------------------------------------------------------ // JWT based configuration //------------------------------------------------------------------------------ diff --git a/graph/index.js b/graph/index.js index 7495c0605..228470acb 100644 --- a/graph/index.js +++ b/graph/index.js @@ -1,6 +1,7 @@ const schema = require('./schema'); const Context = require('./context'); const {createSubscriptionManager} = require('./subscriptions'); +const {ENABLE_TRACING} = require('../config'); module.exports = { createGraphOptions: (req) => ({ @@ -10,7 +11,11 @@ module.exports = { // Load in the new context here, this'll create the loaders + mutators for // the lifespan of this request. - context: new Context(req) + context: new Context(req), + + // Tracing request options, needed for Apollo Engine. + tracing: ENABLE_TRACING, + cacheControl: ENABLE_TRACING }), createSubscriptionManager }; diff --git a/models/comment.js b/models/comment.js index 73aa22d0b..e95ecc38e 100644 --- a/models/comment.js +++ b/models/comment.js @@ -111,11 +111,13 @@ CommentSchema.index({ // Add an index that is optimized for sorting based on the action count data. CommentSchema.index({ 'created_at': 1, - 'action_counts': 1, + 'action_counts.flag': 1, }, { background: true, }); +// TODO: Evaluate adding indexes for each reaction as well. + // Add an index that is optimized for sorting based on the created_at timestamp // but also good at locating comments that have a specific asset id. CommentSchema.index({ diff --git a/models/user.js b/models/user.js index 742c669d0..98e004a38 100644 --- a/models/user.js +++ b/models/user.js @@ -220,6 +220,24 @@ UserSchema.index({ background: false }); +// This query is executed often, to count the number of flagged accounts with +// usernames. +UserSchema.index({ + 'action_counts.flag': 1, + 'status.username.status': 1, +}, { + background: true +}); + +// Sorting users by created at is the default people search. +UserSchema.index({ + 'created_at': -1, +}, { + background: true, +}); + +// TODO: Add indexes for searching the user collection. Needs product decision. + /** * returns true if a commenter is staff */ diff --git a/package.json b/package.json index 3e948cb32..dd6f004b5 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "dependencies": { "accepts": "^1.3.4", "apollo-client": "^1.9.1", + "apollo-server-express": "^1.2.0", "app-module-path": "^2.2.0", "autoprefixer": "^6.5.2", "babel-cli": "6.26.0", @@ -102,7 +103,6 @@ "graphql-docs": "0.2.0", "graphql-errors": "^2.1.0", "graphql-redis-subscriptions": "1.3.0", - "graphql-server-express": "^0.6.0", "graphql-subscriptions": "^0.4.3", "graphql-tag": "^1.2.3", "graphql-tools": "^0.10.1", @@ -182,6 +182,7 @@ }, "devDependencies": { "@coralproject/eslint-config-talk": "^0.0.4", + "apollo-engine": "^0.6.0", "babel-jest": "^21.2.0", "babel-plugin-dynamic-import-node": "^1.1.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", diff --git a/routes/index.js b/routes/index.js index 90654adc5..1fde4b915 100644 --- a/routes/index.js +++ b/routes/index.js @@ -9,7 +9,7 @@ const i18n = require('../services/i18n'); const enabled = require('debug').enabled; const errors = require('../errors'); const {createGraphOptions} = require('../graph'); -const apollo = require('graphql-server-express'); +const apollo = require('apollo-server-express'); const {DISABLE_STATIC_SERVER} = require('../config'); const SetupService = require('../services/setup'); const static = require('express-static-gzip'); diff --git a/yarn.lock b/yarn.lock index cbbebd4e6..767c98f39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,24 +18,11 @@ git-url-parse "^6.0.2" shelljs "^0.7.0" -"@types/express-serve-static-core@*": - version "4.0.53" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.0.53.tgz#1723a35d1447f2c55e13c8721eab3448e42f4d82" - dependencies: - "@types/node" "*" - -"@types/express@^4.0.35": - version "4.0.37" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.0.37.tgz#625ac3765169676e01897ca47011c26375784971" - dependencies: - "@types/express-serve-static-core" "*" - "@types/serve-static" "*" - "@types/graphql@0.10.2": version "0.10.2" resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.10.2.tgz#d7c79acbaa17453b6681c80c34b38fcb10c4c08c" -"@types/graphql@^0.8.5", "@types/graphql@^0.8.6": +"@types/graphql@^0.8.5": version "0.8.6" resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.8.6.tgz#b34fb880493ba835b0c067024ee70130d6f9bb68" @@ -43,25 +30,14 @@ version "0.9.4" resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.9.4.tgz#cdeb6bcbef9b6c584374b81aa7f48ecf3da404fa" -"@types/mime@*": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" - "@types/node@*": - version "8.0.45" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.45.tgz#89fad82439d5624e1b5c6b42f0f5d85136dcdecc" + version "8.0.53" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8" "@types/node@^6.0.46": version "6.0.90" resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.90.tgz#0ed74833fa1b73dcdb9409dcb1c97ec0a8b13b02" -"@types/serve-static@*": - version "1.7.32" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.7.32.tgz#0f6732e4dab0813771dd8fc8fe14940f34728b4c" - dependencies: - "@types/express-serve-static-core" "*" - "@types/mime" "*" - "@types/ws@^3.0.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-3.2.0.tgz#988ff690e6ed10068a86aa0e9f842d0a03c09e21" @@ -233,6 +209,12 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" +apollo-cache-control@^0.0.x: + version "0.0.7" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.0.7.tgz#ffef56413a429a1ce204be5b78d248c4fe3b67ac" + dependencies: + graphql-extensions "^0.0.x" + apollo-client@^1.4.0, apollo-client@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-1.9.3.tgz#37000b3c801f4571b7b089739e696a158896aeab" @@ -247,6 +229,29 @@ apollo-client@^1.4.0, apollo-client@^1.9.1: optionalDependencies: "@types/graphql" "0.10.2" +apollo-engine-binary-darwin@^0.2017.11-121-g2a0310e1b: + version "0.2017.11-121-g2a0310e1b" + resolved "https://registry.yarnpkg.com/apollo-engine-binary-darwin/-/apollo-engine-binary-darwin-0.2017.11-121-g2a0310e1b.tgz#789895e1b7dbf70e64f5cc49f0e4b20d2c9640ab" + +apollo-engine-binary-linux@^0.2017.11-121-g2a0310e1b: + version "0.2017.11-121-g2a0310e1b" + resolved "https://registry.yarnpkg.com/apollo-engine-binary-linux/-/apollo-engine-binary-linux-0.2017.11-121-g2a0310e1b.tgz#fc18e2dbd346008335ce06b2713412896ff31108" + +apollo-engine-binary-windows@^0.2017.11-121-g2a0310e1b: + version "0.2017.11-121-g2a0310e1b" + resolved "https://registry.yarnpkg.com/apollo-engine-binary-windows/-/apollo-engine-binary-windows-0.2017.11-121-g2a0310e1b.tgz#681ce23b87d68adebd004b03ddf8a0185ba7acca" + +apollo-engine@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/apollo-engine/-/apollo-engine-0.6.0.tgz#ed3d52f14dec60b7e4551d21d764a6081d58b344" + dependencies: + request "^2.81.0" + stream-json "^0.5.2" + optionalDependencies: + apollo-engine-binary-darwin "^0.2017.11-121-g2a0310e1b" + apollo-engine-binary-linux "^0.2017.11-121-g2a0310e1b" + apollo-engine-binary-windows "^0.2017.11-121-g2a0310e1b" + apollo-link-core@^0.5.0: version "0.5.4" resolved "https://registry.yarnpkg.com/apollo-link-core/-/apollo-link-core-0.5.4.tgz#8efd4cd747959872a32f313f0ccfc2a76b396668" @@ -255,6 +260,31 @@ apollo-link-core@^0.5.0: graphql-tag "^2.4.2" zen-observable-ts "^0.4.4" +apollo-server-core@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.2.0.tgz#e851c47444991b6f89f88529237076b83e01e8ee" + dependencies: + apollo-cache-control "^0.0.x" + apollo-tracing "^0.1.0" + graphql-extensions "^0.0.x" + +apollo-server-express@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.2.0.tgz#026b12b453b8ecac6044b205b6a85fe596fb5f9e" + dependencies: + apollo-server-core "^1.2.0" + apollo-server-module-graphiql "^1.2.0" + +apollo-server-module-graphiql@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.2.0.tgz#899d84f3b747795dbbfc8354aa51622ef038151c" + +apollo-tracing@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.1.tgz#7a5707543fc102f81cda7ba45b98331a82a6750b" + dependencies: + graphql-extensions "^0.0.x" + app-module-path@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5" @@ -1984,7 +2014,7 @@ core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" -core-js@^2.4.0, core-js@^2.5.0: +core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" @@ -3584,6 +3614,13 @@ graphql-errors@^2.1.0: babel-runtime "^6.6.1" uuid "^2.0.2" +graphql-extensions@^0.0.x: + version "0.0.5" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.5.tgz#63bc4a3fd31aab12bfadf783cbc038a9a6937cf0" + dependencies: + core-js "^2.5.1" + source-map-support "^0.5.0" + graphql-redis-subscriptions@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/graphql-redis-subscriptions/-/graphql-redis-subscriptions-1.3.0.tgz#bbc52b0f77bf7d50945c6bf4e8b8aba5135555b4" @@ -3593,26 +3630,6 @@ graphql-redis-subscriptions@1.3.0: optionalDependencies: ioredis "^3.1.2" -graphql-server-core@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/graphql-server-core/-/graphql-server-core-0.6.0.tgz#468625cba4a00f80275c065432faa481985f5a65" - optionalDependencies: - "@types/graphql" "^0.8.5" - -graphql-server-express@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/graphql-server-express/-/graphql-server-express-0.6.0.tgz#516090b4add82e6ed2c4a70dd2d925031fdcc289" - dependencies: - graphql-server-core "^0.6.0" - graphql-server-module-graphiql "^0.6.0" - optionalDependencies: - "@types/express" "^4.0.35" - "@types/graphql" "^0.8.6" - -graphql-server-module-graphiql@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/graphql-server-module-graphiql/-/graphql-server-module-graphiql-0.6.0.tgz#e37634b05f000731981e8ed13103f9a5861e5da0" - graphql-subscriptions@^0.4.2, graphql-subscriptions@^0.4.3: version "0.4.4" resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-0.4.4.tgz#39cff32d08dd3c990113864bab77154403727e9b" @@ -6458,6 +6475,10 @@ parse5@^3.0.1: dependencies: "@types/node" "^6.0.46" +parser-toolkit@>=0.0.3: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parser-toolkit/-/parser-toolkit-0.0.5.tgz#ec4b61729c86318b56ea971bfba6b3c672d62c01" + parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" @@ -7842,7 +7863,7 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@2, request@^2.55.0, request@^2.74.0, request@^2.79.0: +request@2, request@^2.55.0, request@^2.74.0, request@^2.79.0, request@^2.81.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: @@ -8412,6 +8433,12 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" +source-map-support@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.0.tgz#2018a7ad2bdf8faf2691e5fddab26bed5a2bacab" + dependencies: + source-map "^0.6.0" + source-map@0.1.x: version "0.1.43" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" @@ -8428,7 +8455,7 @@ source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, sourc version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" -source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -8505,6 +8532,12 @@ stream-http@^2.3.1: to-arraybuffer "^1.0.0" xtend "^4.0.0" +stream-json@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-0.5.2.tgz#f4256c0ef1a905f2ef2d473706b4b3ff827653cf" + dependencies: + parser-toolkit ">=0.0.3" + strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"