SyncRelease Blog

SyncRelease Desktop version available now!

04/06/2014

Good news for Windows users! We just released a desktop version of SyncRelease for Windows platform. 

To install SyncRelease Desktop version is really easy by simply clicking "Next" buttons in an easy Windows installation wizard. That means the end of complex configurations and setups in installation process. No need to install any other software to run SyncRelease such as Apache or MySQL etc. Just install it as any Windows application.

SyncRelease Desktop Installation Wizard


Nginx URL rewrite for Zend Framework application as a subdirectory

11/19/2013

Nginx is an increasingly popular web server for web development these days. URL Rewrite in Nginx is simple and powerful but kind of tricky to beginner users of Nginx. While there are numerous examples on how to rewrite URL for Nginx to run Zend application on a virtual host level, there is hardly any working example on how to configure at the subdirectory level.

 

So today we would like to share how you can do URL rewrite for running Zend framework application on Nginx at a subdirectory level like http://mydomain.com/myproject.

 

So to get to the point, following is how you do it.

Nginx Configuration

        location ^~ /myproject {


                try_files $uri $uri/ /myproject/index.php$is_args$args;

                location ~ .php$ {
                #       fastcgi_split_path_info ^(.+.php)(/.+)$;
                #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                #
                #       # With php5-cgi alone:
                        fastcgi_pass 127.0.0.1:9000;
                #       # With php5-fpm:
                #       fastcgi_pass unix:/var/run/php5-fpm.sock;
                        fastcgi_index index.php;
                        fastcgi_param APPLICATION_ENV production; #set your Zend environment name here
                        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
                        include fastcgi_params;
                }  

        }

  


How to use multiple memcached servers with Zend Framework

11/14/2013

Memcached is a powerful tool for caching temporary data in memory for faster read/write. And it has been very popular with web application development for scaling purpose and performance tuning. Today, we would like to share our experience on how to use memcached for Zend Framework 1, especially on using multiple memcached servers.

 

Zend Framework comes nicely with its own module called Zend Cache, which allows you to cache a variety of temporary data for performance tuning, ranging from caching expensive database calls to cache page output for faster page rendering. You can configure Zend Cache to store cache data in a variety of storage medium such as local filesystem, APC (Alternative PHP Cache), sqlite, Xcache or memcached.

 

Before continue, let’s me introduce a little bit about the theory of Zend Cache and how it works. In a typical web application, you will have different points in your application that need caching for performance increase. For example, you may have to cache for auto suggest lookup or for expensive web service call to remote servers. So you will have two or more types of cache data to store and each type may have different requirements such as cache lifetime and medium for cache storage. Zend Cache was built with consideration for those scenarios. In Zend Cache, each type of cache data is represented as an instance or simply a PHP object. These cache objects are created by telling Zend Cache factory how to build with a set of information. And such information is divided into front end and backend. Frontend is basically for telling how long the cache should be alive, whether to automatically serialize the data or not and etc. Backend is about telling what storage medium will be used and other storage medium specific options. You can read more about it on Zend manual link provided at the end of this blog post.

 

So let’s get to the point and show you how to configure one or more memcached servers for your Zend application. Assume we are going to cache for two types of data 1) for auto-suggest cache 2) for expensive Web services call. Then, you will configure it in your application.ini file as follow:

 

With a single memcached server:

 

resources.cachemanager.auto_suggest.frontend.name = Core
resources.cachemanager.auto_suggest.frontend.customFrontendNaming = false
; every 24 hrs the cache will be refreshed
resources.cachemanager.auto_suggest.frontend.options.lifetime = 86400 resources.cachemanager.auto_suggest.frontend.options.automatic_serialization = true
resources.cachemanager.auto_suggest.backend.name = Memcached
resources.cachemanager.auto_suggest.backend.options.compression = true
resources.cachemanager.auto_suggest.frontendBackendAutoload = false

resources.cachemanager.auto_suggest.backend.name = Memcached
resources.cachemanager.web_service.backend.options.servers.host = 127.0.0.1
resources.cachemanager.auto_suggest.backend.options.compression = true
resources.cachemanager.auto_suggest.frontendBackendAutoload = false


resources.cachemanager.web_service.frontend.name = Core
resources.cachemanager.web_service.frontend.customFrontendNaming = false
; every 1 hr the cache will be refreshed
resources.cachemanager.web_service.frontend.options.lifetime = 3600
resources.cachemanager.web_service.frontend.options.automatic_serialization = true
resources.cachemanager.web_service.backend.name = Memcached
resources.cachemanager.web_service.backend.options.servers.host = 127.0.0.1
resources.cachemanager.web_service.backend.options.compression = true
resources.cachemanager.web_service.frontendBackendAutoload = false

resources.cachemanager.web_service.backend.name = Memcached
resources.cachemanager.web_service.backend.options.compression = true
resources.cachemanager.web_service.frontendBackendAutoload = false
  

 

