Skip to content

How Facebook (probably) implements SMS threads

A lot of web applications provides you the ability to receive or post updates using SMS (text messages). Twitter is the posterboy of such applications.

But the feature that distinguishes Facebook SMS updates from any other service is that you can actually reply to individual messages and your message then becomes a part of the aforementioned thread. You don’t have to specify any special command to do so. Just hit the reply  button and you are done.

How do they know which message belongs to which thread? Its simple, each message comes from a different number. For example, say A writes something on your wall, then you will receive a message from +91922305501. Also B sends a message to you, a message comes from +91922305502 and when C comments on your note, you get a message from +91922305503. How many numbers do facebook own? Probably 100 in India, from +91922305500 to +9192230599.  A per user mapping of the number from which the message is sent and the object/thread id for that message is kept on the backend. So when the user replies to a particular number, say +91922305502 , it knows that is was a reply to the message sent by B and hence treats as a reply to that message. A rotation policy is used to decide from which number the message is to be sent. So after recieving a message from +9192230599, the next message will be from +91922305500  and now you cannot reply to the thread represented by the earlier message from the same number.

Discalimer: This is just a guess of how this functionality might have been implemented (or at least how I would implement it) and based strictly on SMSes received in India. Actual implementation might (probaly is) be entierly different from what is explained here.

Tagged , , , , ,

Bing/Google toggle bookmarklet

I’ve been trying out Bing as my default search engine for last few months and the results are definitely at par with that of Google for most of the consumer categories. But sometimes you just need a quick toggle to see what Google would return for your query. So here is a small bookmarklet that I wrote that toggles from Bing to Google and vice versa.

Drag this to you favourites bar: Bing/Google Toogle

Note: Its tested on IE8 only. A few tweaks might be required for Firefox.

Tagged , , , ,

Minifying Javascript/css without changing file references in your source

Rule 10 of Steve Souders High Performance Web Sites: Minify Javascript

The most common problem faced while implemnting this is how you handle the full and minified version and how to change there reference in referencing documents. One of the easier ways to do this is to make it part of the deployment process.

Here are the relevent steps involved.

I’m using YUI Compressor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
 
#Execute this script after checking out the latest source from repository.
 
#Minify all javascript files
cd /path/to/javascript
for x in `ls *.js`
do
        java -jar /path/to/compressor/yuicompressor-2.4.2.jar -o ${x%%.*}-min.js --preserve-semi  $x
done
 
#Minfiy all css files
cd /path/to/css
for x in `ls *.css`
do
        java -jar /path/to/compressor/yuicompressor-2.4.2.jar -o ${x%%.*}-min.css  $x
done

Now you don’t want to replace all references to x.css or x.js in your development code with references to x-min.css and x-min.js respectively. So what you can do is rewrite all those filenames at the web server level.

For apache the following rewrite rules work fine:

1
2
3
4
#enable rewriting
RewriteEngine on
RewriteRule /(.*)\.js /$1-min.js
RewriteRule /(.*)\.css /$1-min.css

Caution: Remember to delete existing minified css/js file before running the minifying script or you will end up with file names like x-min-min-min.js and so on. One way to do this is to clear the js/css folder before checking out files from your source repository.

Tagged , , , , , , , ,

Humanizing the time difference ( in django )

django.contrib.humanize is a set of Django template filters that adds human touch to data. It provides naturalday filter that formats date to ‘yesterday’, ‘today’ or ‘tomorrow’ when applicable.

A similar requirement which the humanize pacakge does not address is to display time difference with this human touch. so here is a snippet that does so.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from django import template
 
register = template.Library()
 
MOMENT = 120    # duration in seconds within which the time difference 
                # will be rendered as 'a moment ago'
 
@register.filter
def naturalTimeDifference(value):
    """
    Finds the difference between the datetime value given and now()
    and returns appropriate humanize form
    """
 
    from datetime import datetime
 
    if isinstance(value, datetime):
        delta = datetime.now() - value
        if delta.days > 6:
            return value.strftime("%b %d")                    # May 15
        if delta.days > 1:
            return value.strftime("%A")                       # Wednesday
        elif delta.days == 1:
            return 'yesterday'                                # yesterday
        elif delta.seconds > 3600:
            return str(delta.seconds / 3600 ) + ' hours ago'  # 3 hours ago
        elif delta.seconds >  MOMENT:
            return str(delta.seconds/60) + ' minutes ago'     # 29 minutes ago
        else:
            return 'a moment ago'                             # a moment ago
        return defaultfilters.date(value)
    else:
        return str(value)

Tagged , , ,

Running Glassfish as a service on CentOS

Here is how you run glassfish as a service on CentOS:

  1. Create a user glassfish (you can call it anything you want) under which Glassfish will run.
    #useradd glassfish
  2. Install glassfish in /home/glassfish.
  3. Create the startup script /etc/init.d/glassifsh for glassfish.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    
    #!/bin/bash
    #
    # glassfish:          Startup script for Glassfish Application Server.
    #
    # chkconfig: 3 80 05
    # description:      Startup script for domain1 of Glassfish Application Server.
     
    GLASSFISH_HOME=/home/glassfish/glassfish;
    export GLASSFISH_HOME
     
    GLASSFISH_OWNER=glassfish;
    export GLASSFISH_OWNER
     
    start() {
            echo -n "Starting Glassfish: "
            echo "Starting Glassfish at `date`" >> $GLASSFISH_HOME/domains/domain1/logs/startup.log
            su $GLASSFISH_OWNER -c "$GLASSFISH_HOME/bin/asadmin start-domain domain1" >> $GLASSFISH_HOME/domains/domain1/logs/startup.log
            sleep 2
            echo "done"
    }
     
    stop() {
            echo -n "Stopping Glassfish: "
            echo "Stopping Glassfish at `date`" >> $GLASSFISH_HOME/domains/domain1/logs/startup.log
            su $GLASSFISH_OWNER -c "$GLASSFISH_HOME/bin/asadmin stop-domain domain1" >> $GLASSFISH_HOME/domains/domain1/logs/startup.log
            echo "done"
    }
     
    # See how we were called.
    case "$1" in
            start)
                    start
                    ;;
            stop)
                    stop
                    ;;
            restart)
                    stop
                    start
                    ;;
            *)
                    echo $"Usage: glassfish {start|stop|restart}"
                    exit
    esac
  4. Install the service
    #chmod +x /etc/init.d/glassfish
    #chkconfig --add glassfish
    #chkconfig --level 3 glassfish on
  5. Start glassfish.
    #/etc/init.d/glassfish start

Tagged , , ,