bundle-context.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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. //process.nextTick(() => {
  85. try {
  86. this._bundleContext.instanceStart(this);
  87. } catch(e) {
  88. log.error("Bundle start error: " + this.name + "\n",e);
  89. }
  90. //this.manager.events.toggleOn(this.name,this.instance);
  91. this.info.state = 1;
  92. this.info.startDate = new Date();
  93. //});
  94. }
  95. stop() {
  96. if(this.info.state == 0) return;
  97. //this.toggleOff("start");
  98. this.emit("stop");
  99. try {
  100. this._bundleContext.instanceStop(this);
  101. } catch( e) {
  102. log.error("Bundle stop error: " + this.name + "\n",e);
  103. }
  104. this.clearIntervals();
  105. this.clearTimeouts();
  106. this.events.destroy();
  107. //this.manager.events.removeListener(this);
  108. this.info.state = 0;
  109. }
  110. /* Event wrappers */
  111. /*removeListener(ename) {
  112. this.manager.events.removeListener(this,ename);
  113. }*/
  114. emit(name,...args) {
  115. return this.events.broadcast( this.name + ":" +name,...args);
  116. }
  117. state(name,...args) {
  118. this.events.state( this.name + ":"+ name,...args);
  119. return this;
  120. }
  121. /*emit(ename,...args) {
  122. return this.manager.events.emit(this.name+":"+ename,...args);
  123. }*/
  124. /*toggleOn(ename,arg) {
  125. this.manager.events.toggleOn(this.name+":"+ename,arg);
  126. }
  127. toggleOff(ename) {
  128. this.manager.events.toggleOff(this.name+":"+ename);
  129. }*/
  130. channel(name) {
  131. return this.events.channel(name);
  132. }
  133. on(name,cb) {
  134. // Only create events if does not exists, maybe with a getter
  135. this.events.on(name,cb);
  136. return this;
  137. }
  138. /*on(...args) {
  139. var cb = args.pop();
  140. var evtName = args.join(":");
  141. this.manager.events.on(this,evtName ,cb);
  142. return this;
  143. }*/
  144. after(name,cb) { // Priorities
  145. this.events.on(name,cb,1000);
  146. return this;
  147. }
  148. // Channel
  149. prefix(name) {
  150. return this.manager.events.prefix(this,name);
  151. }
  152. // Wrappers
  153. /**
  154. * @param {array} args
  155. * @param {function} callback
  156. */
  157. with(args,callback) {
  158. return this.manager.with(args,callback);
  159. }
  160. /**
  161. * @param {string} match
  162. * @param {variable} ...args
  163. */
  164. call(name,...args) {
  165. return this.manager.call(name,args);
  166. }
  167. /*
  168. get(name) {
  169. var ctx = this.manager.get(name);
  170. if(ctx == null || ctx.info.state != 1) {
  171. // Early bail
  172. return null;
  173. }
  174. return ctx.instance;
  175. }*/
  176. // Auto clear helpers
  177. //
  178. setInterval(cb,n) {
  179. var ret = setInterval(cb,n);
  180. this._bundleContext.intervals.push(ret);
  181. return ret;
  182. }
  183. clearIntervals() {
  184. this._bundleContext.intervals.forEach((v) => {
  185. clearInterval(v);
  186. });
  187. }
  188. setTimeout(cb,n) {
  189. var ret = setTimeout(cb,n);
  190. this._bundleContext.timeouts.push(ret);
  191. return ret;
  192. }
  193. clearTimeouts() {
  194. this._bundleContext.timeouts.forEach((v) => {
  195. clearTimeout(v);
  196. });
  197. }
  198. }
  199. module.exports = BundleContext;