Commit 9ff3225c authored by Ludovic Ganée's avatar Ludovic Ganée

csfix

parent 6a416746
Pipeline #7738 passed with stage
in 4 minutes and 13 seconds
......@@ -57,13 +57,17 @@ class BeanstalkJobsTable extends Table
->allowEmptyString('jobid', null, 'create');
$validator
->add('tube', 'validFormat', [
'rule' => [
'custom',
"/^[a-z0-9\+\/;\.\$\(\)][a-z0-9\+\/;\.\$\(\)\-]*$/i"
],
'message' => "Format de text invalid"
])
->add(
'tube',
'validFormat',
[
'rule' => [
'custom',
"/^[a-z0-9\+\/;\.\$\(\)][a-z0-9\+\/;\.\$\(\)\-]*$/i"
],
'message' => "Format de text invalid"
]
)
->allowEmptyString('tube'); // default: "default"
$validator
......
......@@ -69,8 +69,8 @@ abstract class AbstractWorker implements WorkerInterface
* Constructeur de classe
*
* @param Beanstalk $Beanstalk
* @param boolean $keepAlive
* @param array $params
* @param boolean $keepAlive
* @param array $params
* @throws \ReflectionException
*/
public function __construct(
......@@ -95,12 +95,14 @@ abstract class AbstractWorker implements WorkerInterface
public function start()
{
$data = [];
$this->log(sprintf(
"Starting %s ; id=%d pid=%d",
get_called_class(),
(isset($this->params['id']) ? " ".$this->params['id'] : ''),
getmypid()
));
$this->log(
sprintf(
"Starting %s ; id=%d pid=%d",
get_called_class(),
(isset($this->params['id']) ? " ".$this->params['id'] : ''),
getmypid()
)
);
$this->resetConnection();
$stats = [
......@@ -214,7 +216,7 @@ abstract class AbstractWorker implements WorkerInterface
/**
* Arret du chrono de durée du job
* @param array $stats
* @param array $stats
* @param string $type
* @return int
*/
......@@ -311,12 +313,20 @@ abstract class AbstractWorker implements WorkerInterface
/**
* {@inheritdoc}
*
* @param \Throwable $ex Exception envoyé depui le bloc start()
* @param mixed $data Data obtenu par Beanstalkd
* @param \Throwable $ex Exception envoyé depui le bloc
* start()
* @param mixed $data Data obtenu par Beanstalkd
*/
public function fail(\Throwable $ex, $data)
{
$this->log(sprintf("Job work fail on %s:%d with message:\n%s", $ex->getFile(), $ex->getLine(), $ex->getMessage()));
$this->log(
sprintf(
"Job work fail on %s:%d with message:\n%s",
$ex->getFile(),
$ex->getLine(),
$ex->getMessage()
)
);
$this->log($ex->getTraceAsString());
Log::error((string)$ex);
}
......
......@@ -30,8 +30,8 @@ interface WorkerInterface
/**
* WorkerInterface constructor.
* @param Beanstalk $Beanstalk
* @param bool $keepAlive
* @param array $params
* @param bool $keepAlive
* @param array $params
*/
public function __construct(Beanstalk $Beanstalk, $keepAlive = true, array $params = []);
......@@ -75,8 +75,9 @@ interface WorkerInterface
/**
* Callback utilisé en cas d'Exception dans le bloc d'execution du worker
*
* @param \Throwable $ex Exception envoyé depui le bloc start()
* @param mixed $data Data obtenu par Beanstalkd
* @param \Throwable $ex Exception envoyé depui le bloc
* start()
* @param mixed $data Data obtenu par Beanstalkd
*/
public function fail(\Throwable $ex, $data);
......
......@@ -57,39 +57,65 @@ class WorkerShell extends Shell
{
$parser = new ConsoleOptionParser();
$parser->addArgument('worker', [
'help' => __("Nom du worker"),
]);
$parser->addOption('dir', [
'help' => __("Dossier de la classe du worker"),
]);
$parser->addOption('suffix', [
'default' => 'Worker',
'help' => __("Permet de spécifier le dossier worker"),
]);
$parser->addOption('tube', [
'help' => __("Nom du tube (par défaut: <nom du worker>)"),
]);
$parser->addOption('one-job', [
'boolean' => true,
'help' => __("N'effectue qu'un seul job - utile pour un worker sous docker"),
]);
$parser->addOption('unique', [
'boolean' => true,
'help' => __("Lance le worker seulement s'il est seul sur son tube"),
]);
$parser->addOption('table-workers', [
'default' => Configure::read('Beanstalk.table_workers', 'Beanstalk.BeanstalkWorkers'),
'help' => __("Permet de spécifier la table utilisée pour stocker les informations sur le worker lancé"),
]);
$parser->addOption('log-file', [
'help' => __("Fichier log du worker <default: logs/worker_<tube>.log>"),
]);
$parser->setDescription([
"--------------------------------------------------------------------",
__("Le cron 'worker' permet de lancer un worker type Beanstalk"),
"--------------------------------------------------------------------",
]);
$parser->addArgument(
'worker',
[
'help' => __("Nom du worker"),
]
);
$parser->addOption(
'dir',
[
'help' => __("Dossier de la classe du worker"),
]
);
$parser->addOption(
'suffix',
[
'default' => 'Worker',
'help' => __("Permet de spécifier le dossier worker"),
]
);
$parser->addOption(
'tube',
[
'help' => __("Nom du tube (par défaut: <nom du worker>)"),
]
);
$parser->addOption(
'one-job',
[
'boolean' => true,
'help' => __("N'effectue qu'un seul job - utile pour un worker sous docker"),
]
);
$parser->addOption(
'unique',
[
'boolean' => true,
'help' => __("Lance le worker seulement s'il est seul sur son tube"),
]
);
$parser->addOption(
'table-workers',
[
'default' => Configure::read('Beanstalk.table_workers', 'Beanstalk.BeanstalkWorkers'),
'help' => __("Permet de spécifier la table utilisée pour stocker les informations sur le worker lancé"),
]
);
$parser->addOption(
'log-file',
[
'help' => __("Fichier log du worker <default: logs/worker_<tube>.log>"),
]
);
$parser->setDescription(
[
"--------------------------------------------------------------------",
__("Le cron 'worker' permet de lancer un worker type Beanstalk"),
"--------------------------------------------------------------------",
]
);
return $parser;
}
......@@ -185,7 +211,7 @@ class WorkerShell extends Shell
/**
* Donne une instance de Beanstalk
* @param $tube
* @param string $tube
* @return Beanstalk
*/
protected function getBeanstalk($tube)
......@@ -214,8 +240,8 @@ class WorkerShell extends Shell
/**
* $filename est tokenized et ne namespace\classname et ajouté à $workers,
* si la classe utilise WorkerInterface et est instanciable
* @param $filename
* @param $workers
* @param string $filename
* @param array $workers
* @throws \ReflectionException
*/
protected function parseWorkerClassname($filename, &$workers)
......
......@@ -60,7 +60,7 @@ class Beanstalk
* Effectue la connexion au serveur
*
* @param string $tube
* @param array $params
* @param array $params
*/
public function __construct($tube = PheanstalkInterface::DEFAULT_TUBE, array $params = [])
{
......@@ -90,7 +90,7 @@ class Beanstalk
* Permet de vérifier de façon statique que l'on est connecté
* A n'utiliser que si on a pas besoin d'une instance de la classe
* @param string $tube
* @param array $params
* @param array $params
* @return bool
*/
public static function connected($tube = PheanstalkInterface::DEFAULT_TUBE, array $params = [])
......@@ -115,9 +115,9 @@ class Beanstalk
/**
* Setter du Pheanstalk
* @param string $host
* @param int $port
* @param null $connectTimeout
* @param bool $connectPersistent
* @param int $port
* @param null $connectTimeout
* @param bool $connectPersistent
* @return Beanstalk
*/
public function setPheanstalk(
......@@ -204,7 +204,7 @@ class Beanstalk
/**
* Donne un hash salé pour une chaine donnée
* @param $str
* @param string $str
* @return string
*/
protected function getEncodeKey($str)
......@@ -214,7 +214,7 @@ class Beanstalk
/**
* Ajoute une clé salé au data pour vérifier la provenance du message
* @param $data
* @param mixed $data
* @return string
*/
public function encodeData($data)
......@@ -229,9 +229,9 @@ class Beanstalk
/**
* Envoi un message sur beanstalkd (avec clé de contrôle)
* @param mixed $data
* @param int $priority
* @param int $delay
* @param int $ttr
* @param int $priority
* @param int $delay
* @param int $ttr
* @return string response id
*/
public function emit(
......@@ -248,16 +248,18 @@ class Beanstalk
$ttr
);
$Jobs = TableRegistry::getTableLocator()->get($this->params['table_jobs']);
$job = $Jobs->newEntity([
'jobid' => $response_id,
'tube' => $this->tube,
'priority' => $priority,
'last_status' => $delay ? 'delayed' : 'ready',
'user_id' => isset($data['user_id']) ? $data['user_id'] : null,
'delay' => $delay,
'ttr' => $ttr,
'data' => $data,
]);
$job = $Jobs->newEntity(
[
'jobid' => $response_id,
'tube' => $this->tube,
'priority' => $priority,
'last_status' => $delay ? 'delayed' : 'ready',
'user_id' => isset($data['user_id']) ? $data['user_id'] : null,
'delay' => $delay,
'ttr' => $ttr,
'data' => $data,
]
);
$Jobs->saveOrFail($job);
return $response_id;
}
......@@ -388,7 +390,7 @@ class Beanstalk
/**
* Sélectionne un job par son id, n'effectue pas de réservation
* @param $jobid
* @param int $jobid
* @return Beanstalk
*/
public function selectJob($jobid)
......@@ -428,11 +430,13 @@ class Beanstalk
$Pheanstalk->release($job);
}
if (!$found) {
throw new ServerException(sprintf(
'%s: Job %u is not reserved or does not exist.',
Response::RESPONSE_NOT_FOUND,
$this->job->getId()
));
throw new ServerException(
sprintf(
'%s: Job %u is not reserved or does not exist.',
Response::RESPONSE_NOT_FOUND,
$this->job->getId()
)
);
}
$this->setEntityJobStatus('reserved');
$this->lastTouch = microtime(true);
......
......@@ -173,8 +173,8 @@ class MockedPheanstalk implements PheanstalkInterface
/**
* Temporarily prevent jobs being reserved from the given tube.
*
* @param string $tube The tube to pause
* @param int $delay Seconds before jobs may be reserved from this queue.
* @param string $tube The tube to pause
* @param int $delay Seconds before jobs may be reserved from this queue.
*
* @return $this
*/
......@@ -249,10 +249,10 @@ class MockedPheanstalk implements PheanstalkInterface
/**
* Puts a job on the queue.
*
* @param string $data The job data
* @param int $priority From 0 (most urgent) to 0xFFFFFFFF (least urgent)
* @param int $delay Seconds to wait before job becomes ready
* @param int $ttr Time To Run: seconds a job can be reserved for
* @param string $data The job data
* @param int $priority From 0 (most urgent) to 0xFFFFFFFF (least urgent)
* @param int $delay Seconds to wait before job becomes ready
* @param int $ttr Time To Run: seconds a job can be reserved for
*
* @return int The new job ID
*/
......@@ -268,11 +268,11 @@ class MockedPheanstalk implements PheanstalkInterface
* the added benefit that it will not execute the USE command if the client
* is already using the specified tube.
*
* @param string $tube The tube to use
* @param string $data The job data
* @param int $priority From 0 (most urgent) to 0xFFFFFFFF (least urgent)
* @param int $delay Seconds to wait before job becomes ready
* @param int $ttr Time To Run: seconds a job can be reserved for
* @param string $tube The tube to use
* @param string $data The job data
* @param int $priority From 0 (most urgent) to 0xFFFFFFFF (least urgent)
* @param int $delay Seconds to wait before job becomes ready
* @param int $ttr Time To Run: seconds a job can be reserved for
*
* @return int The new job ID
*/
......@@ -287,9 +287,9 @@ class MockedPheanstalk implements PheanstalkInterface
* Marks the jobs state as "ready" to be run by any client.
* It is normally used when the job fails because of a transitory error.
*
* @param object $job Job
* @param int $priority From 0 (most urgent) to 0xFFFFFFFF (least urgent)
* @param int $delay Seconds to wait before job becomes ready
* @param object $job Job
* @param int $priority From 0 (most urgent) to 0xFFFFFFFF (least urgent)
* @param int $delay Seconds to wait before job becomes ready
*
* @return $this
*/
......@@ -333,7 +333,7 @@ class MockedPheanstalk implements PheanstalkInterface
* specified tube.
*
* @param string $tube
* @param int $timeout
* @param int $timeout
*
* @return object Job
*/
......
......@@ -80,47 +80,53 @@ class BeanstalkJobTest extends TestCase
$Pheanstalk->method('reserve')->willReturn($Job);
$Pheanstalk->method('peek')->willReturn($Job);
}
$Pheanstalk->method('statsJob')->willReturn([
"id" => "1",
"tube" => self::TUBE,
"state" => "reserved",
"pri" => "1024",
"age" => "2229",
"delay" => "0",
"ttr" => "60",
"time-left" => "51",
"file" => "540",
"reserves" => "2",
"timeouts" => "0",
"releases" => "1",
"buries" => "0",
"kicks" => "0",
]);
$Pheanstalk->method('statsTube')->willReturn((object)[
"name" => self::TUBE,
"current-jobs-urgent" => "0",
"current-jobs-ready" => "1",
"current-jobs-reserved" => "0",
"current-jobs-delayed" => "0",
"current-jobs-buried" => "0",
"total-jobs" => "2",
"current-using" => "1",
"current-watching" => "1",
"current-waiting" => "0",
"cmd-delete" => "0",
"cmd-pause-tube" => "0",
"pause" => "0",
"pause-time-left" => "0",
]);
$Pheanstalk->method('stats')->willReturn([
'current-jobs-urgent' => "0",
'current-jobs-ready' => "1",
'current-jobs-reserved' => "0",
'current-jobs-delayed' => "0",
'current-jobs-buried' => "0",
'current-workers' => "0",
'uptime' => "0",
]);
$Pheanstalk->method('statsJob')->willReturn(
[
"id" => "1",
"tube" => self::TUBE,
"state" => "reserved",
"pri" => "1024",
"age" => "2229",
"delay" => "0",
"ttr" => "60",
"time-left" => "51",
"file" => "540",
"reserves" => "2",
"timeouts" => "0",
"releases" => "1",
"buries" => "0",
"kicks" => "0",
]
);
$Pheanstalk->method('statsTube')->willReturn(
(object)[
"name" => self::TUBE,
"current-jobs-urgent" => "0",
"current-jobs-ready" => "1",
"current-jobs-reserved" => "0",
"current-jobs-delayed" => "0",
"current-jobs-buried" => "0",
"total-jobs" => "2",
"current-using" => "1",
"current-watching" => "1",
"current-waiting" => "0",
"cmd-delete" => "0",
"cmd-pause-tube" => "0",
"pause" => "0",
"pause-time-left" => "0",
]
);
$Pheanstalk->method('stats')->willReturn(
[
'current-jobs-urgent' => "0",
'current-jobs-ready' => "1",
'current-jobs-reserved' => "0",
'current-jobs-delayed' => "0",
'current-jobs-buried' => "0",
'current-workers' => "0",
'uptime' => "0",
]
);
$Pheanstalk->method('getConnection')->willReturn($Connection);
MockedBeanstalk::$StaticPheanstalk = $Pheanstalk;
......@@ -174,10 +180,12 @@ class BeanstalkJobTest extends TestCase
}
$this->assertEquals($expected, $actual);
$success = $this->Beanstalk->emit([
'message' => 'Hello world',
'user_id' => 123
]);
$success = $this->Beanstalk->emit(
[
'message' => 'Hello world',
'user_id' => 123
]
);
$this->assertTrue((bool)$success);
$actual = $this->Beanstalk->count();
$expected = 1;
......@@ -230,15 +238,17 @@ class BeanstalkJobTest extends TestCase
$Pheanstalk->method('peek')->willThrowException(new \Exception);
$this->BeanstalkJobs->deleteAll([]);
$this->BeanstalkJobs->sync = false;
$entity = $this->BeanstalkJobs->newEntity([
'jobid' => 1456,
'tube' => 'testunit',
'priority' => 1024,
'last_status' => 'ready',
'user_id' => 1,
'delay' => 0,
'ttr' => 60
]);
$entity = $this->BeanstalkJobs->newEntity(
[
'jobid' => 1456,
'tube' => 'testunit',
'priority' => 1024,
'last_status' => 'ready',
'user_id' => 1,
'delay' => 0,
'ttr' => 60
]
);
$this->BeanstalkJobs->save($entity);
$this->assertNotEmpty($entity->get('id'));
......
......@@ -63,14 +63,16 @@ class WorkerShellTest extends TestCase
/** @var BeanstalkWorkersTable $BeanstalkWorkers */
$BeanstalkWorkers = TableRegistry::getTableLocator()->get('Beanstalk.BeanstalkWorkers');
$BeanstalkWorkers->sync = true;
$entity = $BeanstalkWorkers->newEntity([
'name' => 'test',
'tube' => 'test',
'path' => TestWorker::class,
'pid' => 1,
'last_launch' => new Time,
'hostname' => 'testunit',
]);
$entity = $BeanstalkWorkers->newEntity(
[
'name' => 'test',
'tube' => 'test',
'path' => TestWorker::class,
'pid' => 1,
'last_launch' => new Time,
'hostname' => 'testunit',
]
);
$BeanstalkWorkers->save($entity);
TestWorker::$workData = ['foo', 'bar', 'baz'];
TestWorker::$keepworkingData = [true];// 1 true = 2 boucle
......
......@@ -110,14 +110,16 @@ class BeanstalkTest extends TestCase
{
$BeanstalkJobs = TableRegistry::getTableLocator()->get('BeanstalkJobs');
$BeanstalkJobs->deleteAll([]);
$entity = $BeanstalkJobs->newEntity([
'jobid' => 123,
'tube' => 'testunit-validtubename',
'data' => 'message',
'priority' => 1024,
'delay' => 0,
'ttr' => 60
]);
$entity = $BeanstalkJobs->newEntity(
[
'jobid' => 123,
'tube' => 'testunit-validtubename',
'data' => 'message',
'priority' => 1024,
'delay' => 0,
'ttr' => 60
]
);
$BeanstalkJobs->saveOrFail($entity);
$job = $this->createMock(Job::class);
$job->method('getId')->willReturn(123);
......@@ -132,15 +134,17 @@ class BeanstalkTest extends TestCase
{
$BeanstalkJobs = TableRegistry::getTableLocator()->get('BeanstalkJobs');
$BeanstalkJobs->deleteAll([]);
$entity = $BeanstalkJobs->newEntity([
'jobid' => 123,
'tube' => 'testunit-validtubename',
'data' => 'message',
'priority' => 1024,
'delay' => 0,
'ttr' => 60,
'last_status' => 'ready',
]);
$entity = $BeanstalkJobs->newEntity(
[
'jobid' => 123,
'tube' => 'testunit-validtubename',
'data' => 'message',
'priority' => 1024,
'delay' => 0,
'ttr' => 60,
'last_status' => 'ready',
]
);
$BeanstalkJobs->saveOrFail($entity);
$job = $this->createMock(Job::class);
$job->method('getId')->willReturn(123);
......@@ -155,15 +159,17 @@ class BeanstalkTest extends TestCase
{
$BeanstalkJobs = TableRegistry::getTableLocator()->get('BeanstalkJobs');
$BeanstalkJobs->deleteAll([]);
$entity = $BeanstalkJobs->newEntity([
'jobid' => 123,
'tube' => 'testunit-validtubename',
'data' => 'message',
'priority' => 1024,
'delay' => 0,
'ttr' => 60,
'last_status' => 'reserved',
]);
$entity = $BeanstalkJobs->newEntity(
[
'jobid' => 123,
'tube' => 'testunit-validtubename',
'data' => 'message',
'priority' => 1024,
'delay' => 0,
'ttr' => 60,
'last_status' => 'reserved',
]
);
$BeanstalkJobs->saveOrFail($entity);
$job = $this->createMock(Job::class);
$job->method('getId')->willReturn(123);
......
......@@ -31,34 +31,39 @@ if (extension_loaded('sqlite3')) {
try {
Cake\Datasource\ConnectionManager::get('test');
} catch (Exception $e) {
Cake\Datasource\ConnectionManager::setConfig('test', [
'className' => Cake\Database\Connection::class,
'driver' => Cake\Database\Driver\Sqlite::class,
'database' => DATABASE_TEST_SQLITE,
]);
Cake\Datasource\ConnectionManager::setConfig(
'test',
[
'className' => Cake\Database\Connection::class,
'driver' => Cake\Database\Driver\Sqlite::class,
'database' => DATABASE_TEST_SQLITE,
]
);
}
}
if (!Configure::read('App')) {
Configure::write([
'debug' => true,
'App' => [
'namespace' => 'Beanstalk',
'encoding' => env('APP_ENCODING', 'UTF-8'),
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'fr_FR'),
'base' => false,
'dir' => 'src',
'webroot' => 'webroot',
'wwwRoot' => WWW_ROOT,
'fullBaseUrl' => false,
'imageBaseUrl' => 'img/',
'cssBaseUrl' => 'css/',
'jsBaseUrl' => 'js/',
'paths' => [
'plugins' => [ROOT . DS . 'plugins' . DS],
'templates' => [APP . 'Template' . DS],
'locales' => [APP . 'Locale' . DS],
Configure::write(
[
'debug' => true,
'App' => [
'namespace' => 'Beanstalk',
'encoding' => env('APP_ENCODING', 'UTF-8'),
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'fr_FR'),
'base' => false,
'dir' => 'src',
'webroot' => 'webroot',
'wwwRoot' => WWW_ROOT,
'fullBaseUrl' => false,
'imageBaseUrl' => 'img/',
'cssBaseUrl' => 'css/',
'jsBaseUrl' => 'js/',
'paths' => [
'plugins' => [ROOT . DS . 'plugins' . DS],
'templates' => [APP . 'Template' . DS],
'locales' => [APP . 'Locale' . DS],
],
],
],
]);
]
);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment