diff --git a/.circleci/config.yml b/.circleci/config.yml index f7d4d7ca0929..86e85b84921f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -45,17 +45,11 @@ test-save-npm-cache: &test-save-npm-cache test-docker-image: &test-docker-image circleci/node:8.11-stretch-browsers -test: &test +test-with-oplog: &test-with-oplog <<: *defaults - environment: &test-environment + environment: TEST_MODE: "true" MONGO_URL: mongodb://localhost:27017/rocketchat - - -test-with-oplog: &test-with-oplog - <<: *test - environment: - <<: *test-environment MONGO_OPLOG_URL: mongodb://localhost:27017/local steps: @@ -69,19 +63,6 @@ test-with-oplog: &test-with-oplog - save_cache: *test-save-npm-cache - store_artifacts: *test-store_artifacts -test-without-oplog: &test-without-oplog - <<: *test - steps: - - attach_workspace: *attach_workspace - - checkout - - run: *test-install-dependencies - - restore_cache: *test-restore-npm-cache - - run: *test-npm-install - - run: *test-run - - save_cache: *test-save-npm-cache - - store_artifacts: *test-store_artifacts - - version: 2 jobs: build: @@ -248,32 +229,6 @@ jobs: - image: mongo:4.0 command: [mongod, --noprealloc, --smallfiles, --replSet=rs0] - - test-without-oplog-mongo-3-2: - <<: *test-without-oplog - docker: - - image: *test-docker-image - - image: mongo:3.2 - - test-without-oplog-mongo-3-4: - <<: *test-without-oplog - docker: - - image: *test-docker-image - - image: mongo:3.4 - - test-without-oplog-mongo-3-6: - <<: *test-without-oplog - docker: - - image: *test-docker-image - - image: mongo:3.6 - - test-without-oplog-mongo-4-0: - <<: *test-without-oplog - docker: - - image: *test-docker-image - - image: mongo:4.0 - - deploy: <<: *defaults docker: @@ -449,20 +404,12 @@ workflows: only: /^[0-9]+\.[0-9]+\.[0-9]+(?:-(?:rc|beta)\.[0-9]+)?$/ - test-with-oplog-mongo-3-6: *test-mongo-no-pr - test-with-oplog-mongo-4-0: *test-mongo - - test-without-oplog-mongo-3-2: *test-mongo-no-pr - - test-without-oplog-mongo-3-4: *test-mongo-no-pr - - test-without-oplog-mongo-3-6: *test-mongo-no-pr - - test-without-oplog-mongo-4-0: *test-mongo-no-pr - deploy: requires: - test-with-oplog-mongo-3-2 - test-with-oplog-mongo-3-4 - test-with-oplog-mongo-3-6 - test-with-oplog-mongo-4-0 - - test-without-oplog-mongo-3-2 - - test-without-oplog-mongo-3-4 - - test-without-oplog-mongo-3-6 - - test-without-oplog-mongo-4-0 filters: branches: only: develop diff --git a/app/lib/server/startup/settings.js b/app/lib/server/startup/settings.js index 630daf1845ba..e219fcf36ca4 100644 --- a/app/lib/server/startup/settings.js +++ b/app/lib/server/startup/settings.js @@ -811,10 +811,6 @@ settings.addGroup('General', function() { type: 'string', public: false, }); - this.add('Force_Disable_OpLog_For_Cache', false, { - type: 'boolean', - public: false, - }); this.add('Restart', 'restart_server', { type: 'action', actionText: 'Restart_the_server', diff --git a/app/models/server/models/_BaseDb.js b/app/models/server/models/_BaseDb.js index b287cd432e8f..c5c79c8fbc5a 100644 --- a/app/models/server/models/_BaseDb.js +++ b/app/models/server/models/_BaseDb.js @@ -2,7 +2,6 @@ import { Match } from 'meteor/check'; import { Mongo, MongoInternals } from 'meteor/mongo'; import _ from 'underscore'; import { EventEmitter } from 'events'; -import { settings } from '../../../settings/server/functions/settings'; const baseName = 'rocketchat_'; @@ -14,8 +13,7 @@ try { console.log(e); } -const isOplogAvailable = MongoInternals.defaultRemoteCollectionDriver().mongo._oplogHandle && !!MongoInternals.defaultRemoteCollectionDriver().mongo._oplogHandle.onOplogEntry; -let isOplogEnabled = isOplogAvailable; +const isOplogEnabled = MongoInternals.defaultRemoteCollectionDriver().mongo._oplogHandle && !!MongoInternals.defaultRemoteCollectionDriver().mongo._oplogHandle.onOplogEntry; export class BaseDb extends EventEmitter { constructor(model, baseModel) { @@ -36,7 +34,6 @@ export class BaseDb extends EventEmitter { this.wrapModel(); let alreadyListeningToOplog = false; - this.listenSettings(); // When someone start listening for changes we start oplog if available this.on('newListener', (event/* , listener*/) => { if (event === 'change' && alreadyListeningToOplog === false) { @@ -58,12 +55,6 @@ export class BaseDb extends EventEmitter { this.tryEnsureIndex({ _updatedAt: 1 }); } - listenSettings() { - settings.get('Force_Disable_OpLog_For_Cache', (key, value) => { - isOplogEnabled = isOplogAvailable && value === false; - }); - } - get baseName() { return baseName; } @@ -142,10 +133,6 @@ export class BaseDb extends EventEmitter { } processOplogRecord(action) { - if (isOplogEnabled === false) { - return; - } - if (action.op.op === 'i') { this.emit('change', { action: 'insert', @@ -214,66 +201,13 @@ export class BaseDb extends EventEmitter { record._id = result; - if (!isOplogEnabled && this.listenerCount('change') > 0) { - this.emit('change', { - action: 'insert', - clientAction: 'inserted', - id: result, - data: _.extend({}, record), - oplog: false, - }); - } - return result; } update(query, update, options = {}) { this.setUpdatedAt(update, true, query); - let ids = []; - if (!isOplogEnabled && this.listenerCount('change') > 0) { - const findOptions = { fields: { _id: 1 } }; - let records = options.multi ? this.find(query, findOptions).fetch() : this.findOne(query, findOptions) || []; - if (!Array.isArray(records)) { - records = [records]; - } - - ids = records.map((item) => item._id); - if (options.upsert !== true && this.updateHasPositionalOperator(update) === false) { - query = { - _id: { - $in: ids, - }, - }; - } - } - - // TODO: CACHE: Can we use findAndModify here when oplog is disabled? - const result = this.originals.update(query, update, options); - - if (!isOplogEnabled && this.listenerCount('change') > 0) { - if (options.upsert === true && result.insertedId) { - this.emit('change', { - action: 'insert', - clientAction: 'inserted', - id: result.insertedId, - oplog: false, - }); - - return result; - } - - for (const id of ids) { - this.emit('change', { - action: 'update', - clientAction: 'updated', - id, - oplog: false, - }); - } - } - - return result; + return this.originals.update(query, update, options); } upsert(query, update, options = {}) { @@ -297,21 +231,7 @@ export class BaseDb extends EventEmitter { query = { _id: { $in: ids } }; - const result = this.originals.remove(query); - - if (!isOplogEnabled && this.listenerCount('change') > 0) { - for (const record of records) { - this.emit('change', { - action: 'remove', - clientAction: 'removed', - id: record._id, - data: _.extend({}, record), - oplog: false, - }); - } - } - - return result; + return this.originals.remove(query); } insertOrUpsert(...args) { diff --git a/app/statistics/server/functions/get.js b/app/statistics/server/functions/get.js index 0224bb002824..2553ba87fca1 100644 --- a/app/statistics/server/functions/get.js +++ b/app/statistics/server/functions/get.js @@ -138,7 +138,7 @@ statistics.get = function _getStatistics() { const { mongo } = MongoInternals.defaultRemoteCollectionDriver(); - if (mongo._oplogHandle && mongo._oplogHandle.onOplogEntry && settings.get('Force_Disable_OpLog_For_Cache') !== true) { + if (mongo._oplogHandle && mongo._oplogHandle.onOplogEntry) { statistics.oplogEnabled = true; } diff --git a/app/version-check/server/functions/getNewUpdates.js b/app/version-check/server/functions/getNewUpdates.js index b08df8538d40..1694e5b41677 100644 --- a/app/version-check/server/functions/getNewUpdates.js +++ b/app/version-check/server/functions/getNewUpdates.js @@ -2,7 +2,6 @@ import os from 'os'; import { HTTP } from 'meteor/http'; import { check, Match } from 'meteor/check'; import { Settings } from '../../../models'; -import { settings } from '../../../settings'; import { Info } from '../../../utils'; import { getWorkspaceAccessToken } from '../../../cloud/server'; import { MongoInternals } from 'meteor/mongo'; @@ -11,7 +10,7 @@ export default () => { try { const uniqueID = Settings.findOne('uniqueID'); const { _oplogHandle } = MongoInternals.defaultRemoteCollectionDriver().mongo; - const oplogEnabled = _oplogHandle && _oplogHandle.onOplogEntry && settings.get('Force_Disable_OpLog_For_Cache') !== true; + const oplogEnabled = _oplogHandle && _oplogHandle.onOplogEntry; const params = { uniqueId: uniqueID.value, diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index e13ea305725a..dbb540301b92 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -1390,8 +1390,6 @@ "For_your_security_you_must_enter_your_current_password_to_continue": "For your security, you must enter your current password to continue", "force-delete-message": "Force Delete Message", "force-delete-message_description": "Permission to delete a message bypassing all restrictions", - "Force_Disable_OpLog_For_Cache": "Force Disable OpLog for Cache", - "Force_Disable_OpLog_For_Cache_Description": "Will not use OpLog to sync cache even when it's available", "Force_SSL": "Force SSL", "Force_SSL_Description": "*Caution!* _Force SSL_ should never be used with reverse proxy. If you have a reverse proxy, you should do the redirect THERE. This option exists for deployments like Heroku, that does not allow the redirect configuration at the reverse proxy.", "Force_visitor_to_accept_data_processing_consent": "Force visitor to accept data processing consent", diff --git a/server/startup/migrations/index.js b/server/startup/migrations/index.js index c26cfc0c6d04..edd7d26a9510 100644 --- a/server/startup/migrations/index.js +++ b/server/startup/migrations/index.js @@ -139,4 +139,5 @@ import './v138'; import './v139'; import './v140'; import './v141'; +import './v142'; import './xrun'; diff --git a/server/startup/migrations/v142.js b/server/startup/migrations/v142.js new file mode 100644 index 000000000000..f54da1764b35 --- /dev/null +++ b/server/startup/migrations/v142.js @@ -0,0 +1,9 @@ +import { Migrations } from '../../../app/migrations'; +import { Settings } from '../../../app/models'; + +Migrations.add({ + version: 142, + up() { + Settings.remove({ _id: 'Force_Disable_OpLog_For_Cache' }); + }, +}); diff --git a/server/startup/serverRunning.js b/server/startup/serverRunning.js index a7859d005a28..64867a1aa94c 100644 --- a/server/startup/serverRunning.js +++ b/server/startup/serverRunning.js @@ -8,16 +8,9 @@ import path from 'path'; import semver from 'semver'; Meteor.startup(function() { - let oplogState = 'Disabled'; - const { mongo } = MongoInternals.defaultRemoteCollectionDriver(); - if (mongo._oplogHandle && mongo._oplogHandle.onOplogEntry) { - oplogState = 'Enabled'; - if (settings.get('Force_Disable_OpLog_For_Cache') === true) { - oplogState += ' (Disabled for Cache Sync)'; - } - } + const isOplogEnabled = Boolean(mongo._oplogHandle && mongo._oplogHandle.onOplogEntry); let mongoDbVersion; let mongoDbEngine; @@ -42,7 +35,7 @@ Meteor.startup(function() { ` Platform: ${ process.platform }`, ` Process Port: ${ process.env.PORT }`, ` Site URL: ${ settings.get('Site_Url') }`, - ` ReplicaSet OpLog: ${ oplogState }`, + ` ReplicaSet OpLog: ${ isOplogEnabled ? 'Enabled' : 'Disabled' }`, ]; if (Info.commit && Info.commit.hash) { @@ -55,18 +48,25 @@ Meteor.startup(function() { msg = msg.join('\n'); + if (!isOplogEnabled) { + msg += ['', '', 'OPLOG / REPLICASET IS REQUIRED TO RUN ROCKET.CHAT, MORE INFORMATION AT:', 'https://rocket.chat/docs/installation/docker-containers/high-availability-install'].join('\n'); + SystemLogger.error_box(msg, 'SERVER ERROR'); + + return process.exit(1); + } + if (!semver.satisfies(process.versions.node, desiredNodeVersionMajor)) { msg += ['', '', 'YOUR CURRENT NODEJS VERSION IS NOT SUPPORTED,', `PLEASE UPGRADE / DOWNGRADE TO VERSION ${ desiredNodeVersionMajor }.X.X`].join('\n'); SystemLogger.error_box(msg, 'SERVER ERROR'); - return process.exit(); + return process.exit(1); } if (!semver.satisfies(mongoDbVersion, '>=3.2.0')) { msg += ['', '', 'YOUR CURRENT MONGODB VERSION IS NOT SUPPORTED,', 'PLEASE UPGRADE TO VERSION 3.2 OR LATER'].join('\n'); SystemLogger.error_box(msg, 'SERVER ERROR'); - return process.exit(); + return process.exit(1); } return SystemLogger.startup_box(msg, 'SERVER RUNNING');