/lib/AppInstance.php

https://github.com/max-shamaev/phpdaemon · PHP · 277 lines · 134 code · 36 blank · 107 comment · 22 complexity · 53b853ea244a2ed15003de3c2e5c4d7b MD5 · raw file

  1. <?php
  2. /**
  3. * Application instance
  4. *
  5. * @package Core
  6. *
  7. * @author Zorin Vasily <kak.serpom.po.yaitsam@gmail.com>
  8. */
  9. class AppInstance {
  10. public $status = 0; // runtime status
  11. public $passphrase; // optional passphrase
  12. public $reqCounter = 0; // counter of requests
  13. public $ready = FALSE; // ready to start?
  14. public $name; // name of instance
  15. public $config;
  16. /**
  17. * Application constructor
  18. * @return void
  19. */
  20. public function __construct($name = '') {
  21. $this->name = $name;
  22. $appName = get_class($this);
  23. $appNameLower = strtolower($appName);
  24. $fullname = Daemon::$appResolver->getAppFullName($appName, $this->name);
  25. //Daemon::$process->log($fullname . ' instantiated.');
  26. if (!isset(Daemon::$appInstances[$appNameLower])) {
  27. Daemon::$appInstances[$appNameLower] = array();
  28. }
  29. Daemon::$appInstances[$appNameLower][$this->name] = $this;
  30. if (!isset(Daemon::$config->{$fullname})) {
  31. Daemon::$config->{$fullname} = new Daemon_ConfigSection;
  32. } else {
  33. if (
  34. !isset(Daemon::$config->{$fullname}->enable)
  35. && !isset(Daemon::$config->{$fullname}->disable)
  36. ) {
  37. Daemon::$config->{$fullname}->enable = new Daemon_ConfigEntry;
  38. Daemon::$config->{$fullname}->enable->setValue(TRUE);
  39. }
  40. }
  41. $this->config = Daemon::$config->{$fullname};
  42. if ($this->isEnabled()) {
  43. Daemon::$process->log($appName . ($name ? "-{$name}" : '') . ' up.');
  44. }
  45. $defaults = $this->getConfigDefaults();
  46. if ($defaults) {
  47. $this->processDefaultConfig($defaults);
  48. }
  49. $this->init();
  50. if (Daemon::$process instanceof Daemon_WorkerThread) {
  51. if (!$this->ready) {
  52. $this->ready = true;
  53. $this->onReady();
  54. }
  55. }
  56. }
  57. public static function getInstance($name) {
  58. return Daemon::$appResolver->getInstanceByAppName(get_called_class(), $name);
  59. }
  60. public function isEnabled() {
  61. return isset($this->config->enable->value) && $this->config->enable->value;
  62. }
  63. /**
  64. * Function to get default config options from application
  65. * Override to set your own
  66. * @return array|false
  67. */
  68. protected function getConfigDefaults() {
  69. return false;
  70. }
  71. /**
  72. * Function handles incoming Remote Procedure Calls
  73. * You can override it
  74. * @param string Method name.
  75. * @param array Arguments.
  76. * @return mixed Result
  77. */
  78. public function RPCall($method, $args) {
  79. if ($this->enableRPC && is_callable(array($this, $method))) {
  80. return call_user_func_array(array($this, $method), $args);
  81. }
  82. }
  83. /**
  84. * Send broadcast RPC.
  85. * You can override it
  86. * @param string Method name.
  87. * @param array Arguments.
  88. * @param mixed Callback.
  89. * @return boolean Success.
  90. */
  91. public function broadcastCall($method, $args = array(), $cb = NULL) {
  92. return Daemon::$process->IPCManager->sendBroadcastCall(
  93. get_class($this) . ($this->name !== '' ? '-' . $this->name : ''),
  94. $method,
  95. $args,
  96. $cb
  97. );
  98. }
  99. /**
  100. * Process default config
  101. * @todo move it to Daemon_Config class
  102. * @param array {"setting": "value"}
  103. * @return void
  104. */
  105. public function processDefaultConfig($settings = array()) {
  106. foreach ($settings as $k => $v) {
  107. $k = strtolower(str_replace('-', '', $k));
  108. if (!isset($this->config->{$k})) {
  109. if (is_scalar($v)) {
  110. $this->config->{$k} = new Daemon_ConfigEntry($v);
  111. } else {
  112. $this->config->{$k} = $v;
  113. }
  114. } elseif ($v instanceof Daemon_ConfigSection) {
  115. // @todo
  116. } else {
  117. $current = $this->config->{$k};
  118. if (is_scalar($v)) {
  119. $this->config->{$k} = new Daemon_ConfigEntry($v);
  120. } else {
  121. $this->config->{$k} = $v;
  122. }
  123. $this->config->{$k}->setHumanValue($current->value);
  124. $this->config->{$k}->source = $current->source;
  125. $this->config->{$k}->revision = $current->revision;
  126. }
  127. }
  128. }
  129. /**
  130. * Called when the worker is ready to go
  131. * @todo -> protected?
  132. * @return void
  133. */
  134. public function onReady() { }
  135. /**
  136. * Called when creates instance of the application
  137. * @return void
  138. */
  139. public function init() {}
  140. /**
  141. * Called when worker is going to update configuration
  142. * @todo call it only when application section config is changed
  143. * @return void
  144. */
  145. public function onConfigUpdated() {}
  146. /**
  147. * Called when application instance is going to shutdown
  148. * @todo protected?
  149. * @return boolean Ready to shutdown?
  150. */
  151. public function onShutdown() {
  152. return TRUE;
  153. }
  154. /**
  155. * Create Request
  156. * @todo more description needed
  157. * @param object Request
  158. * @param object Upstream application instance
  159. * @return object Request
  160. */
  161. public function beginRequest($req, $upstream) {
  162. return FALSE;
  163. }
  164. /**
  165. * Handles the output from downstream requests
  166. * @todo more description
  167. * @param object Request
  168. * @param string The output
  169. * @return void
  170. */
  171. public function requestOut($r, $s) { }
  172. /**
  173. * Handles the output from downstream requests
  174. * @return void
  175. */
  176. public function endRequest($req, $appStatus, $protoStatus) { }
  177. /**
  178. * Log something
  179. * @param string - Message.
  180. * @return void
  181. */
  182. public function log($message) {
  183. Daemon::log(get_class($this) . ': ' . $message);
  184. }
  185. /**
  186. * Shutdown the application instance
  187. * @param boolean Graceful?
  188. * @return void
  189. */
  190. public function shutdown($graceful = false) {
  191. return $this->onShutdown();
  192. }
  193. /**
  194. * Handle the request
  195. * @param object Parent request
  196. * @param object Upstream application @todo is upstream really needed?
  197. * @return object Request
  198. */
  199. public function handleRequest($parent, $upstream) {
  200. $req = $this->beginRequest($parent, $upstream);
  201. if (!$req) {
  202. return $parent;
  203. }
  204. if (Daemon::$config->logqueue->value) {
  205. Daemon::$process->log('request added to ' . get_class($this) . '->queue.');
  206. }
  207. return $req;
  208. }
  209. /**
  210. * Pushes request to the queue
  211. * @todo log warning message and then sometime remove it
  212. * @param object Request
  213. * @return object Request
  214. * @deprecated
  215. */
  216. public function pushRequest($req) {
  217. return $req;
  218. }
  219. /**
  220. * Handle the worker status
  221. * @param int Status code @todo use constants in method
  222. * @return boolean Result
  223. */
  224. public function handleStatus($ret) {
  225. if ($ret === 2) {
  226. // script update
  227. $r = $this->onConfigUpdated();
  228. }
  229. elseif ($ret === 3) {
  230. // graceful worker shutdown for restart
  231. $r = $this->shutdown(TRUE);
  232. }
  233. elseif ($ret === 5) {
  234. // shutdown worker
  235. $r = $this->shutdown();
  236. } else {
  237. $r = TRUE;
  238. }
  239. return $r;
  240. }
  241. }