bundle-context.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. this.events.channel(this.name).emit('start');
  92. }
  93. stop() {
  94. if(this.info.state == 0) return;
  95. //this.toggleOff("start");
  96. this.events.channel(this.name).emit("stop");
  97. try {
  98. this._bundleContext.instanceStop(this);
  99. } catch( e) {
  100. log.error("Bundle stop error: " + this.name + "\n",e);
  101. }
  102. this.clearIntervals();
  103. this.clearTimeouts();
  104. this.events.destroy();
  105. //this.manager.events.removeListener(this);
  106. this.info.state = 0;
  107. }
  108. /*channel(...names) {
  109. return this.events.channel(...names);
  110. }*/
  111. /*emit(name,...args) {
  112. return this.events.emit(this.name + ":" +name,...args);
  113. }
  114. propagate(name,nameto,...args) {
  115. return this.events.propagate(this.name + ":" + name, this.name + ":" + nameto,...args);
  116. }
  117. on(name,cb) {
  118. // Only create events if does not exists, maybe with a getter
  119. this.events.on(name,cb);
  120. return this;
  121. }
  122. after(name,cb) { // Priorities
  123. this.events.on(name,cb,1000);
  124. return this;
  125. }
  126. // Watcher
  127. watch(name,cb) {
  128. this.events.watch(name,cb);
  129. }
  130. set(name,value) {
  131. this.events.set(this.name + ":" + name, value);
  132. }
  133. unset(name) {
  134. this.events.unset(this.name + ":" + name);
  135. }
  136. */
  137. // manager Wrappers
  138. /**
  139. * @param {array} args
  140. * @param {function} callback
  141. */
  142. with(args,callback) {
  143. return this.manager.with(args,callback);
  144. }
  145. /**
  146. * @param {string} match
  147. * @param {variable} ...args
  148. */
  149. call(name,...args) {
  150. return this.manager.call(name,...args);
  151. }
  152. // Auto clear helpers
  153. //
  154. setInterval(cb,n) {
  155. var ret = setInterval(cb,n);
  156. this._bundleContext.intervals.push(ret);
  157. return ret;
  158. }
  159. clearIntervals() {
  160. this._bundleContext.intervals.forEach((v) => {
  161. clearInterval(v);
  162. });
  163. }
  164. setTimeout(cb,n) {
  165. var ret = setTimeout(cb,n);
  166. this._bundleContext.timeouts.push(ret);
  167. return ret;
  168. }
  169. clearTimeouts() {
  170. this._bundleContext.timeouts.forEach((v) => {
  171. clearTimeout(v);
  172. });
  173. }
  174. }
  175. module.exports = BundleContext;