ResourceRequest.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. "use strict";
  2. const Deferred = require("./Deferred");
  3. const errors = require("./errors");
  4. function fbind(fn, ctx) {
  5. return function bound() {
  6. return fn.apply(ctx, arguments);
  7. };
  8. }
  9. /**
  10. * Wraps a users request for a resource
  11. * Basically a promise mashed in with a timeout
  12. * @private
  13. */
  14. class ResourceRequest extends Deferred {
  15. /**
  16. * [constructor description]
  17. * @param {Number} ttl timeout
  18. */
  19. constructor(ttl, Promise) {
  20. super(Promise);
  21. this._creationTimestamp = Date.now();
  22. this._timeout = null;
  23. if (ttl !== undefined) {
  24. this.setTimeout(ttl);
  25. }
  26. }
  27. setTimeout(delay) {
  28. if (this._state !== ResourceRequest.PENDING) {
  29. return;
  30. }
  31. const ttl = parseInt(delay, 10);
  32. if (isNaN(ttl) || ttl <= 0) {
  33. throw new Error("delay must be a positive int");
  34. }
  35. const age = Date.now() - this._creationTimestamp;
  36. if (this._timeout) {
  37. this.removeTimeout();
  38. }
  39. this._timeout = setTimeout(
  40. fbind(this._fireTimeout, this),
  41. Math.max(ttl - age, 0)
  42. );
  43. }
  44. removeTimeout() {
  45. if (this._timeout) {
  46. clearTimeout(this._timeout);
  47. }
  48. this._timeout = null;
  49. }
  50. _fireTimeout() {
  51. this.reject(new errors.TimeoutError("ResourceRequest timed out"));
  52. }
  53. reject(reason) {
  54. this.removeTimeout();
  55. super.reject(reason);
  56. }
  57. resolve(value) {
  58. this.removeTimeout();
  59. super.resolve(value);
  60. }
  61. }
  62. module.exports = ResourceRequest;