New to Git? Here is a successful Git branching model

This is not just another blog post about some interesting tech stuff. This time it's the real thing!

If you've come from the Subversion world like I did, you may have heard about Git before but didn't quite understand what's the whole deal or why you should move to it. You probably do not understand the whole concept and definitly you do not know how to build your product lifecycle around it. Well, the search is over and the answer is here: http://nvie.com/posts/a-successful-git-branching-model/

 

 

Yes, it's a wonderful tutorial about a branching model for Git. 
Yes, it will help you base your product lifecycle and your team work around Git.
Yes, you can use the example code as a real protocol when branching/merging/etc
But more importantly, you'll understand the power of Git.

Thank you Vincent Driessen !

IO benchmark and recommendations for EBS

Just found this post:
http://orion.heroku.com/past/2009/7/29/io_performance_on_ebs/
Interesting stuff!
Basically, this guy is comaring different RAID setups and parameters and finds fundamental differences in EBS performance. Very handful for anyone using AWS + EBS with MySQL (or any other DB) .

One Hour Translation latest PRs and News

Just wanted to share some of our latest PRs and News...

Here is the interview on FoxNews last week:

Entrepreneur article: "Is Your Website Lost in Translation?

Ynet artice (Hebrew only...): "The return of foreign investors"

PHP Application Server

For a long time, I've been thinking about performance issues in PHP. One of the things that distinguishes PHP from other web-dev languages, is that PHP architecture is build around the "share nothing" concept.  Practically, it means that whenever a user opens a request to the server, a new PHP process is invoked which retains a distinct "user-space" environment. No matter how hard you try, memory of one PHP process is never shared with another process. This allows the developer to focus on developing the app for one user at a time and not worry about scalability.
 
Though simple and strait-forward, this concept is also very wasteful in terms of performance. Every user access requires a new PHP process, which then loads all necessary function and classes, connect to DBs and other resources and perform similar bootstrap and termination tasks. 
 
This has already been approached by some firms and individuals, creating acceleration layers on top of PHP that basically cache the compiled PHP files in RAM thus allows PHP scripts to run without the need to recompile the sources over and over again. Those tools are known to boost performance dramatically in a starting factor of 3. See here and here.
 
This is awesome!
 
But still something is missing...Even when accelerating PHP apps, including function and classes and other bootstrapping processes still cost execution time. 
In an attempt to deal with this situation, I've created a tiny project called PHP Application Server (PHAS). This aims to simulate an application server, a concept that is heavily used in other platforms such as J2EE, .NET and others. App servers are mainly into computation and performance. Their whole purpose is to execute the app itself as fast as possible and return a result to the requester.
 
The whole idea with PHAS is to launch a PHP process, include all needed function and classes, execute all required bootstrapping and wait for requests. When a request finally arrives, it executes only that specific task, return the result and waits for a new request. 
 
More specifically, this is how it works:

  1. First, the "Server" is launched, which then launched "Workers" that listen on a queue (Gearman).
  2. A worker that boots automatically execute the "bootstrapping" section in the user's app. This section should include classes and functions loading, DB connections and other "one-time" tasks.
  3. A new request arrives on the "entrance" or "gateway" script which pushes the request into the queue.
  4. One worker pulls the request from the queue, creates a "Virtual Environment" in preparation to running the user's app and launches the app. 
  5. The result of the user's app is transferred back to the "entrance" script which echos it to the HTTP response. 

 
Surprisingly, this actually works... More astonishing fact is that it boosts performance by a starting factor of 4!
I hope to have some real benchmarking soon... I would appreciate if someone could spare an example scripts, preferably "heavy" scripts with lots of functions\classes, to benchmark on.
I invite you to read more about it here: https://github.com/oyagev/PHP-App-Server
 

Tags:

Application configuration and PHP - the basics

Every medium (or larger) application needs a bit of configuration variables, the only questions are the scale and the desire of the developer to spend more than a minute building it.

So lets make it quick.

I'm going to show 3 basic concepts of wide-system configuration storage with PHP.

Method 1: Plain PHP Array

This maybe the most simple and efficient method of all. Just keep your configurations inside a PHP array and use it globally across your app. Simple to use, fast to develop.

Consider this configuration file:

--config.php-- 
<?php 
$config = array(); 
$config['dbhost'] = 'server1';
$config['dbuser'] = 'bob';
$config['dbpass'] = '1234';
?>

Now, all needed is to include this file inside a page scope and use $config as a global variable inside classes and functions across the application. Like this:

<?php
require_once 'config.php';
if (!$config) die('...');
function connectToDatabase(){
    global $config;
    $conn = mysql_connect( $config['dbhost'] , $config['dbuser'] ,
                                    $config['dbpass'] );
    ...
}
?>

So this method works alright, but it uses global variable which is highly difficult to maintain while our application scales up. Furthermore, I personally dislike the idea of code-configuration hybrid since messing up with configuration should not be involved with code understanding. This type of configuration must be maintained by developers, and developers only and may be used only by PHP speaking apps.

Method 2: XML

