HHVM notes

  • Impressive throughput improvements (>100%) with the app that I am working on.
  • phpinfo() doesn’t output what you would expect.
  • xhprof output_dir doesn’t get read from ini files, need to set that up in the constructor of XHProfRuns_Default.
  • Set hhvm.server.thread_count to a high value (>=MaxRequestWorkers), otherwise a few slow MySQL queries could bring the server to halt, minimal doc here: HHVM server architecture (worker thread => hhvm.server.thread_count). Suggest to keep it higher while JITing is happening.
  • If using Newrelic, tough luck!
    Unofficial Newrelic HHVM extension uses XHProf internally, so cannot get any data out of your own XHProf usage.
    The extension above relies on agent SDK that has no support for MySQL slow traces.
    Very low MySQL time in transactions.
    Strange traces in transactions.
  • CGI differences (apache_getenv not available use $_SERVER, SCRIPT_NAME will not be the same as REQUEST_URI).
  • Use realpath in imageftbox, relative paths for fonts don’t work.
  • Use Apache 2.4 as it has FastCGI support.
  • hhvm.log.header = true to have datetime in hhvm log.
  • HHVM log will also contain slow sql.
  • .hhbc was getting very huge, turned out it was due to Smarty file caching being enabled (the cached files were themselves php files that HHVM was compiling).
  • .hhbc file is sqlite(3) file that one can query (that is how I worked out the above).
  • High timeout values in memcached was leading to very high System CPU usage.
  • @ wasn’t suppressing (this could be Newrelic related)
  • Friendly folks in the hhvm IRC channel (get link from HHVM homepage), need to be online during daytime in the US.

Backgrounded PHP jobs in ‘STOPPED’ state

This could be specific to the PHP package from Ubuntu. Please consider the following a disclaimer.

$ php -v
PHP 5.3.5-1ubuntu7.2 with Suhosin-Patch (cli) (built: May  2 2011 23:00:17) 
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
    with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans
 
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=11.04
DISTRIB_CODENAME=natty
DISTRIB_DESCRIPTION="Ubuntu 11.04"

I have a file with the following contents:

$ cat stdin.php
<?php
echo microtime(), "n";

and I was doing something like this (backgrounds the script. I was using a slightly modified version to make concurrent SOAP requests)

$ for i in `seq 1 2`; do echo $i; sleep 2s; php /tmp/stdin.php &gt;&gt; /tmp/k7.out & done
$ jobs
[1]-  Stopped                 php /tmp/stdin.php &gt;&gt; /tmp/k7.out
[2]+  Stopped                 php /tmp/stdin.php &gt;&gt; /tmp/k7.out

There are a few threads on the Internet relating to the issue and there are a few solutions.
First let us kill the ‘STOPPED’ jobs

$ kill %1
$ kill %2
[1]   Terminated              php /tmp/stdin.php &gt;&gt; /tmp/k7.out
$ jobs
[2]+  Terminated              php /tmp/stdin.php &gt;&gt; /tmp/k7.out

One of the solutions that worked for me was by supplying something to STDIN (perhaps STDIN was blocking, but then again, stream_set_blocking (STDIN, 0) wasn’t of much help).

$ for i in `seq 1 2`; do echo $i; sleep 2s; php /tmp/stdin.php &gt;&gt; /tmp/k7.out &lt; /dev/null & done

and you could simulate arguments

$ for i in `seq 1 2`; do echo $i; sleep 2s; echo arg1 arg2 | php /tmp/stdin.php &gt;&gt; /tmp/k7.out & done
$ tail -f k7.out
0.82262900 1316606606
array(2) {
  [0]=&gt;
  string(4) "arg1"
  [1]=&gt;
  string(4) "arg2"
}
0.83546500 1316606608
array(2) {
  [0]=&gt;
  string(4) "arg1"
  [1]=&gt;
  string(4) "arg2"
}

PHP as a replacement for sed/awk

I had gotten sick of not being able to do what I wanted to do with sed/awk – partly because I am not too familiar with those – and, was investigating replacements for those. Many people seem to be using perl and since I wasn’t too familiar with Perl as well, I started thinking about using PHP – which I do know. And, that served my needs brilliantly.

This is a simplistic version of my problem & a solution:
I can do the following to get the values for specific params (cid and oid in this case) for requests made, from my access logs:

k7@local:echo "http://example.com?cid=123&oid=435" | php -R 'preg_match("#.*cid=([^&]+)&oid=([^&]+)#",$argn, $matches);if(!empty($matches)) {echo $matches[1], " ", $matches[2], "n";}'
123 435

PHP, MongoDB, findAndModify

findAndModify is not supported by the current version of the PHP MongoDB driver, so I had to use the following code

$feed = $db->command(array('findAndModify' => 'feedList', 'query' => array('$where' => new MongoCode('
                                 function(){ 
                                      return ((this.inProgress == false)  
                                          || (currentTime >= (this.lastUpdated + this.updateFrequency))));
                                     }', array('currentTime' => $start))), 'update' => array('$set' => array('inProgress' => true))));

Where:

  • $db = Database handle
  • ‘feedList’ = Name of the Collection(Table)
  • inProgress, currentTime,updateFrequency and lastUpdated are some keys
  • $start = a MongoDate Obj

Essentially I am locking a document(set ‘inProgress’ to true) by finding and updating the first document that that is not locked by another process (‘inProgress’ set to false and a few other conditions)

Notice the use of ‘this’ in the MongoCode Obj. I think it refers to the current Document that is being processed.

Also be aware that findAndModify only finds and modifies the first document found.