PageRenderTime 38ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/pecl-manager.php

http://github.com/brianlmoon/GearmanManager
PHP | 222 lines | 125 code | 60 blank | 37 comment | 35 complexity | d956e9bdaf1450d69301c8884bbced56 MD5 | raw file
  1. #!/usr/bin/env php
  2. <?php
  3. /**
  4. * Implements the worker portions of the pecl/gearman library
  5. *
  6. * @author Brian Moon <brian@moonspot.net>
  7. * @copyright 1997-Present Brian Moon
  8. * @package GearmanManager
  9. *
  10. */
  11. declare(ticks = 1);
  12. require dirname(__FILE__)."/GearmanManager.php";
  13. /**
  14. * Implements the worker portions of the pecl/gearman library
  15. */
  16. class GearmanPeclManager extends GearmanManager {
  17. /**
  18. * Starts a worker for the PECL library
  19. *
  20. * @param array $worker_list List of worker functions to add
  21. * @return void
  22. *
  23. */
  24. protected function start_lib_worker($worker_list) {
  25. $thisWorker = new GearmanWorker();
  26. $thisWorker->addOptions(GEARMAN_WORKER_NON_BLOCKING);
  27. $thisWorker->setTimeout(5000);
  28. foreach($this->servers as $s){
  29. $this->log("Adding server $s", GearmanManager::LOG_LEVEL_WORKER_INFO);
  30. $thisWorker->addServers($s);
  31. }
  32. foreach($worker_list as $w){
  33. $this->log("Adding job $w", GearmanManager::LOG_LEVEL_WORKER_INFO);
  34. $thisWorker->addFunction($w, array($this, "do_job"), $this);
  35. }
  36. $start = time();
  37. while(!$this->stop_work){
  38. if(@$thisWorker->work() ||
  39. $thisWorker->returnCode() == GEARMAN_IO_WAIT ||
  40. $thisWorker->returnCode() == GEARMAN_NO_JOBS) {
  41. if ($thisWorker->returnCode() == GEARMAN_SUCCESS) continue;
  42. if (!@$thisWorker->wait()){
  43. if ($thisWorker->returnCode() == GEARMAN_NO_ACTIVE_FDS){
  44. sleep(5);
  45. }
  46. }
  47. }
  48. /**
  49. * Check the running time of the current child. If it has
  50. * been too long, stop working.
  51. */
  52. if($this->max_run_time > 0 && time() - $start > $this->max_run_time) {
  53. $this->log("Been running too long, exiting", GearmanManager::LOG_LEVEL_WORKER_INFO);
  54. $this->stop_work = true;
  55. }
  56. if(!empty($this->config["max_runs_per_worker"]) && $this->job_execution_count >= $this->config["max_runs_per_worker"]) {
  57. $this->log("Ran $this->job_execution_count jobs which is over the maximum({$this->config['max_runs_per_worker']}), exiting", GearmanManager::LOG_LEVEL_WORKER_INFO);
  58. $this->stop_work = true;
  59. }
  60. }
  61. $thisWorker->unregisterAll();
  62. }
  63. /**
  64. * Wrapper function handler for all registered functions
  65. * This allows us to do some nice logging when jobs are started/finished
  66. */
  67. public function do_job($job) {
  68. static $objects;
  69. if($objects===null) $objects = array();
  70. $w = $job->workload();
  71. $h = $job->handle();
  72. $job_name = $job->functionName();
  73. if($this->prefix){
  74. $func = $this->prefix.$job_name;
  75. } else {
  76. $func = $job_name;
  77. }
  78. if(empty($objects[$job_name]) && !function_exists($func) && !class_exists($func)){
  79. if(!isset($this->functions[$job_name])){
  80. $this->log("Function $func is not a registered job name");
  81. return;
  82. }
  83. require_once $this->functions[$job_name]["path"];
  84. if(class_exists($func) && method_exists($func, "run")){
  85. $this->log("Creating a $func object", GearmanManager::LOG_LEVEL_WORKER_INFO);
  86. $objects[$job_name] = new $func();
  87. } elseif(!function_exists($func)) {
  88. $this->log("Function $func not found");
  89. return;
  90. }
  91. }
  92. $this->log("($h) Starting Job: $job_name", GearmanManager::LOG_LEVEL_WORKER_INFO);
  93. $this->log("($h) Workload: $w", GearmanManager::LOG_LEVEL_DEBUG);
  94. $log = array();
  95. /**
  96. * Run the real function here
  97. */
  98. if(isset($objects[$job_name])){
  99. $this->log("($h) Calling object for $job_name.", GearmanManager::LOG_LEVEL_DEBUG);
  100. $result = $objects[$job_name]->run($job, $log);
  101. } elseif(function_exists($func)) {
  102. $this->log("($h) Calling function for $job_name.", GearmanManager::LOG_LEVEL_DEBUG);
  103. $result = $func($job, $log);
  104. } else {
  105. $this->log("($h) FAILED to find a function or class for $job_name.", GearmanManager::LOG_LEVEL_INFO);
  106. }
  107. if(!empty($log)){
  108. foreach($log as $l){
  109. if(!is_scalar($l)){
  110. $l = explode("\n", trim(print_r($l, true)));
  111. } elseif(strlen($l) > 256){
  112. $l = substr($l, 0, 256)."...(truncated)";
  113. }
  114. if(is_array($l)){
  115. foreach($l as $ln){
  116. $this->log("($h) $ln", GearmanManager::LOG_LEVEL_WORKER_INFO);
  117. }
  118. } else {
  119. $this->log("($h) $l", GearmanManager::LOG_LEVEL_WORKER_INFO);
  120. }
  121. }
  122. }
  123. $result_log = $result;
  124. if(!is_scalar($result_log)){
  125. $result_log = explode("\n", trim(print_r($result_log, true)));
  126. } elseif(strlen($result_log) > 256){
  127. $result_log = substr($result_log, 0, 256)."...(truncated)";
  128. }
  129. if(is_array($result_log)){
  130. foreach($result_log as $ln){
  131. $this->log("($h) $ln", GearmanManager::LOG_LEVEL_DEBUG);
  132. }
  133. } else {
  134. $this->log("($h) $result_log", GearmanManager::LOG_LEVEL_DEBUG);
  135. }
  136. /**
  137. * Workaround for PECL bug #17114
  138. * http://pecl.php.net/bugs/bug.php?id=17114
  139. */
  140. $type = gettype($result);
  141. settype($result, $type);
  142. $this->job_execution_count++;
  143. return $result;
  144. }
  145. /**
  146. * Validates the PECL compatible worker files/functions
  147. */
  148. protected function validate_lib_workers() {
  149. foreach($this->functions as $func => $props){
  150. require_once $props["path"];
  151. $real_func = $this->prefix.$func;
  152. if(!function_exists($real_func) &&
  153. (!class_exists($real_func) || !method_exists($real_func, "run"))){
  154. $this->log("Function $real_func not found in ".$props["path"]);
  155. posix_kill($this->pid, SIGUSR2);
  156. exit();
  157. }
  158. }
  159. }
  160. }
  161. $mgr = new GearmanPeclManager();
  162. ?>