How to use it in your code?

For example, in your controller you can use it as follow:

     $manager = $this->getFrontController()
                    ->getParam('bootstrap')
                    ->getPluginResource('cachemanager')
                    ->getCacheManager();
            //get the cache object for auto suggest data type
            $autosuggestCache = $manager->getCache('auto_suggest');
            //load from cache
            if(($data = $autosuggestCache->load('some key')) === false) {
                //cache miss
                //needs to load from actual data source
                $data = expensiveLookup('some key'); // just a dummy hypothetical function to get data from original source
                $autosuggestCache->save('some_key', $data);
            }
   

 

How to use multiple memcached servers?

Configuration for multiple memcached servers is also very similar to the previous configuration where you did it for a single memcached server. The only difference is in the backend option for “servers”. Following is an example of using three memcached servers for example above of auto suggest.

 
resources.cachemanager.auto_suggest.backend.options.servers.first.host = 127.0.0.1
resources.cachemanager.auto_suggest.backend.options.servers.second.host = 127.0.0.2
resources.cachemanager.auto_suggest.backend.options.servers.third.host = 127.0.0.3

 

one BIG caution

When you use multiple memcached servers, please do not think of this as redundancy storage for caching data. Often people think using multiple servers will allow them to store copies of cache data across multiple memcached servers. That is not the case. Instead, multiple memcached servers is for more of like load balancing strategy known as sharding i.e cache item A may be stored in first server and B will be in second and so on, depending on how you configure and how much memory space still available on each memcached server.

 

Reference:

Zend Manual on Caching -http://framework.zend.com/manual/1.12/en/zend.cache.introduction.html


Singleton Ajax: How to cancel previous ajax calls, instead using the last request

11/13/2013

Sometimes when you are making multiple ajax calls to the same URL to update content on a page, you want to make sure only the last ajax request makes the final call while previous calls are cancelled. That is to make sure content on your page is updated with correct data when multiple ajax calls can arrive back from backend URL at different times without any guaranteed order due to the asynchronous nature.

 

Some people come up with a solution to this problem using a counter and checking the counter value on arrival back from backend URL. I think that approach is unnecessary. Instead we can solve this problem elegantly utilizing closure in Javascript.

 

As we have similar problems to solve while working on our SyncRelease project, I ended up writing a little jQuery plugin, which I call as Singleton Ajax.

 

(function($){
    var singletonPost = null;
    var singletonGet = null;
    
    $.extend({
       'singletonPost': function(url, params, callback, dataType){
            if(singletonPost != null){
                singletonPost.abort();
            }

            singletonPost =  $.ajax({
                type: "POST",
                url: url,
                data: params,
                success: function(data){
                    singletonPost = null;
                    callback(data);
                },
                dataType : dataType || 'json'
            });
       },
       'singletonGet' : function(url, params, callback, type){
            if(singletonGet != null){
                singletonGet.abort();
            }

            singletonGet =  $.ajax({
                type: "GET",
                url: url,
                data: params,
                success: function(data){
                    singletonPost = null;
                    callback(data);
                },
                dataType : dataType || 'json'
            });
       }});

})(jQuery);

 

How to Use It?

When you want to make sure always the last ajax request to be used while canceling any prior requests, please use the singleton ajax calls similar to how you would normally do with $.get and $.post functions.

 

//using POST method
$.singletonPost(“/my-rest-url”, { “id”: 123, “query” : “hello world” }, function(data){

	//do something with data received.
           
}, ‘json’);

//using GET method
$.singletonGet(“/my-rest-url”, { “id”: 123, “query” : “hello world” }, function(data){

	//do something with data received.
           
}, ‘json’);


Mango Backup: SVN and MySQL database backup tool

11/05/2013

We have open-sourced our backup tool for SVN repositories and MySQL databases. It's called Mango Backup.

Mango Backup is a backup tool for storing backup copies of your SVN repositories and databases onto Rackspace Cloud Files, one of the best cloud storage available in the market. Currently, Mango Backup supports MySQL databases.

It is built using Zend framework and OpenCloud Files API from Rackspace. You will need an account from Rackspace Cloud Files to use it. This project was created as part of backing up our own projects at www.syncrelease.com

Currently it is hosted on Google Projects website, please checkout and download to start using it: 

https://code.google.com/p/mango-backup/


SyncRelease Beta Version Released

09/12/2013

Today, we are proud to announce SyncRelase private-beta version has been released and is now ready to download to those on our invitation list. It is a result of years long effort to design well and build systematically a perfectly tailored and easy-to-use release management and deployment web application for website owners and software development firms.

Some of the important features with the current release are:

  • Ability to cherry-pick your changes
  • Ability to rollback to any point in your history 
  • Deploy to multiple environment with real-time updates on progress
  • Multi-user system with fine-grained controls

Please see the more information on feature highlights on our website: http://www.syncrelease.com/tour