HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Service status checker... Is there a more efficient way?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
moreefficientwaystatusservicetherechecker

Problem

I've been working on a website status checker.. However this array that I use has around 30 sites within it, I've noticed it's taking around 6-7 seconds to load it.

I was wondering if there's any kind of way of doing below, but more efficiently.

I have thought of doing the below in a cron, and fetching the stored results from a database.

=200 && $httpcode "URL",
);
?>

    Service Status
    

    
        service status
    
    
         $value) {
            echo '';
            if (Visit($value)) {
                echo "$key ($value)Available ($httpcode)";
            } else {
                echo "$key ($value)Unavailable ($httpcode)";
            }
            echo '';
        }
        ?>
    
    


Any recommendations on how parts of this could be done better would be greatly appreciated :)

Solution

PHP is not suitable for multi-threading. Though there are some extensions that offer ways of multithreading, they all are, basically, hacks IMO. The best way forward in your case would be: to use a tool that is async by nature, and update the url's as you go along.
Thankfully, such a thing exists, and it goes by the name JavaScript (AJAX calls), here's what I'd do:

foreach ($sites as $key => $value)
{
    echo '',$key, ' (', $value, ')',
    '';
}


This will present the client with a complete overview of urls (since that's what you say they are), each row showing a gif (optional, of course) of one of those circular loading things This one, for example.

On the page, have script that goes something like this:

window.addEventListener('load',function l()
{
    var pending = document.querySelectorAll('td.pending'),i=0,
    callNext = function(elem)
    {
        var urlMatch = elem.parentNode.cells[0].textContent.match(/\(([^)]+)/)[1],
        xhr = new XMLHttpRequest;
        xhr.open('POST','ajax.php', true);
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = callback;
        xhr.send('url=' + encodeURI(urlMatch));
    },
    callback = function()
    {
        if (this.readyState === 4 && this.status === 200)
        {
            var resp = JSON.parse(this.responseText);
            pending[i].setAttribute('class','error');//default error
            if (resp.success)
            {
                pending[i].setAttribute('class','success');
            }
            pending[i].replaceChild(
                document.createTextElement(resp.cellText),
                pending[i].firstChild
            );
            if (++i < pending.length)
            {
                callNext(pending[i]);
            }
        }
    };
    callNext(pending[i]);
    window.removeEventListener('load',l,false);
},false);


Then, the ajax.php script, could just be the Visit function (BTW: please follow the PHP-FIG-coding standards as much as possible, and lower-case that function name). Instead of $url just use:

$url = isset($_POST['url']) && filter_var($_POST['url'], FILTER_VALIDATE_URL) ? $_POST['url'] : false;
if (!$url)
{
    echo json_encode(array('cellText' => 'invalid URL'));
    exit;
}
//do curl request
echo json_encode(array('success' => true, 'cellText' => 'valid'));//or invalid, depending on curl results


This way, the client gets to see the page quite quickly, and sees it's being updated once every 6~7 seconds, depending on how long the curl request takes to complete.

In addition to that, look into caching extensions, such as APC, and set the cache options for the cUrl requests, too. This usually requires some trial and error to find the right balance...

Code Snippets

foreach ($sites as $key => $value)
{
    echo '<tr><td><strong>',$key, '</strong> (', $value, ')</td>',
    '<td class="pending"><img src="loading.gif"/></td></tr>';
}
window.addEventListener('load',function l()
{
    var pending = document.querySelectorAll('td.pending'),i=0,
    callNext = function(elem)
    {
        var urlMatch = elem.parentNode.cells[0].textContent.match(/\(([^)]+)/)[1],
        xhr = new XMLHttpRequest;
        xhr.open('POST','ajax.php', true);
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = callback;
        xhr.send('url=' + encodeURI(urlMatch));
    },
    callback = function()
    {
        if (this.readyState === 4 && this.status === 200)
        {
            var resp = JSON.parse(this.responseText);
            pending[i].setAttribute('class','error');//default error
            if (resp.success)
            {
                pending[i].setAttribute('class','success');
            }
            pending[i].replaceChild(
                document.createTextElement(resp.cellText),
                pending[i].firstChild
            );
            if (++i < pending.length)
            {
                callNext(pending[i]);
            }
        }
    };
    callNext(pending[i]);
    window.removeEventListener('load',l,false);
},false);
$url = isset($_POST['url']) && filter_var($_POST['url'], FILTER_VALIDATE_URL) ? $_POST['url'] : false;
if (!$url)
{
    echo json_encode(array('cellText' => 'invalid URL'));
    exit;
}
//do curl request
echo json_encode(array('success' => true, 'cellText' => 'valid'));//or invalid, depending on curl results

Context

StackExchange Code Review Q#31729, answer score: 3

Revisions (0)

No revisions yet.