diff --git a/app/.meteor/packages b/app/.meteor/packages index 8e6c12c3..06788bcc 100644 --- a/app/.meteor/packages +++ b/app/.meteor/packages @@ -3,6 +3,7 @@ # 'meteor add' and 'meteor remove' will edit this file for you, # but you can also edit it by hand. +zegenie:redis-oplog accounts-password@2.3.4 random@1.2.1 underscore@1.0.13 @@ -46,7 +47,7 @@ ostrio:files simple:rest-bearer-token-parser simple:rest-json-error-handler littledata:synced-cron -mdg:meteor-apm-agent +#mdg:meteor-apm-agent typescript@4.9.4 seba:minifiers-autoprefixer mixmax:smart-disconnect diff --git a/app/.meteor/versions b/app/.meteor/versions index 03d4f323..578fce81 100644 --- a/app/.meteor/versions +++ b/app/.meteor/versions @@ -52,10 +52,8 @@ inter-process-messaging@0.1.1 lai:collection-extensions@0.3.0 launch-screen@1.3.0 littledata:synced-cron@1.5.1 -livedata@1.0.18 localstorage@1.2.0 logging@1.3.2 -mdg:meteor-apm-agent@3.5.1 mdg:validated-method@1.3.0 meteor@1.11.2 meteor-base@1.5.1 @@ -76,7 +74,6 @@ mongo@1.16.6 mongo-decimal@0.1.3 mongo-dev-server@1.1.0 mongo-id@1.0.8 -mongo-livedata@1.0.12 npm-mongo@4.16.0 oauth@2.2.0 oauth2@1.3.2 @@ -127,4 +124,5 @@ underscore@1.0.13 url@1.3.2 webapp@1.13.5 webapp-hashing@1.1.1 +zegenie:redis-oplog@2.0.16 zer0th:meteor-vuetify-loader@0.1.41 diff --git a/app/imports/server/config/redisCaching.js b/app/imports/server/config/redisCaching.js new file mode 100644 index 00000000..45132ac3 --- /dev/null +++ b/app/imports/server/config/redisCaching.js @@ -0,0 +1,3 @@ +import LibraryNodes from '/imports/api/library/LibraryNodes.js'; + +LibraryNodes.startCaching(); diff --git a/app/imports/server/publications/searchLibraryNodes.js b/app/imports/server/publications/searchLibraryNodes.js index cedbc7a8..bbfcea84 100644 --- a/app/imports/server/publications/searchLibraryNodes.js +++ b/app/imports/server/publications/searchLibraryNodes.js @@ -5,27 +5,33 @@ import getCreatureLibraryIds from '/imports/api/library/getCreatureLibraryIds.js import getUserLibraryIds from '/imports/api/library/getUserLibraryIds.js'; import { assertViewPermission } from '/imports/api/sharing/sharingPermissions.js'; -Meteor.publish('selectedLibraryNodes', function(selectedNodeIds){ +function escapeRegex(string) { + return string.replace(/[/\-\\^$*+?.()|[\]{}]/g, ''); +} + +Meteor.publish('selectedLibraryNodes', function (selectedNodeIds) { check(selectedNodeIds, Array); // Limit to 20 selected nodes - if (selectedNodeIds.length > 20){ + if (selectedNodeIds.length > 20) { selectedNodeIds = selectedNodeIds.slice(0, 20); } let libraryViewPermissions = {}; // Check view permissions of all libraries - for (let id of selectedNodeIds){ + for (let id of selectedNodeIds) { let node = LibraryNodes.findOne(id); if (!node) continue; let libraryId = node.ancestors[0].id; - if (libraryViewPermissions[id]){ + if (libraryViewPermissions[id]) { continue; } else { - let library = Libraries.findOne(libraryId, {fields: { - owner: 1, - readers: 1, - writers: 1, - public: 1, - }}); + let library = Libraries.findOne(libraryId, { + fields: { + owner: 1, + readers: 1, + writers: 1, + public: 1, + } + }); assertViewPermission(library, this.userId); libraryViewPermissions[id] = true; } @@ -33,15 +39,15 @@ Meteor.publish('selectedLibraryNodes', function(selectedNodeIds){ // Return all nodes and their children return [LibraryNodes.find({ $or: [ - {_id: {$in: selectedNodeIds}}, - {'ancestors.id': {$in: selectedNodeIds}}, + { _id: { $in: selectedNodeIds } }, + { 'ancestors.id': { $in: selectedNodeIds } }, ], })]; }); -Meteor.publish('searchLibraryNodes', function(creatureId){ +Meteor.publish('searchLibraryNodes', function (creatureId) { let self = this; - this.autorun(function (){ + this.autorun(function () { let type = self.data('type'); if (!type) return []; @@ -60,20 +66,20 @@ Meteor.publish('searchLibraryNodes', function(creatureId){ // Build a filter for nodes in those libraries that match the type let filter = { - 'ancestors.id': {$in: libraryIds}, - removed: {$ne: true}, - tags: {$ne: []}, // Only tagged library nodes are considered + 'ancestors.id': { $in: libraryIds }, + removed: { $ne: true }, + tags: { $ne: [] }, // Only tagged library nodes are considered }; - if (type){ + if (type) { filter.$or = [{ - type, - },{ - type: 'slotFiller', - slotFillerType: type, + type, + }, { + type: 'slotFiller', + slotFillerType: type, }]; } - this.autorun(function(){ + this.autorun(function () { // Get the limit of the documents the user can fetch var limit = self.data('limit') || 32; check(limit, Number); @@ -83,28 +89,34 @@ Meteor.publish('searchLibraryNodes', function(creatureId){ check(searchTerm, String); let options = undefined; - if (searchTerm){ - filter.$text = {$search: searchTerm}; + if (searchTerm) { + filter.name = { $regex: escapeRegex(searchTerm), '$options': 'i' }; + // filter.$text = {$search: searchTerm}; options = { + /* // relevant documents have a higher score. fields: { score: { $meta: 'textScore' } }, + */ sort: { // `score` property specified in the projection fields above. - score: { $meta: 'textScore' }, + // score: { $meta: 'textScore' }, 'ancestors.0.id': 1, name: 1, order: 1, } } } else { - delete filter.$text - options = {sort: { - 'ancestors.0.id': 1, - name: 1, - order: 1, - }}; + //delete filter.$text + delete filter.name; + options = { + sort: { + 'ancestors.0.id': 1, + name: 1, + order: 1, + } + }; } options.limit = limit; @@ -118,17 +130,17 @@ Meteor.publish('searchLibraryNodes', function(creatureId){ Mongo.Collection._publishCursor(libraries, self, 'libraries'); let observeHandle = cursor.observeChanges({ - added: function (id, fields) { - fields._searchResult = true; - self.added('libraryNodes', id, fields); - }, - changed: function (id, fields) { - self.changed('libraryNodes', id, fields); - }, - removed: function (id) { - self.removed('libraryNodes', id); - } + added: function (id, fields) { + fields._searchResult = true; + self.added('libraryNodes', id, fields); }, + changed: function (id, fields) { + self.changed('libraryNodes', id, fields); + }, + removed: function (id) { + self.removed('libraryNodes', id); + } + }, // Publications don't mutate the documents { nonMutatingCallbacks: true } ); diff --git a/app/packages/redis-oplog b/app/packages/redis-oplog new file mode 160000 index 00000000..83e302c1 --- /dev/null +++ b/app/packages/redis-oplog @@ -0,0 +1 @@ +Subproject commit 83e302c15456d6744047c50fc8d1add9e739b001 diff --git a/app/redis-settings.json b/app/redis-settings.json new file mode 100644 index 00000000..45fc18d7 --- /dev/null +++ b/app/redis-settings.json @@ -0,0 +1,19 @@ +{ + "redisOplog": { + "redis": { + "port": 6379, + "host": "127.0.0.1" + }, + "retryIntervalMs": 1000, + "mutationDefaults": { + "optimistic": true, + "pushToRedis": true + }, + "cacheTimeout": 1800000, + "cacheTimer": 300000, + "secondaryReads": null, + "raceDetectionDelay": 1000, + "raceDetection": true, + "debug": false + } +} \ No newline at end of file diff --git a/app/server/main.js b/app/server/main.js index 642113e0..eddb6d67 100644 --- a/app/server/main.js +++ b/app/server/main.js @@ -5,6 +5,7 @@ import '/imports/server/rest/index.js'; import '/imports/server/config/accountsEmailConfig.js'; import '/imports/server/config/simpleSchemaDebug.js'; import '/imports/server/config/SyncedCronConfig.js'; +import '/imports/server/config/redisCaching.js'; import '/imports/server/publications/index.js'; import '/imports/server/cron/deleteSoftRemovedDocuments.js'; import '/imports/api/parenting/organizeMethods.js';