EventsManager.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import Actions from "./enum/Actions.js"
  2. import Codes from "./enum/Codes.js"
  3. import util from "./util.js"
  4. import Logger from "./Logger.js"
  5. import ActionResponseTimeoutError from "./error/ActionResponseTimeoutError.js"
  6. const logger = new Logger('events')
  7. export default class EventsManager extends EventEmitter {
  8. constructor() {
  9. super(...arguments);
  10. this.events = new Map
  11. this.specialEvents = new Map
  12. }
  13. remove(traceId, code, signal, needDelete)
  14. {
  15. if (this.specialEvents.has(traceId) && !needDelete && code === Codes.Success) return;
  16. this.events.get(traceId) && (
  17. this.emit(traceId, {code, data:signal}),
  18. this.events.delete(traceId),
  19. this.specialEvents.delete(traceId)
  20. )
  21. // todo 写死数据纠正
  22. // if (this.specialEvents.has(this.traceId) && !needDelete && code === Codes.Success) return;
  23. // this.events.get(this.traceId) && (
  24. // this.emit(this.traceId, {code, data:signal}),
  25. // this.events.delete(this.traceId),
  26. // this.specialEvents.delete(this.traceId)
  27. // )
  28. }
  29. async track(e, t)
  30. {
  31. const traceId = e.traceId;
  32. this.traceId = traceId // todo 写死数据纠正
  33. this.emitTraceIdToDecoder(e);
  34. const { sampleRate, noReport=!1, special } = t || {};
  35. if (sampleRate && Math.random() > sampleRate) return Promise.resolve();
  36. const s = Actions[e.event] + "Action"
  37. const tag = e.tag;
  38. // 暂存traceId
  39. this.events.set(traceId, !0),
  40. special && this.specialEvents.set(traceId, !0);
  41. const startTime = Date.now();
  42. let c = null;
  43. return new Promise((resolve, reject) =>
  44. {
  45. if (noReport)
  46. return this.off(traceId),
  47. this.events.delete(traceId),
  48. resolve(void 0);
  49. // 移除traceId。events.delete在emit之后执行
  50. this.on(traceId, ({ code, data, msg }) =>
  51. {
  52. if (code === Codes.Success)
  53. resolve(data),
  54. this.off(traceId),
  55. logger.infoAndReportMeasurement({ metric: s, tag, extra: e.extra, startTime, traceId });
  56. else {
  57. if (code === Codes.ActionMaybeDelay) return;
  58. if (code === Codes.DoActionBlocked && e.event === Actions.Rotation) {
  59. logger.debug(s + " response code: " + code);
  60. return
  61. }
  62. const CodeError = util.getErrorByCode(code)
  63. , error = new CodeError(msg);
  64. this.off(traceId),
  65. reject(error),
  66. this.emit("actionResponseError", { error, event: e, tag }),
  67. logger.infoAndReportMeasurement({ metric: s, tag, extra: e.extra, error, startTime, traceId })
  68. }
  69. });
  70. // 超时报错
  71. const time = e.timeout || 2e3;
  72. c = window.setTimeout(() =>
  73. {
  74. if (c && clearTimeout(c), !this.events.get(traceId)) return;
  75. const error = new ActionResponseTimeoutError(`${s} timeout in ${time}ms`);
  76. this.emit("actionResponseTimeout", { error, event: e, tag }),
  77. reject(error),
  78. this.events.delete(traceId),
  79. this.off(traceId),
  80. logger.infoAndReportMeasurement({ metric: s, tag, extra: e.extra, error, startTime, traceId })
  81. }, time)
  82. })
  83. }
  84. emitTraceIdToDecoder(e) {
  85. if (
  86. e.event === Actions.Rotation ||
  87. e.event === Actions.Clicking ||
  88. e.event === Actions.GetOnVehicle ||
  89. e.event === Actions.GetOffVehicle
  90. ) {
  91. const t = {
  92. [Actions.Rotation]: "Rotation",
  93. [Actions.GetOnVehicle]: "GetOnVehicle",
  94. [Actions.GetOffVehicle]: "GetOffVehicle",
  95. [Actions.Clicking]: "MoveTo"
  96. };
  97. this.emit("traceId", {
  98. traceId: e.traceId,
  99. timestamp: Date.now(),
  100. event: t[e.event]
  101. })
  102. }
  103. }
  104. }
  105. const eventsManager = new EventsManager();
  106. export { eventsManager };