DrawioFilePolling.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /**
  2. * Copyright (c) 2006-2024, draw.io AG
  3. * Copyright (c) 2006-2024, JGraph Ltd
  4. *
  5. * Class for polling files for changes.
  6. */
  7. DrawioFilePolling = function(file, sync)
  8. {
  9. this.file = file;
  10. this.sync = sync;
  11. };
  12. /**
  13. * Maximum number if attempts to poll after an error.
  14. */
  15. DrawioFilePolling.prototype.maxRetries = 2;
  16. /**
  17. * The minimum delay between polls for adaptive polling.
  18. */
  19. DrawioFilePolling.prototype.minPollDelay = 2000;
  20. /**
  21. * Starts the polling with the given delay.
  22. */
  23. DrawioFilePolling.prototype.start = function(delay)
  24. {
  25. if (!this.isConnected())
  26. {
  27. this.maxDelay = delay;
  28. this.delay = delay;
  29. var threadFn = mxUtils.bind(this, function()
  30. {
  31. this.poll(0, nextFn);
  32. });
  33. var nextFn = mxUtils.bind(this, function()
  34. {
  35. // To get adaptive polling, we use timeout instead of interval
  36. this.thread = setTimeout(threadFn, this.delay);
  37. this.delay = Math.min(this.maxDelay, this.delay + 2000); // TODO this or this.delay * 2
  38. });
  39. nextFn();
  40. EditorUi.debug('DrawioFilePolling.start', [this],
  41. 'thread', this.thread, 'delay', delay,
  42. 'rev', this.file.getCurrentRevisionId());
  43. }
  44. };
  45. /**
  46. * Checks if the file has been modified.
  47. */
  48. DrawioFilePolling.prototype.updateStatus = function()
  49. {
  50. if (this.hasOtherWriters())
  51. {
  52. this.sync.lastMessage = mxResources.get('otherUsersEditing');
  53. }
  54. this.sync.lastModified = this.file.getLastModifiedDate();
  55. this.sync.updateStatus();
  56. };
  57. /**
  58. * Checks if the file has been modified.
  59. */
  60. DrawioFilePolling.prototype.poll = function(retry, nextFn)
  61. {
  62. retry = (retry != null) ? retry : 0;
  63. var handleError = mxUtils.bind(this, function(e)
  64. {
  65. if (retry < this.maxRetries)
  66. {
  67. this.retryPoll(mxUtils.bind(this, function()
  68. {
  69. this.poll(retry + 1, nextFn);
  70. }));
  71. }
  72. else
  73. {
  74. nextFn();
  75. }
  76. });
  77. this.file.getLatestVersionId(mxUtils.bind(this, function(latestVersionId)
  78. {
  79. if (latestVersionId != -1)
  80. {
  81. var currentVersionId = this.file.getCurrentRevisionId();
  82. if (latestVersionId != currentVersionId)
  83. {
  84. this.file.getLatestVersion(mxUtils.bind(this, function(latestFile)
  85. {
  86. this.file.mergeFile(latestFile, mxUtils.bind(this, function()
  87. {
  88. // An update is detected, so start adaptive polling
  89. this.delay = this.minPollDelay;
  90. this.lastOtherWriter = Date.now();
  91. this.updateStatus();
  92. nextFn();
  93. }), handleError);
  94. }), handleError);
  95. }
  96. else
  97. {
  98. this.updateStatus();
  99. nextFn();
  100. }
  101. }
  102. else
  103. {
  104. nextFn();
  105. }
  106. }), handleError);
  107. };
  108. /**
  109. * Translates this point by the given vector.
  110. *
  111. * @param {number} dx X-coordinate of the translation.
  112. * @param {number} dy Y-coordinate of the translation.
  113. */
  114. DrawioFilePolling.prototype.retryPoll = function(fn)
  115. {
  116. var delay = 300 + Math.random() * 300;
  117. window.setTimeout(fn, delay);
  118. EditorUi.debug('StorageFile.retryPoll', [this], 'delay', delay);
  119. };
  120. /**
  121. * Stops the polling.
  122. */
  123. DrawioFilePolling.prototype.stop = function()
  124. {
  125. EditorUi.debug('DrawioFilePolling.stop',
  126. [this], 'thread', this.thread);
  127. clearTimeout(this.thread);
  128. this.thread = null;
  129. };
  130. /**
  131. * Returns true if polling is active.
  132. */
  133. DrawioFilePolling.prototype.isConnected = function()
  134. {
  135. return this.thread != null;
  136. };
  137. DrawioFilePolling.prototype.hasOtherWriters = function()
  138. {
  139. return this.lastOtherWriter != null && Date.now() - this.lastOtherWriter < 60 * 1000; // Other writer detected in the last minute
  140. };