Added InvoiceJob
This commit is contained in:
269
scripts/invoice/invoice-job-broker.php
Executable file
269
scripts/invoice/invoice-job-broker.php
Executable file
@@ -0,0 +1,269 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
die("This program can only be run on the command line.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
fclose(STDIN);
|
||||
fclose(STDOUT);
|
||||
fclose(STDERR);
|
||||
|
||||
$STDIN = fopen('/dev/null', 'r');
|
||||
$STDOUT = fopen('/dev/null', 'w');
|
||||
$STDERR = fopen('/dev/null', 'w');
|
||||
*/
|
||||
require("../../config/config.php");
|
||||
|
||||
define('mfUI',"cli");
|
||||
define('FRONKDB_SQLDEBUG',false);
|
||||
define("MFBASE_BYPASS_LOGIN", true);
|
||||
error_reporting(E_ALL & ~(E_NOTICE | E_STRICT | E_DEPRECATED));
|
||||
|
||||
if(defined('MFLOCALE_TIME')) {
|
||||
setlocale(LC_TIME, MFLOCALE_TIME);
|
||||
}
|
||||
if(defined('MFLOCALE_MONETARY')) {
|
||||
setlocale(LC_MONETARY, MFLOCALE_MONETARY);
|
||||
}
|
||||
if(defined('MFLOCALE_NUMERIC')) {
|
||||
setlocale(LC_NUMERIC, MFLOCALE_NUMERIC);
|
||||
}
|
||||
|
||||
require_once(LIBDIR."/mvcfronk/mfRouter/mfRouter.php");
|
||||
require_once(LIBDIR."/mvcfronk/mfBase/mfBaseModel.php");
|
||||
require_once(LIBDIR."/mvcfronk/mfBase/mfBaseController.php");
|
||||
|
||||
$me = new User(1);
|
||||
|
||||
define("INTERNAL_USER_ID", $me->id);
|
||||
define("INTERNAL_USER_USERNAME", $me->username);
|
||||
|
||||
$request = array();
|
||||
|
||||
// Put commandline arguments into $request
|
||||
if(count($argv)) {
|
||||
$args=$argv;
|
||||
array_shift($args); // shift scriptname off of args array
|
||||
foreach($args as $i => $arg) {
|
||||
if(preg_match('/^--(.+)/',$arg,$m)) {
|
||||
if(isset($args[$i+1]) && !preg_match('/^-/',$args[$i+1])) {
|
||||
$request[$m[1]] = $args[$i+1];
|
||||
} else {
|
||||
$request[$m[1]] = true;
|
||||
}
|
||||
} elseif(preg_match('/^-([a-zA-Z])(.+)/', $arg, $m)) {
|
||||
$request[$m[1]] = $m[2];
|
||||
} elseif(preg_match('/^-([^-])/', $arg, $m)) {
|
||||
if(isset($args[$i+1]) && !preg_match('/^-/',$args[$i+1])) {
|
||||
$request[$m[1]] = $args[$i + 1];
|
||||
} else {
|
||||
$request[$m[1]] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require_once(LIBDIR."/mvcfronk/mfRouter/mfRouter.php");
|
||||
$log = mfLoghandler::singleton();
|
||||
|
||||
cli_set_process_title("thetool-invoice-job-broker");
|
||||
pcntl_async_signals(true);
|
||||
pcntl_signal(SIGTERM, 'signalHandler');
|
||||
|
||||
$forkcount = 0;
|
||||
$childpids = [];
|
||||
|
||||
if(pidislocked()) {
|
||||
echo "Invoice Job Broker läuft bereits (pidfile vorhanden)\n";
|
||||
exit;
|
||||
}
|
||||
if(!lockpid()) {
|
||||
$log->error(__FILE__.": Error creating lock file!");
|
||||
die("Error creating lock file!\n");
|
||||
}
|
||||
|
||||
$all_pids = [];
|
||||
|
||||
$valid_tasks = [
|
||||
"make-invoice-pdf",
|
||||
"send-invoice-email"
|
||||
];
|
||||
|
||||
while(1) {
|
||||
$processes = [];
|
||||
|
||||
//sleep(5);
|
||||
//echo "looking for new jobs\n";
|
||||
$now = new DateTime("now");
|
||||
$jobs = InvoiceJobModel::search(["from_date<=" => $now->format("Y-m-d"), "to_date>=" => $now->format("Y-m-d"), "finished" => null], false, false, true);
|
||||
|
||||
/*if(!count($jobs)) {
|
||||
echo "no more jobs. Exiting.\n";
|
||||
break;
|
||||
}*/
|
||||
|
||||
foreach($jobs as $job) {
|
||||
$taskname = $job->task;
|
||||
|
||||
if(!array_key_exists($job->task, $childpids)) {
|
||||
$childpids[$taskname] = [];
|
||||
}
|
||||
|
||||
if($job->started && $job->status != "defer") {
|
||||
//echo "Job ".$job->id." is running already\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$proc = [
|
||||
"job_id" => $job->id,
|
||||
"task" => $taskname,
|
||||
"pid" => false,
|
||||
"processtitle" => "$taskname - running job ".$job->id
|
||||
];
|
||||
|
||||
$processes[] = $proc;
|
||||
}
|
||||
|
||||
if(!count($processes) && !count($all_pids)) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach($processes as $proc) {
|
||||
//echo "process task ".$proc["task"]." pid: ".$proc["pid"]."\n";
|
||||
|
||||
if($proc["pid"]) {
|
||||
// maybe look for new tasks here
|
||||
continue;
|
||||
}
|
||||
|
||||
$taskname = $proc["task"];
|
||||
|
||||
if($childpids[$taskname]) {
|
||||
//echo "cannot start new $taskname job, because another one is running already\n";
|
||||
continue;
|
||||
}
|
||||
//echo "Starting new child\n";
|
||||
$pid = pcntl_fork();
|
||||
|
||||
|
||||
if($pid === -1) {
|
||||
$log->debug("error forking");
|
||||
exit;
|
||||
} elseif($pid > 0) {
|
||||
// in parent
|
||||
$forkcount++;
|
||||
$childpids[$taskname] = $pid;
|
||||
$proc["pid"] = $pid;
|
||||
$all_pids[$pid] = $proc;
|
||||
//sleep(1);
|
||||
} else {
|
||||
// in child
|
||||
$mypid = getmypid();
|
||||
$job_id = $proc["job_id"];
|
||||
$job = new InvoiceJob($job_id, true);
|
||||
$job->status = "inprogress";
|
||||
$job->save();
|
||||
|
||||
try {
|
||||
//echo "in pid $mypid\n";
|
||||
//echo "looking for runner for job $taskname\n";
|
||||
cli_set_process_title($proc["processtitle"]);
|
||||
|
||||
$include_name = __DIR__ . "/job-runners/" . $taskname . ".php";
|
||||
if(!file_exists($include_name)) {
|
||||
echo "[$mypid] Runner $include_name not found\n";
|
||||
}
|
||||
|
||||
require($include_name);
|
||||
|
||||
//echo "[$mypid] Runner $include_name is finished\n";
|
||||
|
||||
} catch(\Exception $e) {
|
||||
// exit child process on error
|
||||
echo "$mypid caught exception: " . $e->getMessage();
|
||||
echo $e->getTraceAsString()."\n";
|
||||
exit;
|
||||
}
|
||||
exit; // make sure child exits when done
|
||||
}
|
||||
}
|
||||
|
||||
if(count($all_pids)) {
|
||||
$status = false;
|
||||
$return_pid = pcntl_wait($status, WNOHANG);
|
||||
if($return_pid) {
|
||||
echo "child $return_pid returned\n";
|
||||
$pid_proc = $all_pids[$return_pid];
|
||||
$pid_task = $pid_proc["task"];
|
||||
$childpids[$pid_task] = null;
|
||||
unset($all_pids[$return_pid]);
|
||||
}
|
||||
}
|
||||
/*echo "No more PIDs, exiting loop\n";
|
||||
break;*/
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
unlockpid();
|
||||
|
||||
function signalHandler($sig) {
|
||||
//global $continue;
|
||||
global $childpids;
|
||||
global $invoice_job_lock;
|
||||
|
||||
//$continue = false;
|
||||
//echo "in signal handler\n";
|
||||
|
||||
if(count($childpids)) {
|
||||
foreach($childpids as $taskname => $pids) {
|
||||
foreach($pids as $childpid) {
|
||||
posix_kill($childpid, SIGTERM);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
unlockpid();
|
||||
exit;
|
||||
}
|
||||
|
||||
function client_log($pid, $text, $severity = "notice") {
|
||||
global $log;
|
||||
global $is_daemon;
|
||||
|
||||
if($is_daemon) {
|
||||
echo "[".date('Y-m-d H:i:s')."] [$pid] $text\n";
|
||||
}
|
||||
$log->$severity($text);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function pidislocked() {
|
||||
$pid = getmypid();
|
||||
$pidfile = __DIR__."/.invoice-job-broker.lock";
|
||||
if(file_exists($pidfile)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function lockpid() {
|
||||
$pid = getmypid();
|
||||
$pidfile = __DIR__."/.invoice-job-broker.lock";
|
||||
file_put_contents($pidfile, $pid);
|
||||
if(file_exists($pidfile)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function unlockpid() {
|
||||
$pid = getmypid();
|
||||
$pidfile = __DIR__."/.invoice-job-broker.lock";
|
||||
if(file_exists($pidfile)) {
|
||||
unlink($pidfile);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
69
scripts/invoice/job-runners/make-invoice-pdf.php
Normal file
69
scripts/invoice/job-runners/make-invoice-pdf.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* @var $job InvoiceJob
|
||||
* @var $proc Array
|
||||
*/
|
||||
|
||||
/*
|
||||
echo "==========================\n";
|
||||
echo "in make-invoice-pdf-runner\n";
|
||||
echo "==========================\n";
|
||||
*/
|
||||
/*
|
||||
* make-invoice-pdf-runner.php
|
||||
* File is included in Invoice Job Broker
|
||||
*/
|
||||
|
||||
$started = new DateTime("now");
|
||||
$job->started = $started->format("Y-m-d H:i:s");
|
||||
$job->reconnectDB();
|
||||
$job->save();
|
||||
|
||||
$job_return = new stdClass();
|
||||
$job_return->created = 0;
|
||||
|
||||
$pdfs_created = 0;
|
||||
$timeout = false;
|
||||
|
||||
if($job->result) {
|
||||
$job_return = json_decode($job->result);
|
||||
if(json_last_error() === JSON_ERROR_NONE) {
|
||||
$pdfs_created = $job_return->created;
|
||||
} else {
|
||||
$job_return = new stdClass();
|
||||
$job_return->created = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$ic = new InvoiceController(false);
|
||||
$ic->reconnectDB();
|
||||
|
||||
do {
|
||||
$now = new DateTime("now");
|
||||
if($now->format("Y-m-d H:i:s") > $job->to_date." 23:59:59") {
|
||||
$timeout = true;
|
||||
break;
|
||||
}
|
||||
|
||||
$created = $ic->createPDFs(10);
|
||||
|
||||
$pdfs_created += $created;
|
||||
$job_return->created = $pdfs_created;
|
||||
$job->result = json_encode($job_return);
|
||||
//$job->return = json_encode(["created" => $created]);
|
||||
$job->reconnectDB();
|
||||
$job->save();
|
||||
} while($created);
|
||||
|
||||
|
||||
if($timeout) {
|
||||
$job->status = "timeout";
|
||||
} else {
|
||||
$job->status = "finished";
|
||||
}
|
||||
|
||||
$finished = new DateTime("now");
|
||||
$job->finished = $finished->format("Y-m-d H:i:s");
|
||||
$job->reconnectDB();
|
||||
$job->save();
|
||||
74
scripts/invoice/job-runners/send-invoice-email.php
Normal file
74
scripts/invoice/job-runners/send-invoice-email.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @var $job InvoiceJob
|
||||
*/
|
||||
|
||||
/*
|
||||
echo "==========================\n";
|
||||
echo "in send-invoice-email-runner\n";
|
||||
echo "==========================\n";
|
||||
*/
|
||||
|
||||
$started = new DateTime("now");
|
||||
if(!$job->started) {
|
||||
$job->started = $started->format("Y-m-d H:i:s");
|
||||
$job->reconnectDB();
|
||||
$job->save();
|
||||
}
|
||||
|
||||
$job_return = new stdClass();
|
||||
$job_return->sent = 0;
|
||||
|
||||
$pdfs_sent = 0;
|
||||
$defer = false;
|
||||
$timeout = false;
|
||||
|
||||
if($job->result) {
|
||||
$job_return = json_decode($job->result);
|
||||
if(json_last_error() === JSON_ERROR_NONE) {
|
||||
$pdfs_sent = $job_return->sent;
|
||||
} else {
|
||||
$job_return = new stdClass();
|
||||
$job_return->sent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$ic = new InvoiceController(false);
|
||||
$ic->reconnectDB();
|
||||
|
||||
// main loop
|
||||
do {
|
||||
$now = new DateTime("now");
|
||||
if($now->format("Y-m-d H:i:s") > $job->to_date." 23:59:59") {
|
||||
$timeout = true;
|
||||
break;
|
||||
}
|
||||
|
||||
$email_return = $ic->_sendEmailInvoices(300);
|
||||
if($email_return["defer"]) {
|
||||
$defer = true;
|
||||
}
|
||||
$sent = $email_return["sent"];
|
||||
$pdfs_sent += $sent;
|
||||
$job_return->sent = $pdfs_sent;
|
||||
$job->result = json_encode($job_return);
|
||||
//$job->return = json_encode(["sent" => $sent]);
|
||||
$job->reconnectDB();
|
||||
$job->save();
|
||||
} while($sent);
|
||||
|
||||
// prepare job update
|
||||
if($timeout) {
|
||||
$job->status = "timeout";
|
||||
} elseif($defer) {
|
||||
echo "email runner: deferring to next run\n";
|
||||
$job->status = "defer";
|
||||
} else {
|
||||
$finished = new DateTime("now");
|
||||
$job->finished = $finished->format("Y-m-d H:i:s");
|
||||
$job->status = "finished";
|
||||
}
|
||||
|
||||
$job->reconnectDB();
|
||||
$job->save();
|
||||
Reference in New Issue
Block a user