Friday, January 18, 2013

Shell Script: Analyze time spent in resource load

The developer tools in the new browsers are very helpful. From, debugging html code, analyze load time to in-line development.

The below script will be helpful when you have to analyze load time for bunch of resources which would be difficult to get done one by one in the browser.

Feel free to make your own changes.
#!/bin/bash
resources_file=$1
no_of_calls=$2
if [[ ! -f $resources_file ]]; then
echo "Invalid file $resources_file"
exit 1
fi
if [[ ! $no_of_calls =~ ^[0-9]+$ ]]; then
no_of_calls=1
fi
result_file="${resources_file}_result.csv"
echo "url_effective,http_code,http_connect,time_total,time_namelookup,time_connect,time_appconnect,time_pretransfer,time_redirect,time_starttransfer,size_download,size_header,size_request,speed_download,speed_upload,content_type,num_connects" > "$result_file"
index=0
for uri in $(cat $resources_file)
do
for i in $(seq $no_of_calls)
do
echo -e "Processing $index\r\c"
curl -s -o /dev/null -w "%{url_effective},%{http_code},%{http_connect},%{time_total},%{time_namelookup},%{time_connect},%{time_appconnect},%{time_pretransfer},%{time_redirect},%{time_starttransfer},%{size_download},%{size_header},%{size_request},%{speed_download},%{speed_upload},%{content_type},%{num_connects}" $uri >> "$result_file" 2>&1
echo -e "\r" >> "$result_file" 2>&1
done
(( index = index + 1 ))
done
echo "Output written to $result_file"
view raw load_test.sh hosted with ❤ by GitHub

Saturday, January 12, 2013

Sunday, January 6, 2013

PHP: declarative property validation through document

Here is an attempt to define validation rules in document metadata and read it through reflection to validate the property against metadata. The metadata should be a valid json (verify using jsonlint.org).

Keeping it in metadata has the following benefits:

1. keeps it close to the property
2. easier to manage and read ( otherwise a complex structure if specified in another attribute )
3. is cool to do

Having type to php violates the dynamically typed nature of it. This is only in case you need it.
<?php
/**
* Hello
**/
class BaseClass
{
public function validate()
{
$ref = new ReflectionClass(get_class($this));
$props = $ref->getProperties();
foreach ($props as $key => $prop) {
$this->process_validate($prop);
}
}
private function process_validate($prop)
{
$metadata = $this->parse_metadata($prop);
$prop_name = $prop->name;
if ($metadata) {
foreach ($metadata as $key => $value) {
switch ($key) {
case 'type':
$this->validate_type($prop_name, $value, $this->$prop_name);
break;
case 'allowed_values':
$this->validate_allowed_values($prop_name, $value, $this->$prop_name);
break;
case 'length':
$this->validate_length($prop_name, $value, $this->$prop_name);
break;
case 'maxlength':
$this->validate_maxlength($prop_name, $value, $this->$prop_name);
break;
default:
}
}
}
}
private function parse_metadata($prop)
{
$comment = $prop->getDocComment();
preg_match('/"metadata"\s*:\s*[\[\{][\W\w]+[\]\}]/', $comment, $matches);
if (empty($matches))
return;
$metadata = $matches[0];
$metadata = preg_replace(array('/"metadata"\s*:\s*/', '/\*/','/[\n\t\r]/'), array('', '', ''), $metadata);
$metadata = trim($metadata);
$metadata = json_decode($metadata, true);
return $metadata;
}
private function validate_type($prop, $type, $value)
{
if (gettype($value) !== $type)
throw new ValidationException("Invalid type (" . gettype($value) . ") for $prop::" . get_class($this) . " Should be $type", 1);
}
private function validate_allowed_values($prop, $values, $value)
{
if (!in_array($value, $values))
throw new ValidationException("Invalid value ( $value ) for $prop::" . get_class($this) . " Should be in " . print_r($values, true), 1);
}
private function validate_length($prop, $length, $value)
{
if (strlen($value) != $length)
throw new ValidationException("Invalid length (" . strlen($value) . ") for $prop::" . get_class($this) . " Should be $length", 1);
}
private function validate_maxlength($prop, $length, $value)
{
if (strlen($value) > $length)
throw new ValidationException("Invalid length (" . strlen($value) . ") for $prop::" . get_class($this) . " Should be $length", 1);
}
}
class ValidationException extends Exception
{
}
class SubClass extends BaseClass
{
/**
* "metadata": {
* "type": "string",
* "allowed_values": [
* "active",
* "inactive"
* ],
* "maxlength": 12
* }
*/
protected $name;
/**
* "metadata": { "type": "integer", "allowed_values": [-1, 1] }
*/
protected $id;
public function __construct($name, $id)
{
$this->name = $name;
$this->id = $id;
}
}
$obj = new SubClass("active", 1);
$obj->validate();
?>

Saturday, January 5, 2013

PHP:json_encode private properties

json_encode( $obj ) works with public properties. In case you have private properties, you can implement jsonSerialize()::JsonSerializable. json_encode for objects of this class will create json with properties or value you specify in jsonSerialize. The output of jsonSerialize should either be array (normal or associative). The below code has a provision to filter attributes added in the $exclude_properties_to_json_arr var.Works with PHP 5.4 and above.
<?php
class class_test implements JsonSerializable {
private $exclude_properties_to_json_arr = array( "id" );
private $id = 'default';
protected $name;
static private $loc = 'bangalore';
public function __construct($id, $name) {
$this->id = $id;
$this->name = $name;
}
public function jsonSerialize() {
$arr = get_object_vars( $this );
foreach ( $this->exclude_properties_to_json_arr as $variable ) {
unset( $arr[ $variable ] );
}
unset( $arr[ 'exclude_properties_to_json_arr' ] );
return $arr;
}
}
$obj = new class_test( 1, "amod" );
echo json_encode($obj)
?>