So lets move on and separate our configuration from code. The first choice for holding parse-able and dummy-readable structured info is no other than XML. So I guess we all know XML by now. if you don't, click here (but shame on you, really).

Lets try to represent the same configuration with XML document:

---config.xml---
<config>
    <database>
        <host>server1</host>
        <user>bob</user>
        <pass>1234</pass>
    </database>
</config>

And we continue by reading and using the configuration file inside PHP, like this:

<?php
$config = @simplexml_load_file('config.xml');
if (!$config) die('...');
function connectToDatabase(){
    global $config;
    $conn = mysql_connect(
        $config->database->host,
        $config->database->user ,
        $config->database->pass
    );
    ...
}
?>

The implementation is quite similar, expect the data itself that is now represented as a structured XML in a separated document. Using XML as a configuration document may be a good practice, specially when the data is hierarchical. XML allows us to define our configuration variables organized however we want. In practice, we can represent the configuration of a huge application in one file.

However, XML holds some overhead as the amount of text needed to represent tens or more of variables is enormous and a not so human friendly.

Method 3: INI file

Hence, we come to our last method for this post - the INI file. INI is just another way to represent variables as text. It is, however, simple, short and convenient. Lets start with a similar example:

---config.ini---
[database]
db.host = server1
db.user = bob
db.pass = 1234

The [database] title is called a section, and it may or maybe not used while parsing this file. Each line is formed with "KEY = VALUE" pattern. In the above example, db.host is a key and server1 is its value. The dot in the middle has no meaning, it's just a convention.

So lets use this file:

$config = @parse_ini_file('config.ini');
if (!$config) die('...');
function connectToDatabase(){
    global $config;
    $conn = mysql_connect( 
        $config['db.host'] ,
        $config['db.user'] ,
        $config['db.pass']
    );
    ...
}
?>

As you can see, it's pretty similar to the previous examples, we just used INI file instead and we still use the global $config variable all over the place.

Which method should you use? Its really a question of convenient. I didn't test any of those for performance, but I bet that using method 1 is the fastest. If you happen to check it, don't forget to tell me... I personally prefer keeping my configuration variables with INI file, I find it much more simple to view and maintain.

Getting rid of the global $config variable will be on my next post, so hang on.

 

 

Tags:

Automatic javascript generation on constantly changing websites

This time I will discuss something I wrote for myself.

The problem:

I'm (and maybe you are) constantly developing my application, adding features and closing bugs, both to PHP and Javascript pages. When it comes to PHP, there is no issue, we simply update the last version to the server and forget about it.
With Javascript, however, this is a bit more complicated.

To fully understand the situation, place yourself into the CTO's shoes. We want bugs closed, we want new tricks and we want it to work and fast. When it comes to performance, the first (or second) rule in the book is to minimize and minify javascript files that the website works with. Why?

  1. Each javascript file we load with the <script> tag is actually causing the client's browser to create a separate request to fetch it. Multiple requests are huge overhead, that's why we want to load as little as possible JS files.
  2. Each javascript file contains unnecessary characters like newline, tabs, comment etc. Why not remove them? This process is called minification and it can shrink the JS file by 20-30% while keeping it fully functional. Great!

So here comes the real headache...
We develop and code and debug and test and finally, it's deployment time. But wait! Shouldn't we combine all out JS source files into one file? And why not minify it on the way? Doing this over and over for each small change, it a pain.
Furthermore, what about different sections on out app that require different JS scripts? We surely don't want to serve the client with scripts he doesn't need!

So here is my solution:

I created the JSLoader class, which takes care of generating a combined javascript files according to the JS sources needed for a specific section, minify it and serve it to the client. It will cache the combined JS files for later, so the same combinations will not be re-generated. Nevertheless, if you change one byte in any JS file, it will re-generate the appropriate files.

How do you use it? It's quite simple. You just have to be familiar with PHP5.

Installation:

  1. Create a web-available folder for the generated Javascript files.
  2. Give the above folder write permissions for PHP.
  3. Copy the JSLoader package to your project or clone it from:
    git clone git://github.com/oyagev/PHP-JSLoader.git

How-To:

1. First include or require the class file:
require_once '../lib/JSLoader.php';

2. Everywhere we want to use this class, we have to retrieve its instance:
$jsloader = JSLoader::getInstance();

3. Next, we do one-time configuration:

$jsloader->setJavascriptFolder('/home/user/public/html/my_website/js'); 
$jsloader->setJavascriptFolderURL('<a href="https://www.my-website.com/js'">https://www.my-website.com/js'</a>);

The first line sets the absolute path to where the combined JS files will be placed. The second line sets a web available URL to the same directory.

4. Now here is the real thing! Everywhere you want to “include” a javascript file, you do:
$jsloader->add('/absolute/path/to/file.js');

The above line should go each time you need to include a js file and you should pass the absolute path to that file. Also remember to retrieve the class’s instance when needed. See section 2.

5. Finally, you should place a <script> tag to include the generated combined JS file. Fortunately, JSLoader does it for you. Just place this code (once) where needed:
$jsloader->putScriptTag();

6. Check your page source to see if the file was included and that it’s available.

Subscribe to Oren Yagev RSS