mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 03:29:02 +01:00 
			
		
		
		
	added basic CLS support with re-entrant transactions
This commit is contained in:
		
							parent
							
								
									b10b0048f3
								
							
						
					
					
						commit
						0ec909fd7a
					
				
							
								
								
									
										36
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										36
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -395,6 +395,14 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-1.1.0.tgz", | ||||||
|       "integrity": "sha1-9C/YFV048hpbjqB8KOBj7RcAsTg=" |       "integrity": "sha1-9C/YFV048hpbjqB8KOBj7RcAsTg=" | ||||||
|     }, |     }, | ||||||
|  |     "async-hook-jl": { | ||||||
|  |       "version": "1.7.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", | ||||||
|  |       "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", | ||||||
|  |       "requires": { | ||||||
|  |         "stack-chain": "1.3.7" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "async-limiter": { |     "async-limiter": { | ||||||
|       "version": "1.0.0", |       "version": "1.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", | ||||||
| @ -1888,6 +1896,16 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", |       "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", | ||||||
|       "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" |       "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" | ||||||
|     }, |     }, | ||||||
|  |     "cls-hooked": { | ||||||
|  |       "version": "4.2.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", | ||||||
|  |       "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", | ||||||
|  |       "requires": { | ||||||
|  |         "async-hook-jl": "1.7.6", | ||||||
|  |         "emitter-listener": "1.1.1", | ||||||
|  |         "semver": "5.4.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "co": { |     "co": { | ||||||
|       "version": "4.6.0", |       "version": "4.6.0", | ||||||
|       "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", |       "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", | ||||||
| @ -3593,6 +3611,14 @@ | |||||||
|       "integrity": "sha1-H71tl779crim+SHcONIkE9L2/d8=", |       "integrity": "sha1-H71tl779crim+SHcONIkE9L2/d8=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "emitter-listener": { | ||||||
|  |       "version": "1.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.1.tgz", | ||||||
|  |       "integrity": "sha1-6Lu+gkS8jg0LTvcc0UKUx/JBx+w=", | ||||||
|  |       "requires": { | ||||||
|  |         "shimmer": "1.2.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "encodeurl": { |     "encodeurl": { | ||||||
|       "version": "1.0.2", |       "version": "1.0.2", | ||||||
|       "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", |       "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", | ||||||
| @ -9677,6 +9703,11 @@ | |||||||
|         "rechoir": "0.6.2" |         "rechoir": "0.6.2" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "shimmer": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-xTCx2vohXC2EWWDqY/zb4+5Mu28D+HYNSOuFzsyRDRvI/e1ICb69afwaUwfjr+25ZXldbOLyp+iDUZHq8UnTag==" | ||||||
|  |     }, | ||||||
|     "signal-exit": { |     "signal-exit": { | ||||||
|       "version": "3.0.2", |       "version": "3.0.2", | ||||||
|       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", |       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", | ||||||
| @ -10580,6 +10611,11 @@ | |||||||
|         "tweetnacl": "0.14.5" |         "tweetnacl": "0.14.5" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "stack-chain": { | ||||||
|  |       "version": "1.3.7", | ||||||
|  |       "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", | ||||||
|  |       "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" | ||||||
|  |     }, | ||||||
|     "stat-mode": { |     "stat-mode": { | ||||||
|       "version": "0.2.2", |       "version": "0.2.2", | ||||||
|       "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", |       "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", | ||||||
|  | |||||||
| @ -23,6 +23,7 @@ | |||||||
|     "async-mutex": "^0.1.3", |     "async-mutex": "^0.1.3", | ||||||
|     "axios": "^0.17.1", |     "axios": "^0.17.1", | ||||||
|     "body-parser": "~1.18.2", |     "body-parser": "~1.18.2", | ||||||
|  |     "cls-hooked": "^4.2.2", | ||||||
|     "cookie-parser": "~1.4.3", |     "cookie-parser": "~1.4.3", | ||||||
|     "debug": "~3.1.0", |     "debug": "~3.1.0", | ||||||
|     "devtron": "^1.4.0", |     "devtron": "^1.4.0", | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								src/app.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/app.js
									
									
									
									
									
								
							| @ -9,6 +9,7 @@ const session = require('express-session'); | |||||||
| const FileStore = require('session-file-store')(session); | const FileStore = require('session-file-store')(session); | ||||||
| const os = require('os'); | const os = require('os'); | ||||||
| const sessionSecret = require('./services/session_secret'); | const sessionSecret = require('./services/session_secret'); | ||||||
|  | const cls = require('./services/cls'); | ||||||
| 
 | 
 | ||||||
| const app = express(); | const app = express(); | ||||||
| 
 | 
 | ||||||
| @ -23,6 +24,17 @@ app.use((req, res, next) => { | |||||||
|     next(); |     next(); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | app.use((req, res, next) => { | ||||||
|  |     cls.namespace.bindEmitter(req); | ||||||
|  |     cls.namespace.bindEmitter(res); | ||||||
|  | 
 | ||||||
|  |     cls.init(() => { | ||||||
|  |         cls.namespace.set("Hi"); | ||||||
|  | 
 | ||||||
|  |         next(); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
| app.use(bodyParser.json({limit: '50mb'})); | app.use(bodyParser.json({limit: '50mb'})); | ||||||
| app.use(bodyParser.urlencoded({extended: false})); | app.use(bodyParser.urlencoded({extended: false})); | ||||||
| app.use(cookieParser()); | app.use(cookieParser()); | ||||||
|  | |||||||
| @ -108,7 +108,11 @@ function updateNoteFromInputs(note) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function saveNoteToServer(note) { | async function saveNoteToServer(note) { | ||||||
|     await server.put('notes/' + note.noteId, note); |     const dto = Object.assign({}, note); | ||||||
|  |     delete dto.treeCache; | ||||||
|  |     delete dto.hideInAutocomplete; | ||||||
|  | 
 | ||||||
|  |     await server.put('notes/' + dto.noteId, dto); | ||||||
| 
 | 
 | ||||||
|     isNoteChanged = false; |     isNoteChanged = false; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -55,7 +55,9 @@ router.put('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => { | |||||||
|     const sourceId = req.headers.source_id; |     const sourceId = req.headers.source_id; | ||||||
|     const dataKey = protected_session.getDataKey(req); |     const dataKey = protected_session.getDataKey(req); | ||||||
| 
 | 
 | ||||||
|     await notes.updateNote(noteId, note, dataKey, sourceId); |     await sql.doInTransaction(async () => { | ||||||
|  |         await notes.updateNote(noteId, note, dataKey, sourceId); | ||||||
|  |     }); | ||||||
| 
 | 
 | ||||||
|     res.send({}); |     res.send({}); | ||||||
| })); | })); | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ const dataDir = require('./data_dir'); | |||||||
| const log = require('./log'); | const log = require('./log'); | ||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
| const sync_mutex = require('./sync_mutex'); | const sync_mutex = require('./sync_mutex'); | ||||||
|  | const cls = require('./cls'); | ||||||
| 
 | 
 | ||||||
| async function regularBackup() { | async function regularBackup() { | ||||||
|     const now = new Date(); |     const now = new Date(); | ||||||
| @ -64,10 +65,10 @@ if (!fs.existsSync(dataDir.BACKUP_DIR)) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sql.dbReady.then(() => { | sql.dbReady.then(() => { | ||||||
|     setInterval(regularBackup, 60 * 60 * 1000); |     setInterval(cls.wrap(regularBackup), 60 * 60 * 1000); | ||||||
| 
 | 
 | ||||||
|     // kickoff backup immediately
 |     // kickoff backup immediately
 | ||||||
|     setTimeout(regularBackup, 1000); |     setTimeout(cls.wrap(regularBackup), 1000); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								src/services/cls.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/services/cls.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | const clsHooked = require('cls-hooked'); | ||||||
|  | const namespace = clsHooked.createNamespace("trilium"); | ||||||
|  | 
 | ||||||
|  | async function init(callback) { | ||||||
|  |     return await namespace.runAndReturn(callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function wrap(callback) { | ||||||
|  |     return async () => await init(callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  |     init, | ||||||
|  |     wrap, | ||||||
|  |     namespace | ||||||
|  | }; | ||||||
| @ -5,6 +5,7 @@ const log = require('./log'); | |||||||
| const messaging = require('./messaging'); | const messaging = require('./messaging'); | ||||||
| const sync_mutex = require('./sync_mutex'); | const sync_mutex = require('./sync_mutex'); | ||||||
| const utils = require('./utils'); | const utils = require('./utils'); | ||||||
|  | const cls = require('./cls'); | ||||||
| 
 | 
 | ||||||
| async function runCheck(query, errorText, errorList) { | async function runCheck(query, errorText, errorList) { | ||||||
|     utils.assertArguments(query, errorText, errorList); |     utils.assertArguments(query, errorText, errorList); | ||||||
| @ -268,10 +269,10 @@ async function runChecks() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sql.dbReady.then(() => { | sql.dbReady.then(() => { | ||||||
|     setInterval(runChecks, 60 * 60 * 1000); |     setInterval(cls.wrap(runChecks), 60 * 60 * 1000); | ||||||
| 
 | 
 | ||||||
|     // kickoff backup immediately
 |     // kickoff backup immediately
 | ||||||
|     setTimeout(runChecks, 10000); |     setTimeout(cls.wrap(runChecks), 10000); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|  | |||||||
| @ -262,16 +262,16 @@ async function loadFile(noteId, newNote, dataKey) { | |||||||
|         await protected_session.decryptNote(dataKey, oldNote); |         await protected_session.decryptNote(dataKey, oldNote); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     newNote.detail.content = oldNote.content; |     newNote.content = oldNote.content; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function updateNote(noteId, newNote, dataKey, sourceId) { | async function updateNote(noteId, newNote, dataKey, sourceId) { | ||||||
|     if (newNote.detail.type === 'file') { |     if (newNote.type === 'file') { | ||||||
|         await loadFile(noteId, newNote, dataKey); |         await loadFile(noteId, newNote, dataKey); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (newNote.detail.isProtected) { |     if (newNote.isProtected) { | ||||||
|         await protected_session.encryptNote(dataKey, newNote.detail); |         await protected_session.encryptNote(dataKey, newNote); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const labelsMap = await labels.getNoteLabelMap(noteId); |     const labelsMap = await labels.getNoteLabelMap(noteId); | ||||||
| @ -287,7 +287,7 @@ async function updateNote(noteId, newNote, dataKey, sourceId) { | |||||||
|         "SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND dateModifiedTo >= ?", [noteId, revisionCutoff]); |         "SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND dateModifiedTo >= ?", [noteId, revisionCutoff]); | ||||||
| 
 | 
 | ||||||
|     await sql.doInTransaction(async () => { |     await sql.doInTransaction(async () => { | ||||||
|         const msSinceDateCreated = now.getTime() - utils.parseDateTime(newNote.detail.dateCreated).getTime(); |         const msSinceDateCreated = now.getTime() - utils.parseDateTime(newNote.dateCreated).getTime(); | ||||||
| 
 | 
 | ||||||
|         if (labelsMap.disable_versioning !== 'true' |         if (labelsMap.disable_versioning !== 'true' | ||||||
|             && !existingnoteRevisionId |             && !existingnoteRevisionId | ||||||
| @ -296,14 +296,14 @@ async function updateNote(noteId, newNote, dataKey, sourceId) { | |||||||
|             await saveNoteRevision(noteId, dataKey, sourceId, nowStr); |             await saveNoteRevision(noteId, dataKey, sourceId, nowStr); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         await saveNoteImages(noteId, newNote.detail.content, sourceId); |         await saveNoteImages(noteId, newNote.content, sourceId); | ||||||
| 
 | 
 | ||||||
|         await protectNoteRevisions(noteId, dataKey, newNote.detail.isProtected); |         await protectNoteRevisions(noteId, dataKey, newNote.isProtected); | ||||||
| 
 | 
 | ||||||
|         await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [ |         await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [ | ||||||
|             newNote.detail.title, |             newNote.title, | ||||||
|             newNote.detail.content, |             newNote.content, | ||||||
|             newNote.detail.isProtected, |             newNote.isProtected, | ||||||
|             nowStr, |             nowStr, | ||||||
|             noteId]); |             noteId]); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| const script = require('./script'); | const script = require('./script'); | ||||||
| const Repository = require('./repository'); | const Repository = require('./repository'); | ||||||
|  | const cls = require('./cls'); | ||||||
| 
 | 
 | ||||||
| const repo = new Repository(); | const repo = new Repository(); | ||||||
| 
 | 
 | ||||||
| @ -20,8 +21,8 @@ async function runNotesWithLabel(runAttrValue) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| setTimeout(() => runNotesWithLabel('backend_startup'), 10 * 1000); | setTimeout(cls.wrap(() => runNotesWithLabel('backend_startup')), 10 * 1000); | ||||||
| 
 | 
 | ||||||
| setInterval(() => runNotesWithLabel('hourly'), 3600 * 1000); | setInterval(cls.wrap(() => runNotesWithLabel('hourly')), 3600 * 1000); | ||||||
| 
 | 
 | ||||||
| setInterval(() => runNotesWithLabel('daily'), 24 * 3600 * 1000); | setInterval(cls.wrap(() => runNotesWithLabel('daily'), 24 * 3600 * 1000)); | ||||||
| @ -1,6 +1,7 @@ | |||||||
| const utils = require('./utils'); | const utils = require('./utils'); | ||||||
| const log = require('./log'); | const log = require('./log'); | ||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
|  | const cls = require('./cls'); | ||||||
| 
 | 
 | ||||||
| async function saveSourceId(sourceId) { | async function saveSourceId(sourceId) { | ||||||
|     await sql.doInTransaction(async () => { |     await sql.doInTransaction(async () => { | ||||||
| @ -41,7 +42,7 @@ function isLocalSourceId(srcId) { | |||||||
| const currentSourceId = createSourceId(); | const currentSourceId = createSourceId(); | ||||||
| 
 | 
 | ||||||
| // this will also refresh source IDs
 | // this will also refresh source IDs
 | ||||||
| sql.dbReady.then(() => saveSourceId(currentSourceId)); | sql.dbReady.then(cls.wrap(() => saveSourceId(currentSourceId))); | ||||||
| 
 | 
 | ||||||
| function getCurrentSourceId() { | function getCurrentSourceId() { | ||||||
|     return currentSourceId; |     return currentSourceId; | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ const fs = require('fs'); | |||||||
| const sqlite = require('sqlite'); | const sqlite = require('sqlite'); | ||||||
| const app_info = require('./app_info'); | const app_info = require('./app_info'); | ||||||
| const resource_dir = require('./resource_dir'); | const resource_dir = require('./resource_dir'); | ||||||
|  | const cls = require('./cls'); | ||||||
| 
 | 
 | ||||||
| async function createConnection() { | async function createConnection() { | ||||||
|     return await sqlite.open(dataDir.DOCUMENT_PATH, {Promise}); |     return await sqlite.open(dataDir.DOCUMENT_PATH, {Promise}); | ||||||
| @ -15,7 +16,7 @@ const dbConnected = createConnection(); | |||||||
| 
 | 
 | ||||||
| let dbReadyResolve = null; | let dbReadyResolve = null; | ||||||
| const dbReady = new Promise((resolve, reject) => { | const dbReady = new Promise((resolve, reject) => { | ||||||
|     dbConnected.then(async db => { |     dbConnected.then(cls.wrap(async db => { | ||||||
|         await execute("PRAGMA foreign_keys = ON"); |         await execute("PRAGMA foreign_keys = ON"); | ||||||
| 
 | 
 | ||||||
|         dbReadyResolve = () => { |         dbReadyResolve = () => { | ||||||
| @ -65,7 +66,7 @@ const dbReady = new Promise((resolve, reject) => { | |||||||
| 
 | 
 | ||||||
|             resolve(db); |             resolve(db); | ||||||
|         } |         } | ||||||
|     }) |     })) | ||||||
|     .catch(e => { |     .catch(e => { | ||||||
|         console.log("Error connecting to DB.", e); |         console.log("Error connecting to DB.", e); | ||||||
|         process.exit(1); |         process.exit(1); | ||||||
| @ -191,6 +192,15 @@ let transactionActive = false; | |||||||
| let transactionPromise = null; | let transactionPromise = null; | ||||||
| 
 | 
 | ||||||
| async function doInTransaction(func) { | async function doInTransaction(func) { | ||||||
|  |     if (cls.namespace.get('isInTransaction')) { | ||||||
|  |         console.log("Transaction already active"); | ||||||
|  | 
 | ||||||
|  |         return await func(); | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         console.log("Starting new transaction"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     while (transactionActive) { |     while (transactionActive) { | ||||||
|         await transactionPromise; |         await transactionPromise; | ||||||
|     } |     } | ||||||
| @ -201,6 +211,8 @@ async function doInTransaction(func) { | |||||||
|     transactionActive = true; |     transactionActive = true; | ||||||
|     transactionPromise = new Promise(async (resolve, reject) => { |     transactionPromise = new Promise(async (resolve, reject) => { | ||||||
|         try { |         try { | ||||||
|  |             cls.namespace.set('isInTransaction', true); | ||||||
|  | 
 | ||||||
|             await beginTransaction(); |             await beginTransaction(); | ||||||
| 
 | 
 | ||||||
|             ret = await func(); |             ret = await func(); | ||||||
| @ -219,6 +231,9 @@ async function doInTransaction(func) { | |||||||
| 
 | 
 | ||||||
|             reject(e); |             reject(e); | ||||||
|         } |         } | ||||||
|  |         finally { | ||||||
|  |             cls.namespace.set('isInTransaction', false); | ||||||
|  |         } | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     if (transactionActive) { |     if (transactionActive) { | ||||||
|  | |||||||
| @ -15,6 +15,7 @@ const app_info = require('./app_info'); | |||||||
| const messaging = require('./messaging'); | const messaging = require('./messaging'); | ||||||
| const sync_setup = require('./sync_setup'); | const sync_setup = require('./sync_setup'); | ||||||
| const sync_mutex = require('./sync_mutex'); | const sync_mutex = require('./sync_mutex'); | ||||||
|  | const cls = require('./cls'); | ||||||
| 
 | 
 | ||||||
| let proxyToggle = true; | let proxyToggle = true; | ||||||
| let syncServerCertificate = null; | let syncServerCertificate = null; | ||||||
| @ -347,10 +348,10 @@ sql.dbReady.then(() => { | |||||||
|             syncServerCertificate = fs.readFileSync(sync_setup.SYNC_CERT_PATH); |             syncServerCertificate = fs.readFileSync(sync_setup.SYNC_CERT_PATH); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         setInterval(sync, 60000); |         setInterval(cls.wrap(sync), 60000); | ||||||
| 
 | 
 | ||||||
|         // kickoff initial sync immediately
 |         // kickoff initial sync immediately
 | ||||||
|         setTimeout(sync, 1000); |         setTimeout(cls.wrap(sync), 1000); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         log.info("Sync server not configured, sync timer not running.") |         log.info("Sync server not configured, sync timer not running.") | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 azivner
						azivner