Preamble

As a matter of course, we at Impelos have built a significant set of modules that can plug in to various database systems and schemas to accomplish the needs of our clients.

In order to accomplish the varying client requirements we’ve needed to build a system that’s modular and flexible, while maintaining some consistency in our develop, test, and deploy processes.

Current count is 35 git repositories that need to be in sync before any updates can be rolled out.

What we’re about to show you is deploy only and doesn’t include automated pre-deploy testing. We wouldn’t want you believing this is all we do, now would we?

Our Environment

Currently, Repos are hosted on by our own Gitlab CE server, client servers are typically CentOS 7 virtual machines.

Why CommandBox?

CommandBox is a powerful and multi-talented command-line interface (CLI) for modern CFML. If you’re new to CommandBox, start here:https://www.ortussolutions.com/products/commandbox

Task Runners are automated jobs that can accomplish anything that can be done with CFML via command line rather than http request. For an introduction, start here: https://commandbox.ortusbooks.com/task-runners

First Step: Daemonization

We discovered that running a CommandBox task runner as a daemon on any OS is extremely lightweight, as opposed to starting CommandBox each time using a cron job.  In essence, we’re just going to throw the task into an infinite while loop like this:

component {

function run( string mode = 'once' ){

var interval = 20; // in minutes

while( true ){

// capture the loop's start time
var startStamp = now();

// do the automated processes

// capture the loop's end time
var stopStamp = now();

// calculate the remaining seconds before resuming the loop
var remainingSec = (interval * 60) - stopStamp.compare( startStamp, 's' );

var currSec = timeFormat( stopStamp, "ss" );

var sleepMS = ( (currSec >= startSec ? 60 : 0) + startSec - currSec ) * 1000 + ( remainingSec * 1000 );

if ( arguments.mode == 'once' ){
// break out of the loop as the default course of action
break;
}

sleep( sleepMS );

} // end while

} // end run function

} // end component

Next step: