agent.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // ===========================================
  2. // REQUARKS WIKI - Background Agent
  3. // 1.0.0
  4. // Licensed under AGPLv3
  5. // ===========================================
  6. global.ROOTPATH = __dirname;
  7. // ----------------------------------------
  8. // Load modules
  9. // ----------------------------------------
  10. global.winston = require('winston');
  11. winston.info('[AGENT] Background Agent is initializing...');
  12. var appconfig = require('./models/config')('./config.yml');
  13. global.git = require('./models/git').init(appconfig);
  14. global.entries = require('./models/entries').init(appconfig);
  15. global.mark = require('./models/markdown');
  16. global.search = require('./models/search').init(appconfig);
  17. var _ = require('lodash');
  18. var moment = require('moment');
  19. var Promise = require('bluebird');
  20. var fs = Promise.promisifyAll(require("fs-extra"));
  21. var path = require('path');
  22. var cron = require('cron').CronJob;
  23. // ----------------------------------------
  24. // Start Cron
  25. // ----------------------------------------
  26. var jobIsBusy = false;
  27. var job = new cron({
  28. cronTime: '0 */5 * * * *',
  29. onTick: () => {
  30. // Make sure we don't start two concurrent jobs
  31. if(jobIsBusy) {
  32. winston.warn('[AGENT] Previous job has not completed gracefully or is still running! Skipping for now. (This is not normal, you should investigate)');
  33. return;
  34. }
  35. jobIsBusy = true;
  36. // Prepare async job collector
  37. let jobs = [];
  38. let repoPath = path.resolve(ROOTPATH, appconfig.datadir.repo);
  39. // ----------------------------------------
  40. // Compile Jobs
  41. // ----------------------------------------
  42. //-> Resync with Git remote
  43. jobs.push(git.onReady.then(() => {
  44. return git.resync().then(() => {
  45. //-> Stream all documents
  46. let cacheJobs = [];
  47. fs.walk(repoPath).on('data', function (item) {
  48. if(path.extname(item.path) === '.md') {
  49. let entryPath = entries.parsePath(entries.getEntryPathFromFullPath(item.path));
  50. let cachePath = entries.getCachePath(entryPath);
  51. //-> Purge outdated cache
  52. cacheJobs.push(
  53. fs.statAsync(cachePath).then((st) => {
  54. return moment(st.mtime).isBefore(item.stats.mtime) ? 'expired' : 'active';
  55. }).catch((err) => {
  56. return (err.code !== 'EEXIST') ? err : 'new';
  57. }).then((fileStatus) => {
  58. //-> Delete expired cache file
  59. if(fileStatus === 'expired') {
  60. return fs.unlinkAsync(cachePath).return(fileStatus);
  61. }
  62. return fileStatus;
  63. }).then((fileStatus) => {
  64. //-> Update search index
  65. if(fileStatus !== 'active') {
  66. return entries.fetchTextVersion(entryPath).then((content) => {
  67. console.log(content);
  68. });
  69. }
  70. return true;
  71. })
  72. );
  73. }
  74. });
  75. return Promise.all(cacheJobs);
  76. });
  77. }));
  78. // ----------------------------------------
  79. // Run
  80. // ----------------------------------------
  81. Promise.all(jobs).then(() => {
  82. winston.info('[AGENT] All jobs completed successfully! Going to sleep for now... [' + moment().toISOString() + ']');
  83. }).catch((err) => {
  84. winston.error('[AGENT] One or more jobs have failed [' + moment().toISOString() + ']: ', err);
  85. }).finally(() => {
  86. jobIsBusy = false;
  87. });
  88. },
  89. start: true,
  90. timeZone: 'UTC',
  91. runOnInit: true
  92. });
  93. // ----------------------------------------
  94. // Shutdown gracefully
  95. // ----------------------------------------
  96. process.on('disconnect', () => {
  97. winston.warn('[AGENT] Lost connection to main server. Exiting... [' + moment().toISOString() + ']');
  98. job.stop();
  99. process.exit();
  100. });
  101. process.on('exit', () => {
  102. job.stop();
  103. });