bundle-context.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /**
  2. * TODO here:
  3. * Create try catch in start and stop: modules are not being unloaded/reloaded if there is exception in stop
  4. * Improve fields, solve redundancy, on "on" and "after"
  5. * Maybe use the XPrefix to create an endpoint named events or fetch a channel
  6. * channel should work for emit aswell
  7. *
  8. * Separate vars in several contexts
  9. *
  10. * For the endpoint when bundle is stopped we could
  11. *
  12. * */
  13. var log = require('hlogger').createLogger('bundle-context');
  14. /**
  15. * Check method in bundleActivator if not check as bundleMethod
  16. */
  17. function solveMethod(instance,name) {
  18. if(instance.bundleActivator != undefined && instance.bundleActivator[name]!= undefined ) {
  19. return (context) => {instance.bundleActivator[name](context)};
  20. }
  21. var subName = "bundle" + name[0].toUpperCase() + name.slice(1);
  22. if(instance[subName] != undefined ) {
  23. return (context) => {instance[subName](context)};
  24. }
  25. return null;
  26. }
  27. // Maybe create channel code here and completelly remove on here
  28. //
  29. // This will contain the listeners for Activator
  30. class BundleContext /*extends XEventEmitter*/ {
  31. constructor(conf) {
  32. /*super();*/
  33. var info = {};
  34. ({id:info.id,
  35. name:info.name,
  36. manager:info.manager,
  37. instance:info.instance,
  38. modulePath:info.modulePath,
  39. pkgInfo:info.pkgInfo} = conf);
  40. //info = fromFields(["id","name","manager","instance","modulePath","pkgInfo"],conf);
  41. info.state = 0;
  42. info.loadDate = new Date();
  43. this.info = info;
  44. this._bundleContext = {
  45. intervals:[],
  46. timeouts:[],
  47. instanceStart: null,
  48. instanceStop: null
  49. };
  50. var dummyFunc = () => {};
  51. this._bundleContext.instanceStart = solveMethod(this.instance,"start") || dummyFunc;
  52. this._bundleContext.instanceStop = solveMethod(this.instance,"stop") || dummyFunc;
  53. // New contextual events
  54. }
  55. get events() {
  56. if(this._events == undefined) {
  57. this._events = this.manager.eventual.createContext();
  58. }
  59. return this._events;
  60. }
  61. get id() {
  62. return this.info.id;
  63. }
  64. get modulePath() {
  65. return this.info.modulePath;
  66. }
  67. get name() {
  68. return this.info.name;
  69. }
  70. get instance() {
  71. return this.info.instance;
  72. }
  73. get manager() {
  74. return this.info.manager;
  75. }
  76. get version() {
  77. return this.info.version;
  78. }
  79. start() {
  80. if(this.info.state == 1) {
  81. log.warn("Instance is turned on trying to turn off first");
  82. this.stop();
  83. }
  84. try {
  85. this._bundleContext.instanceStart(this);
  86. } catch(e) {
  87. log.error("Bundle start error: " + this.name + "\n",e);
  88. }
  89. this.info.state = 1;
  90. this.info.startDate = new Date();
  91. }
  92. stop() {
  93. if(this.info.state == 0) return;
  94. //this.toggleOff("start");
  95. this.emit("stop");
  96. try {
  97. this._bundleContext.instanceStop(this);
  98. } catch( e) {
  99. log.error("Bundle stop error: " + this.name + "\n",e);
  100. }
  101. this.clearIntervals();
  102. this.clearTimeouts();
  103. this.events.destroy();
  104. //this.manager.events.removeListener(this);
  105. this.info.state = 0;
  106. }
  107. emit(name,...args) {
  108. return this.events.emit(this.name + ":" +name,...args);
  109. }
  110. channel(name) {
  111. return this.events.channel(name);
  112. }
  113. on(name,cb) {
  114. // Only create events if does not exists, maybe with a getter
  115. this.events.on(name,cb);
  116. return this;
  117. }
  118. // Watcher
  119. watch(name,cb) {
  120. this.events.watch(name,cb);
  121. }
  122. set(name,value) {
  123. this.events.set(this.name + ":" + name, value);
  124. }
  125. unset(name) {
  126. this.events.unset(this.name + ":" + name);
  127. }
  128. /*on(...args) {
  129. var cb = args.pop();
  130. var evtName = args.join(":");
  131. this.manager.events.on(this,evtName ,cb);
  132. return this;
  133. }*/
  134. after(name,cb) { // Priorities
  135. this.events.on(name,cb,1000);
  136. return this;
  137. }
  138. // Wrappers
  139. /**
  140. * @param {array} args
  141. * @param {function} callback
  142. */
  143. with(args,callback) {
  144. return this.manager.with(args,callback);
  145. }
  146. /**
  147. * @param {string} match
  148. * @param {variable} ...args
  149. */
  150. call(name,...args) {
  151. return this.manager.call(name,args);
  152. }
  153. /*
  154. get(name) {
  155. var ctx = this.manager.get(name);
  156. if(ctx == null || ctx.info.state != 1) {
  157. // Early bail
  158. return null;
  159. }
  160. return ctx.instance;
  161. }*/
  162. // Auto clear helpers
  163. //
  164. setInterval(cb,n) {
  165. var ret = setInterval(cb,n);
  166. this._bundleContext.intervals.push(ret);
  167. return ret;
  168. }
  169. clearIntervals() {
  170. this._bundleContext.intervals.forEach((v) => {
  171. clearInterval(v);
  172. });
  173. }
  174. setTimeout(cb,n) {
  175. var ret = setTimeout(cb,n);
  176. this._bundleContext.timeouts.push(ret);
  177. return ret;
  178. }
  179. clearTimeouts() {
  180. this._bundleContext.timeouts.forEach((v) => {
  181. clearTimeout(v);
  182. });
  183. }
  184. }
  185. module.exports = BundleContext;