Thursday, April 4, 2013

Install and Configure Memcache/Memcached on Windows and CodeIgniter

I recently spent some time installing and configuring Memcache/Memcached on windows and codeigniter. There are some issues in the configuration i.e. CI supports Memcached and Windows support Memcache. So thought of sharing the steps.

First of all let's install Memcached. You can download Memcached from http://code.jellycan.com/files/memcached-1.2.6-win32-bin.zip

Unzip the file in some directory (let's say C:\Memcached). Open command prompt as Administrator. Point to the C:\Memcached directory. Next step is to install Memcached, you can do that by using following command:

c:\Memcached\memcached.exe -d install

Next step is to run memcached server. Use following command to do that

c:\Memcached\memcached.exe -d start

This will run the memcached server on port 11211. Now, let's configure php to run memcached. Open php.ini file and find ;extension=php_memcache.dll. If you find this line then simply remove semicolon from the start of line. If you don't find this line then add it at the end of extensions section. After extensions section, add a new line and paste following:

[Memcache]
memcache.allow_failover = 1
memcache.max_failover_attempts=20  
memcache.chunk_size =8192  
memcache.default_port = 11211

Next step is to download php_memcache.dll file. You can download the file from http://downloads.php.net/pierre/ . Unzip the php_memcache.dll file and place it in php/ext/ folder.

Now, let's configure CI to run memcached. Create memcached.php file in application/config folder and place following code in it:

<?php

  if (!defined('BASEPATH')) exit('No direct script access allowed');

    $config['memcached'] = array(
        'hostname' => '127.0.0.1',
        'port'        => 11211,
        'weight'    => 1
    );

?>

Next, open \system\libraries\Cache\drivers\Cache_memcached.php file and in the function is_supported(), replace following line
if ( !extension_loaded('memcached'))
with
if ( !extension_loaded('memcached') && !extension_loaded('memcache'))
.Then in _setup_memcached() function, replace following line:
$this->memcached = new Memcached();
with:
if(class_exists("Memcached"))
  $this->_memcached = new Memcached();
else
  $this->_memcached = new Memcache();

Now, restart apache and create a test function in CI controller and paste following code in it to give it a try:

$this->load->driver('cache',array('adapter'=>'mecached'));
$this->cache->memcached->save('foo', 'bar', 10);
echo $this->cache->memcached->get('foo');

You can find the details of Cache plugin in CI at http://ellislab.com/codeigniter/user-guide/librarie/caching.html

Tuesday, July 31, 2012

Solve "ASP.NET 4.0 has not been registered on the Web server" issue

If you are working on IIS web server and you get an error saying that ASP.NET 4.0 has not been registered on the Web Server (see following screenshot)


A simple way to solve above issue is to run aspnet_regiis.exe. Simply open command shell in administrator mode and execute following command

%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i

Tuesday, July 17, 2012

Using Single Sign-on (windows live) in Windows 8 Metro App

I was playing around with Windows 8 Metro api (will try to post a blog post covering basics of that later) and I thought of using SSO (Single sign on) using Windows live account for membership. This was an obvious option considering Windows 8 allows you to use your windows live account to sign in to windows 8. And moreover, most of the Windows 8 metro applications do use SSO for membership. During the implementation, I hit a roadbump and it took a lot of time to fix the problem, since, the issue wasn't mentioned on any of official blog posts (though answer to some questions on public forums did help out) so I thought to write a simple step by step procedure to cover this. I am covering C# api but the concepts apply on both Javascript and C++ apis as well. (keep in mind this tutorial is specific for Windows 8 Metro api which is available in Visual Studio 2012)

1. First of all, download and install Windows Live SDK (http://go.microsoft.com/fwlink/p/?LinkId=224535)

2. Create a Blank application under Metro style application (found under C# template)

3. In Solution explorer, right click on "References" node under your project and click "Add Reference"

4. Click Windows -> Extensions -> Live SDK and click OK

5. Open MainPage.xaml.cs (or the page on which you want to add controller), add following references to Windows live libraries;

using Microsoft.Live;
using Microsoft.Live.Controls;

and declare following as global private variables

private LiveConnectClient client;
private LiveConnectSession session;


6. Now, open MainPage.xaml file and in the "Page" tag, add following namespace for windows live sdk;

xmlns:live="using:Microsoft.Live.Controls"

7. Add following windows live sign-in button under the Grid you want to host sign-in button controler

<live:SignInButton x:Name="btnSignin" Scopes="wl.signin wl.basic" SessionChanged="btnSignin_SessionChanged" />
<TextBlock Height="32" Foreground="White" Name="infoTextBlock" Width="419" />

As soon as the session/state is changed, a function btnSingin_SessionChanged will be called. (the second tag is just to show the sign in status)

8. Now, let's add a simple code in session changed handler:

private async void btnSignin_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
        {
            if (e.Status == LiveConnectSessionStatus.Connected)
            {
                session = e.Session;
                client = new LiveConnectClient(session);
                LiveOperationResult operationResult = await client.GetAsync("me");
                try
                {
                    dynamic meResult = operationResult.Result;
                    if (meResult.first_name != null &&
                        meResult.last_name != null)
                    {
                        infoTextBlock.Text = "Hello " +
                            meResult.first_name + " " +
                            meResult.last_name + "!";
                    }
                    else
                    {
                        infoTextBlock.Text = "Hello, signed-in user!";
                    }
                }
                catch (LiveConnectException exception)
                {
                    this.infoTextBlock.Text = "Error calling API: " +
                        exception.Message;
                }
            }
            else
            {
                infoTextBlock.Text = "Not signed in.";
                client = null;
            }
        }

9. At this point, if you try to try Single sign-on, you'll see the windows live sign in dialog, but when you try to login, it'll keep giving you error that "An error occurred while performing the operation. Please try again later" and if you see the stack trace it points to mscorlib. In order to make sure that this works, goto https://manage.dev.live.com/build and follow instructions mentioned there.Once, you complete 2 step procedure mentioned at above url, SSO will start working.

hope this helps.
 
Reference: http://msdn.microsoft.com/en-us/library/live/hh826551.aspx 

Sunday, May 13, 2012

Strategy to handle worker threads in php and create daemon

If you are working on a project which requires fair amount of background work to be done, then you must have seen the requirement of keeping background threads separate. Unfortunately, there is no explicit way of threading in php (there are a number of way around to do this, but those to me look like hacks rather a supported feature). Such needs are normally seen in a project which requires some work to be done which is not needed immediately. For example, if a user uploads a picture and you want to crop that picture, or, you want to send some sort of notification email etc. This is a classical case of having a worker thread doing all these tasks in parallel. There are a number of open source libraries available which take care of such things e.g. https://github.com/pda/pheanstalk . But if you want to do this yourself, then here is a simple strategy.

  1. Create a queue in memcache or add the jobs in some table in DB
  2. Create a php script which takes a job out from memcache queue to from the table in DB and executes the job
  3. Run the php script as a background thread.

 First two points are fairly simple. So, lets talk about third point now. How would you run the php script as a background thread. There are two ways in linux to do this. One is to run the script as a cron. To know how to run a script as a cron job, refer to my post here => http://saadnawaz.blogspot.com/2012/05/create-cron-job-in-linux.html. Now, if you think that your job is something which can run after 1 minute, then simply write the php script and add entry in the crontab. Though, in most of cases, 1 minute is just a bit too much delay. So, the next option is creating a daemon. Daemon is a process which runs in the background. What you should be doing is running the worker php script as a daemon. Follow the following steps to do that:(this is just one way of creating a daemon, there are other ways as well, but this seems simplest to me)

1. Create a shell script which executes the php script file, which is gonna be something like:

while true
do
     php /pathtofile/filename.php
     sleep 5
done

What this shell script is doing is fairly straight forward. You have an infinite loop which runs a php script file, and after than sleeps for 5 seconds. So, basically you are achieving something like cron, but you are executing the script every 5 seconds (which cron can't do, since, the granularity is upto minutes).

Since, this is treated as an executable, therefore, make sure you have given appropriate rights on the script and php worker file.

2. Run the shell script as a daemon:

/completePathToFile/shell.sh &

The "&" at the end runs this as a daemon.

Now, keep in mind, it's always better to use an existing solution rather reinventing the wheel. But, if your problem is not big enough to use open source solutions, then the above strategy should get you started.

Create a cron job in linux

Cron is a system daemon used to execute a specific task at specific time intervals. In linux, there is a simple text file called crontab which contains a list of commands to be run at specific times. In order to add an entry in crontab, first you need to open the crontab file. In order to open the crontab file in edit mode, use the following command

crontab -e

Keep in mind you need to edit crontab file with administrator privileges. So, you might have to use sudo crontab -e.

You can add an entry into the crontab file using the following format:

minute (0-59) hour (0-23, 0 = midnight) day (1-31) month (1-12) weekday (0-6, 0 = Sunday) command 

Notice, there is a space between each section. There are total 5 sections, with each section separated by a space. You can use a * (asterisk) for a section if you want to run the command for every instance of that section. A sample crontab instruction is:

10 08 4 2 1 /somedirectorypath/desiredCommand

The above will execute /somedirectorypath/desiredCommand at 8:10am on February 4th plus every Monday in February. If you want to run a command every 5 minutes, use the following instruction:

*/5 * * * * /somedirectorypath/desiredCommand

The first section i.e. */5 is going to be true for a minute which is divisible by 5. Hence, the command will execute every 5th minute. If you want to run a command every minute, then simply have all sections as *.


There is one limitation to the cron job though, the lowest level of granularity is minute. So, you can't run a command after some specific seconds.

Sunday, January 22, 2012

A simple strategy for time localization

If you are building a webapp which is dependent on time (for example, a bidding or betting application) then you must have seen the requirement to show time on the webapp depending on the timezone of the logged in user. The other day i was going through various blogs and i saw a couple of posts by different blogs covering this approach and i was amazed to see that how complex route they took. So, i thought to write a post describing some really easy steps to achieve this.
There are multiple decisions/questions that you have to answer in order to achieve this goal.

1. In what timezone will you save the time in your db?
2. How would you get user's timezone?
3. When do you want to change the timezone according to user's timezone?

In this post i'll go through each of the above questions one by one.

In order to answer the first question, the best option is to go for GMT/UTC timezone. The reason is that it's extremely easy to convert time from GMT to GMT+8 or GMT0-5 etc. You can simply add/subtract the difference from the timestamp. But, you have to consider another thing here, if you are hosting your webapp on a shared server, then you need to consider the timestamp your shared hosting server is using. Because for any time critical webapp, you'll be frequently getting the current time and the server will be returning you the timestamp depending on the timezone it has set. Most of the shared hosting servers don't allow you to change the timezone. Now, you can also keep GMT/UTC timezone as the default timezone and you can change the timezone of the current time as well. Both are valid ways,  so it's up to you what to go for. Now, whenever user enters some datetime, you convert the datetime entered into the default timezone and save it in your db.

Now, the second question, i.e. how would you get user's timezone. Now there are a couple of ways to achieve this.

1. Ask the user for his timezone upon registration and use that
This is a fairly popular and accurate method of getting user's timestamp. The only problem in this approach is that it's not dynamic, i.e. if the user moves to a different timezone, he'll have to manually change his timezone on your webapp. If you don't mind putting your users through this step, then this method is recommended.

2. Get the timezone from the ip of the user
This is another method of getting the timezone of the logged in user. You can use ip of the user to track his geolocation and from that you can determine his timezone. Though, personally i don't think this is a good approach to go for. In my personal opinion it looks like an over kill unless you are already tracking and showing data on the basis of user's geolocation.

3. Get the timezone of the user through javascript.
I personally like this method because of its simplicity. You can easily get the timezone of the logged in user through following steps.
  • Get the timezone of the logged in user on your main page. For this i saw such complex approaches that i was amazed. Certainly some people love to bring gun to a knife fight :s .You can achieve this through one line of the following code
    • - (new Date.getTimezoneOffset()/60)
      • This method basically returns the difference between GMT and local time in minutes. So, if you are at GMT+2 then Date.getTimezoneOffset() will return -120 and if you are at GMT-2 then it will return 120. Therefore, simply put a - before it and divide the result by 60 and you'll get the time difference in hours. 
  • Make an ajax call and send this time difference on some server page and store it in session or cookie. A simple snippet of the code is
                         <?php 
             session_start();
             $_SESSION['userTimeZone'] = $_GET['utz'];
           ?>
Now, you have user's timezone saved in session. Whenever, you want to display a time, simply convert the stored time into user's timezone. Now, again there are multiple ways to achieve this. One very simple way is to save user's timezone in terms of seconds and simply add/subtract from the stored timestamp (if you used GMT as your default timezone). Or, you can use the following code to achieve this as well. (in order to use the following code you need to save user's timezone in proper format i.e. GMT+2)

public function convertTimeZone($date, $from_tz, $to_tz, $dateFormat) {
    $dateObj = new DateTime($date, new DateTimeZone($from_tz));
    $dateObj->setTimezone(new DateTimeZone($to_tz));
   
    return $dateObj->format($dateFormat);
}


And there you go, it's as simple as that.

Saturday, January 21, 2012

A simple jquery based ticker

This is a fairly simple and straight forward tutorial. The focus of this post is to share a simple method to create a ticker. There are many real life scenerios where you need tickers, e.g. on a news website to show the latest news. Now, keep in mind that this tutorial is not about real time event handling (though i am planning to write a tutorial on that as well). In this post, i'll simply cover a piece of code through which you can get all the data from server and then show it in the form of a automatic carousel (ticker). So, let's start with the code.

var initTicker = function(wrapperDiv, dataDiv, elementHeight, elementsToBeShown){
    $.get('getFeeds.php', function(data) {
        $('#'+dataDiv).html(data);
        var outerDiv = $('<div id="outerDiv"></div>').hide();       
        outerDiv.css({
                      'width': $("#activites").width(), 
                      'height': elementHeight*elementsToBeShown + 10,
                      'overflow': 'hidden'
                    });
        outerDiv.append($("#"+dataDiv));
        outerDiv.show();
        $("#"+wrapperDiv).append(outerDiv);         
        setInterval( function () { moveItUp(dataDiv, elementHeight) }, 7000); 
  });
}

In the above code, the data is basically provided from getFeeds.php.
wrapperDiv contains the id of the div which contains the div in which data is to be displayed. (A better approach is to create this wrapper div at run time and place the div in which data is to be shown inside the wrapper... for the sake of simplicity i am not including that code here)
dataDiv contains the id of the div in which data is to be shown
elementHeight height of one news element (again this can be determined through a simple javascript)
elementsToBeShown number of elements that you want to show on screen at a time.
 
a simple HTML snippet is


<div id="wrapper">
      <div id="activities">
      </div>
</div>

Now, before i move forward, let me just quickly explain what the above js code is doing. For explanation, i am gonna be using the divs shown in shown html snippet. A step by step explanation is:

1. Get the data from server and place the data in "activities"
2. Create a div at run time and set its width equal to the width of "activities" since we want the ticker to move vertically. Set the height of the div equal to the elementHeight*elementsToBeShown. Add some padding on the height side to get a smooth effect.. Set the overflow to hidden. Now, i'll get back to this point that why do we need the "overflow" property to be hidden.
3. Place the "activities" div inside "outerDiv"
4. Initiate the function which is supposed to apply the carousel/ticker style. Set the timer value according to your need. In the above code, the ticker will move the feeds every 7 seconds.

Now, let's quickly see what is moveItUp() is doing.

var moveItUp = function(dataDiv, elementHeight){
     var reduceMargin = '-='+elementHeight;
     $("#"+dataDiv).animate({'margin-top': reduceMargin}, 2000); 
}


Ok, this is only a two liner function. The above function is simply decreasing the "margin-top" property of "activities" div (which contains the data) by elementHeight. Now, why elementHeight and what purpose is served by decreasing "margin-top"?? The above function will successfully, move the data one element at a time. If you want to move 2 elements up, simply set reduceMargin to "-="+(2*elementHeight). Now, coming to the second part of question. If you remember, in the initialize code of "outerDiv", i mentioned to set "overflow" property to hidden. If you set "overflow" property to "hidden" of a div (or any element) then you'll see only the data which can fit in the mentioned height and width. So, for example, if a div's height and width are set to 500px, and you place data which requires 800px of height, then you'll only see 500px worth of data and rest will be clipped, there won't be any scrollbar as well. (for those who don't remember overflow property, a quick link http://www.w3schools.com/cssref/pr_pos_overflow.asp). So, in the initialization code, we set the height of the outerDiv to elementHeight*numberOfElements, and "activities" (dataDiv) contains all the data, but since "activities" is inside outerDiv, therefore, only that number of elements are shown on the screen that we passed to initTicker function, rest are clipped (not shown). Now, when we decrease the "margin-top" of "activities" div, it basically moves the data inside div vertically, but since, outerDiv can only contain "numberOfElements" elements on the screen at a time, the next elements in the "activities" div show up and the elements at top disappear. Using the jquery function "animate" we give the margin-top reduction step some nice animation and hence you get an effect of ticker/carousel.