FOSSology  4.4.0
Open Source License Compliance by Open Source Software
Agent.php
Go to the documentation of this file.
1 <?php
2 /*
3  Author: Daniele Fognini
4  SPDX-FileCopyrightText: © 2014-2015 Siemens AG
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
20 namespace Fossology\Lib\Agent;
21 
24 use Symfony\Component\DependencyInjection\ContainerBuilder;
25 
26 require_once(dirname(dirname(__FILE__))."/common-cli.php");
27 
32 define("ALARM_SECS", 30);
33 
40 abstract class Agent
41 {
44  private $agentName;
47  private $agentVersion;
50  private $agentRev;
53  private $agentDesc;
56  private $agentArs;
59  private $agentId;
60 
63  protected $userId;
66  protected $groupId;
69  protected $jobId;
70 
75  protected $agentSpecifOptions = "";
80  protected $agentSpecifLongOptions = array();
81 
84  protected $args = array();
85 
88  protected $dbManager;
89 
92  protected $agentDao;
93 
96  protected $container;
97 
100  protected $schedulerMode;
101 
108  function __construct($agentName, $version, $revision)
109  {
110  $this->agentName = $agentName;
111  $this->agentVersion = $version;
112  $this->agentDesc = $agentName. " agent";
113  $this->agentRev = $version.".".$revision;
114  $this->agentArs = strtolower( $agentName ) . "_ars";
115  $this->schedulerMode = false;
116 
117  $GLOBALS['processed'] = 0;
118  $GLOBALS['alive'] = false;
119 
120  /* initialize the environment */
121  cli_Init();
122 
123  global $container;
124  $this->container = $container;
125  $this->dbManager = $container->get('db.manager');
126  $this->agentDao = $container->get('dao.agent');
127 
128  $this->agentId = $this->agentDao->getCurrentAgentId($this->agentName, $this->agentDesc, $this->agentRev);
129  }
130 
139  function scheduler_connect()
140  {
141  $schedulerHandledOpts = "c:";
142  $schedulerHandledLongOpts = array("userID:","groupID:","jobId:","scheduler_start",'config:');
143 
144  $longOpts = array_merge($schedulerHandledLongOpts, $this->agentSpecifLongOptions);
145  $shortOpts = $schedulerHandledOpts . $this->agentSpecifOptions;
146 
147  $args = getopt($shortOpts, $longOpts);
148 
149  $this->schedulerMode = (array_key_exists("scheduler_start", $args));
150 
151  $this->userId = $args['userID'];
152  $this->groupId = $args['groupID'];
153  $this->jobId = $args['jobId'];
154 
155  unset ($args['jobId']);
156  unset ($args['userID']);
157  unset ($args['groupID']);
158 
159  $this->initArsTable();
160 
161  if ($this->schedulerMode) {
162  $this->scheduler_greet();
163 
164  pcntl_signal(SIGALRM, function($signo)
165  {
166  Agent::heartbeat_handler($signo);
167  });
168  pcntl_alarm(ALARM_SECS);
169  }
170 
171  $this->args = $args;
172  }
173 
184  static function heartbeat_handler($signo)
185  {
186  global $processed;
187  global $alive;
188 
189  echo "HEART: $processed ".($alive ? '1' : '0')."\n";
190  $alive = false;
191  pcntl_alarm(ALARM_SECS);
192  }
193 
203  function heartbeat($newProcessed)
204  {
205  if ($this->schedulerMode) {
206  global $processed;
207  global $alive;
208 
209  $processed += $newProcessed;
210 
211  $alive = true;
212  pcntl_signal_dispatch();
213  }
214  }
215 
221  function bail($exitvalue)
222  {
223  debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
224  $this->scheduler_disconnect($exitvalue);
225  throw new \Exception('agent fail in '.__FILE__.':'.__LINE__,$exitvalue);
226  }
227 
236  function scheduler_disconnect($exitvalue)
237  {
238  if ($this->schedulerMode) {
239  Agent::heartbeat_handler(SIGALRM);
240  echo "BYE $exitvalue\n";
241  }
242  }
243 
249  function scheduler_greet()
250  {
251  echo "VERSION: ".$this->agentVersion."\n";
252  echo "OK\n";
253  }
254 
258  function initArsTable()
259  {
260  if (!$this->agentDao->arsTableExists($this->agentName)) {
261  $this->agentDao->createArsTable($this->agentName);
262  }
263  }
264 
273  abstract protected function processUploadId($uploadId);
274 
284  private function scheduler_current()
285  {
286  ($line = fgets(STDIN));
287  if ("CLOSE\n" === $line) {
288  return false;
289  }
290  if ("END\n" === $line) {
291  return false;
292  }
293 
294  return $line;
295  }
296 
312  {
313  while (false !== ($line = $this->scheduler_current())) {
314  $this->heartbeat(0);
315 
316  $uploadId = intval($line);
317  if ($uploadId <= 0) {
318  continue;
319  }
320 
321  $arsId = $this->agentDao->writeArsRecord($this->agentName, $this->agentId, $uploadId);
322  if ($arsId<0) {
323  print "cannot insert ars record";
324  $this->bail(2);
325  }
326 
327  try {
328  $success = $this->processUploadId($uploadId);
329  } catch(\Exception $e) {
330  print "Caught exception while processing uploadId=$uploadId: ".$e->getMessage();
331  print $e->getTraceAsString();
332  $success = false;
333  }
334 
335  $this->agentDao->writeArsRecord($this->agentName, $this->agentId, $uploadId, $arsId, $success);
336 
337  if (!$success) {
338  print "agent failed on uploadId=$uploadId";
339  $this->bail(1);
340  }
341  }
342  }
343 }
Structure of an Agent with all required parameters.
Definition: Agent.php:41
scheduler_current()
Read the commands from scheduler.
Definition: Agent.php:284
__construct($agentName, $version, $revision)
Definition: Agent.php:108
run_scheduler_event_loop()
Runs a loop to read commands from scheduler and process them.
Definition: Agent.php:311
static heartbeat_handler($signo)
Function to handle hear beats from the agent and send them to the scheduler from STDOUT.
Definition: Agent.php:184
bail($exitvalue)
Bail the agent, print the stack and disconnect from scheduler.
Definition: Agent.php:221
heartbeat($newProcessed)
Send hear beat to the scheduler.
Definition: Agent.php:203
processUploadId($uploadId)
Given an upload ID, process the items in it.
scheduler_greet()
Greet the scheduler at the beginning of connection.
Definition: Agent.php:249
scheduler_disconnect($exitvalue)
Closes connection from scheduler.
Definition: Agent.php:236
scheduler_connect()
Connect with scheduler and initialize options.
Definition: Agent.php:139
initArsTable()
Initialize ARS table.
Definition: Agent.php:258
Fossology exception.
Definition: Exception.php:15
cli_Init()
Initialize the fossology environment for CLI use. This routine loads the plugins so they can be use b...
Definition: common-cli.php:25
int jobId
The id of the job.
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16
const ALARM_SECS
Definition: Agent.php:32
int schedulerMode
Definition: nomos.c:33