index.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2015 rain1017.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  12. // implied. See the License for the specific language governing
  13. // permissions and limitations under the License. See the AUTHORS file
  14. // for names of contributors.
  15. 'use strict';
  16. var memdb = require('memdb-client');
  17. var P = memdb.Promise;
  18. var logger = memdb.logger.getLogger('timer', __filename);
  19. var Timer = function(app, opts){
  20. opts = opts || {};
  21. this.app = app;
  22. this.timers = {}; // {id : timer}
  23. };
  24. var proto = Timer.prototype;
  25. proto.name = 'timer';
  26. proto.start = function(cb){
  27. cb();
  28. };
  29. proto.stop = function(force, cb){
  30. this.clearAll();
  31. cb();
  32. };
  33. proto.setTimeout = function(fn, time, id) {
  34. var timer = setTimeout(this._wrapTimer(id, fn, true), time);
  35. if(!!id){
  36. if(this.timers.hasOwnProperty(id)) {
  37. logger.warn('id already exists in timers map, will replace: id=%s', id);
  38. this.clear(id);
  39. }
  40. this.timers[id] = timer;
  41. }
  42. return timer;
  43. };
  44. proto.setInterval = function(fn, time, id) {
  45. var timer = setInterval(this._wrapTimer(id, fn), time);
  46. if(!!id){
  47. if(this.timers.hasOwnProperty(id)) {
  48. logger.warn('id already exists in timers map, will replace: id=%s', id);
  49. this.clear(id);
  50. }
  51. this.timers[id] = timer;
  52. }
  53. return timer;
  54. };
  55. proto.clear = function(id) {
  56. var timer = this.timers[id];
  57. if(timer) {
  58. if(timer._repeat){
  59. clearInterval(timer);
  60. }
  61. else{
  62. clearTimeout(timer);
  63. }
  64. delete this.timers[id];
  65. logger.debug('clear %s', id);
  66. return true;
  67. }
  68. return false;
  69. };
  70. proto.clearAll = function() {
  71. var self = this;
  72. Object.keys(this.timers).forEach(function(key){
  73. self.clear(key);
  74. });
  75. };
  76. proto._wrapTimer = function(id, fn, autoRemove) {
  77. var self = this;
  78. return function(){
  79. logger.debug('on timer: %s', id);
  80. return self.app.memdb.goose.transaction(fn, self.app.getServerId())
  81. .then(function(){
  82. self.app.event.emit('transactionSuccess');
  83. }, function(e){
  84. self.app.event.emit('transactionFail');
  85. logger.error(e.stack);
  86. })
  87. .finally(function(){
  88. if(!!id && autoRemove) {
  89. delete self.timers[id];
  90. }
  91. });
  92. };
  93. };
  94. module.exports = function(app, opts){
  95. var timer = new Timer(app, opts);
  96. app.set(timer.name, timer, true);
  97. return timer;
  98. };