RequestableEventDataSource.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. var RequestableEventDataSource = EventDataSource.extend({
  2. currentStart: null,
  3. currentEnd: null,
  4. currentTimezone: null,
  5. requestsByUid: null,
  6. pendingSourceCnt: 0,
  7. constructor: function() {
  8. EventDataSource.call(this);
  9. this.requestsByUid = {};
  10. },
  11. request: function(start, end, timezone, force) {
  12. if (
  13. force ||
  14. !this.currentStart || // first fetch?
  15. this.currentTimezone !== timezone || // different timezone?
  16. start.isBefore(this.currentStart) || // out of bounds?
  17. end.isAfter(this.currentEnd) // "
  18. ) {
  19. this.currentTimezone = timezone;
  20. this.currentStart = start;
  21. this.currentEnd = end;
  22. this.currentUnzonedRange = new UnzonedRange(
  23. start.clone().stripZone(),
  24. end.clone().stripZone()
  25. );
  26. this.refetchAllSources();
  27. }
  28. },
  29. refetchSource: function(eventSource) {
  30. if (this.currentUnzonedRange) {
  31. this.freeze();
  32. this.purgeSource(eventSource);
  33. this.requestSource(eventSource);
  34. this.thaw();
  35. }
  36. },
  37. refetchAllSources: function() {
  38. if (this.currentUnzonedRange) {
  39. this.freeze();
  40. this.purgeAllSources();
  41. this.requestSources(this.getSources());
  42. this.thaw();
  43. }
  44. },
  45. getSources: function() {
  46. return [];
  47. },
  48. requestSources: function(sources) {
  49. this.freeze();
  50. for (var i = 0; i < sources.length; i++) {
  51. this.requestSource(sources[i]);
  52. }
  53. this.thaw();
  54. },
  55. requestSource: function(source) {
  56. var _this = this;
  57. var request = { source: source, status: 'pending' };
  58. this.requestsByUid[source.uid] = request;
  59. this.pendingSourceCnt += 1;
  60. source.fetch(this.currentStart, this.currentEnd, this.currentTimezone).then(function(eventDefs) {
  61. if (request.status !== 'cancelled') {
  62. request.status = 'completed';
  63. request.eventDefs = eventDefs;
  64. _this.addEventDefs(eventDefs);
  65. _this.reportSourceDone();
  66. }
  67. }, function() { // failure
  68. if (request.status !== 'cancelled') {
  69. request.status = 'failed';
  70. _this.reportSourceDone();
  71. }
  72. });
  73. },
  74. purgeSource: function(source) {
  75. var request = this.requestsByUid[source.uid];
  76. if (request) {
  77. delete this.requestsByUid[source.uid];
  78. if (request.status === 'pending') {
  79. request.status = 'cancelled';
  80. this.reportSourceDone();
  81. }
  82. else if (request.status === 'completed') {
  83. this.freeze();
  84. request.eventDefs.forEach(this.removeEventDef.bind(this));
  85. this.thaw();
  86. }
  87. }
  88. },
  89. purgeAllSources: function() {
  90. var requestsByUid = this.requestsByUid;
  91. var uid, request;
  92. var completedCnt = 0;
  93. for (uid in requestsByUid) {
  94. request = requestsByUid[uid];
  95. if (request.status === 'pending') {
  96. request.status = 'cancelled';
  97. }
  98. else if (request.status === 'completed') {
  99. completedCnt++;
  100. }
  101. }
  102. this.pendingSourceCnt = 0;
  103. this.requestsByUid = {};
  104. if (completedCnt) {
  105. this.removeAllEventDefs();
  106. }
  107. },
  108. reportSourceDone: function() {
  109. this.pendingSourceCnt--;
  110. this.trySendOutbound();
  111. },
  112. canTrigger: function() {
  113. return EventDataSource.prototype.canTrigger.apply(this, arguments) &&
  114. !this.pendingSourceCnt;
  115. }
  116. });