Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Serendesk last won the day on November 22 2015

Serendesk had the most liked content!

Contact Methods

  • Website URL

Profile Information

  • Gender
  • Location
    Sydney, Australia

Serendesk's Achievements


Newbie (1/14)



  1. Great work. Navigation and notifications are much better.
  2. I use version 3.6.1 and a customer had the same issue yesterday. Using the Standard order form, the error occurred on the submit of the last step (review + enter new client details). The service and client registration were created successfully but instead of showing the order complete page the 404 page was shown. I tried 5 times to make this error happen again but it wouldn't.
  3. Using one of the wizard order forms I had a few customers not go all the way through the sign-up steps resulting in a new client registration but no service (then an email to support). In all cases they were getting confused with the second last step where the button is labelled 'Create Account'. After this step a confirmation of the order is still required before the service is created. They navigated away before this last step. The standard order form is great. It offers a 1 step shorter process and feedback on where you are in the order process. Create new registration and create new service happens all in one step. It is a 3 step process if you link directly to the package. Since changing I've had no issues or complaints. However, a single page order would be ideal. If I had the time I would look into attempting it.
  4. Serendesk

    Nginx And Blesta

    Hi mate, If you haven't resolved this already send me a message and I can share the setup that I use for nginx.
  5. Oops, I forgot to mention; to have cron tasks running sooner than 5 minutes you also need to do what PauloV suggested here http://www.blesta.com/forums/index.php?/topic/4942-1-one-minute-cron-jobs/#entry39451
  6. See http://www.blesta.com/forums/index.php?/topic/5509-simple-service-to-avoid-cron/ for a solution.
  7. Here's a very simple script to run the Blesta cron tasks as a constantly running background service and to do away with cron altogether. This is useful if you need to run the tasks more frequently than 5 minutes, or, get locking and overlap with cron. I have been running this now for about 24 hours and no problems so far. This script can be improved on greatly, but it does have a simple feature to ensure that you don't have more than one service running at the same time. With a bit more work you could have a very useful script that behaves like a system service with cli args, better error checking and signal handling for graceful shutdowns etc. (I have added basic signal handling but I haven't tested it. It requires the posix extension which I do not have). You can either start/stop the service from the command line or within a script, or use a process monitor like supervisord or daemontools to handle it (they have better logging and protect you from starting more than one). Two files are used; service.php and config.json. Start the service: redirect output to a log file and place the process in the background (append & to the end of the command). Choose your own php path and log file path. #run as current user /usr/local/bin/php service.php > BlestaService.log & Check the service is running: you should see the service name (set in config) and the pid of the process. ps -aux | grep BlestaService Stop the service:If usePIDFile in the config is set to true, the service will stop if the pid file is deleted. This provides a very simple way of gracefully stopping the service (the while loop will stop if the file cannot be found). Otherwise, you can use kill to stop it immediately, but ideally try to avoid this. DB transactions may be in use, but there could be issues when exiting during imap connections etc. Alternatively and more cleanly, send it signals if you have the posix extension. #kill kill 47854 #send quit signal, better kill -s QUIT 47854 service.php <?php require('/usr/local/www/blesta/blesta/lib/init.php'); set_time_limit(0); class BlestaService { private $config; private $pidFile; private $running = true; public function run() { //these are required steps so dont catch errors thrown from this function $this->prep(); while($this->keepRunning()) { try { $start = time(); //do the cron work Dispatcher::dispatch('/cron/', true); //clean up. might not be absolutely required gc_collect_cycles(); sleep(max(0, $this->config->runInterval - (time() - $start))); } catch(Exception $e) { $this->logWrite($e); sleep(60); } } $this->cleanup(); } private function prep() { gc_enable(); $this->config = json_decode(file_get_contents('config.json')); if(function_exists('cli_set_process_title') && function_exists('cli_get_process_title')) { $currentTitle = cli_get_process_title(); cli_set_process_title($this->config->serviceName); } if($this->config->usePIDFile) { $this->pidFile = $this->config->pidFileDir. DIRECTORY_SEPARATOR .$this->config->serviceName.'.pid'; $this->exitIfPIDFileExists(); $this->setPIDFile(); } if(function_exists('pcntl_signal')) { //signal handling declare(ticks = 1); pcntl_signal(SIGQUIT, 'sigHandler'); pcntl_signal(SIGTERM, 'sigHandler'); pcntl_signal(SIGKILL, 'sigHandler'); pcntl_signal(SIGABRT, 'sigHandler'); pcntl_signal(SIGHUP, 'sigHandler'); pcntl_signal(SIGINT, 'sigHandler'); } } private function exitIfPIDFileExists() { if(file_exists($this->pidFile) === true) { $pid = file_get_contents($this->pidFile); $this->logWrite("Unable to start. Is there a service already running with pid $pid? Otherwise remove the pid file located at $this->pidFile before starting"); exit(1); } } private function setPIDFile() { file_put_contents($this->pidFile, getmypid()); chown($this->pidFile, $this->config->pidFileOwner); chmod($this->pidFile, 0600); } private function removePIDFile() { if($this->config->usePIDFile && file_exists($this->pidFile) === true) { unlink($this->pidFile); } } private function keepRunning() { if($this->config->usePIDFile) { //removing pid file will shutdown the service $this->running = file_exists($this->pidFile); } //alternatively use pcntl_signal to stop the service cleanly by setting $this->running = false in the SIGTERM, SIGKILL, SIGINT handler return $this->running; } private function logWrite($string) { //echo to console as output will be redirected to a log file echo "$string\n"; } public function sigHandler($signo) { switch($signo) { case SIGQUIT: case SIGTERM: case SIGHUP: case SIGABRT: $this->keepRunning = false; break; case SIGKILL: //probably cant catch this one but try anyway $this->cleanup(); break; case SIGINT: break; default: } } private function cleanup() { $this->logWrite('Exiting gracefully'); $this->removePIDFile(); exit; } /*public function __destruct() { //removed this as it will be called when exiting via exitIfPIDFileExists() when a service exists already, causing that services pid file to be deleted (and eventually stop running) $this->cleanup(); }*/ } //run $service = new BlestaService(); $service->run(); ?> config.json { "serviceName":"BlestaService", "runInterval":60, "usePIDFile":true, "pidFileDir":"/tmp", "pidFileOwner":"www" }
  8. Thanks Cody. I just took a look at /blesta/app/controllers/cron.php, so rather than execute the cron job in the loop, create an instance of the Cron class and do something like this in your loop: require('YOUR INSTALL DIR/blesta/app/controllers/cron.php'); //re-use //$cron = new Cron(); //your loop while(true) { try { //or new every time $cron = new Cron(); $cron->index(); } catch(Exception $e) { //log etc } //your sleep/interval stuff etc } Does this class contain everything needed/used by the normal cron job? Should other functions also be called, eg preAction()?
  9. Process monitors (supervisord, daemontools, launchd etc) are a great way to run a looping script like this in the background on a server, just like a daemon process. They allow start/stop/status/start at boot and auto restart on fail. You can avoid cron completely and they are simple to use. You can even use a shell script rather than php to handle the looping part (execute a php script each loop, e.g. /usr/local/bin/php myCronTasks.php). I use one to run multiple and simultaneous "background services", sort of like a single multi-threaded daemon, so tasks like imap, smtp, notifications are near real time. However, there's a few more tricks needed involving a DB or temp files on disk if you want to run multiple doing the same thing at the same time and avoid overlap. If you only need a single service, then php and a process monitor is all you need. There is never a worry about overlap or locking like cron and things just keep on running. If you handle/catch errors properly so the loop never breaks then the service will run forever (use set_time_limit(0) and gc_collect_cycles()). I strongly recommend this approach. Use supervisord if you don't mind installing python or daemontools if you don't want any libraries. I haven't tried this with Blesta yet. Cody, can you see any issues in simply executing the Blesta cron command inside a loop?
  • Create New...