sync-service.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. const utils = require('../libs/utils');
  2. const path = require('path');
  3. const MongoClient = require('mongoose').mongo.MongoClient;
  4. const appConfig = require('../config/app');
  5. const SyncSeq = require('./sync-seq');
  6. const { format } = require('date-fns');
  7. const remotedb = 'coloring_ol'; // 远端数据库
  8. const localdb = 'artsite'; // 本地的数据库
  9. /**
  10. * sync from remote
  11. */
  12. async function run() {
  13. const localClient = await new MongoClient(appConfig.mongodbUrl).connect();
  14. const remoteClient = await new MongoClient(appConfig.syncUrl).connect();
  15. let remoteDB = remoteClient.db(remotedb);
  16. let localDB = localClient.db(localdb);
  17. console.log('Connect to remote mongodb ' + appConfig.syncUrl + ' success!');
  18. // 读取远程syncevent表
  19. const synceventTB = remoteDB.collection('syncevents');
  20. // get current local slave sync seq (use mongoose)
  21. let seq = -1;
  22. let seqDoc = await SyncSeq.findOne();
  23. if (seqDoc) seq = seqDoc.seq;
  24. else seqDoc = new SyncSeq({});
  25. let count, localtb, remotetb, localdoc, remotedoc;
  26. setTimeout(async function cycleRun() {
  27. try {
  28. let eventDocs = await synceventTB.find({ _id: { $gt: seq } }).limit(200).toArray() || [];
  29. count = 0;
  30. for (let i = 0; i < eventDocs.length; i++) {
  31. let eventDoc = eventDocs[i];
  32. console.log(eventDoc);
  33. if (eventDoc.tb == 'identitycounters') continue; // skip
  34. // 只同步特定的几张表: arts, daily-arts, users, albums, translates
  35. if (eventDoc.tb != 'arts'
  36. && eventDoc.tb != 'daily-arts'
  37. && eventDoc.tb != 'users'
  38. && eventDoc.tb != 'albums'
  39. && eventDoc.tb != 'videostories'
  40. && eventDoc.tb != 'translates') {
  41. continue;
  42. }
  43. if (!eventDoc.db) eventDoc.db = remoteDbs[0];
  44. // 对应的表
  45. remotetb = remoteDB.collection(eventDoc.tb);
  46. localtb = localDB.collection(eventDoc.tb);
  47. if (!remotetb || !localtb) {
  48. console.warn('unkown sync database: ' + eventDoc.db + ', will skip');
  49. continue;
  50. }
  51. if (eventDoc.op == 'remove') {
  52. await localtb.deleteOne({ _id: eventDoc.rid });
  53. console.log("sync remove : " + eventDoc.tb + " " + eventDoc.rid);
  54. } else if (eventDoc.op == 'save') {
  55. remotedoc = await remotetb.findOne({ _id: eventDoc.rid });
  56. localdoc = await localtb.findOne({ _id: eventDoc.rid });
  57. if (!remotedoc) {
  58. console.log("remote doc not found, may be deleted, skip: " + eventDoc.tb + " " + eventDoc.rid);
  59. } else if (!localdoc) {
  60. console.log("sync add :" + eventDoc.tb + " " + eventDoc.rid);
  61. try {
  62. await localtb.insertOne(remotedoc);
  63. } catch (e) {
  64. console.error(e);
  65. }
  66. } else {
  67. console.log("sync update :" + eventDoc.tb + " " + eventDoc.rid);
  68. if (eventDoc.tb == 'arts') { // art 表需保留新的title,desc,copy 这几个字段,避免覆盖
  69. remotedoc.title = localdoc.title;
  70. remotedoc.desc = localdoc.desc;
  71. remotedoc.seoTitle = localdoc.seoTitle;
  72. remotedoc.seoDescription = localdoc.seoDescription;
  73. } else if (eventDoc.tb == 'albums' || eventDoc.tb == 'videostories') { // albums 和 videostories 表需保留新增的seoTitle,seoDescription字段,避免覆盖
  74. remotedoc.seoTitle = localdoc.seoTitle;
  75. remotedoc.seoDescription = localdoc.seoDescription;
  76. }
  77. await localtb.replaceOne({ _id: eventDoc.rid }, remotedoc);
  78. }
  79. }
  80. seq = eventDoc._id;
  81. seqDoc.seq = seq;
  82. await seqDoc.save();
  83. count++;
  84. }
  85. console.log(`${format(new Date(), 'yyyy-MM-dd HH:mm')} sync event length: ${eventDocs.length}, precessed: ${count}`);
  86. } catch (err) {
  87. console.error(err);
  88. }
  89. if (count > 0) setTimeout(cycleRun, 0);
  90. // else setTimeout(run, delay);
  91. }, 0);
  92. }
  93. module.exports = {
  94. run
  95. }
  96. if (require.main == module) {
  97. run().catch(console.error);
  98. }