Today, when I was trying out a new application bufferapp, I noticed something very interesting in their interface which immediately caught my attention. Although it is a tiny little detail about the interface, but I think it is one of the very important ones especially in context of a web app, so I thought of writing it down.
If you have used bufferapp, you will notice following things (shown in the picture below):
High level navigation at the top (header section).
Notification with some call to action right beneath the header section (in this case Install Chrome extension)
Main content section which is about buffering your tweets.
The detail that I wanted to point out was, when I am navigating from bottom section to the header section, I would see “install” button wiggles for a moment. Now that momentary wiggle made me pay attention and read that message to understand install what ? It felt exactly like as if you are navigating through your office corridor and someone calls you out to show you something. So this “wiggle for .2 seconds” was almost like someone calling out to make sure I read that message. You can see this in action here in modern browsers specifically Chrome, Safari or Firefox.
You will see this layout pattern in lot of places where application is trying to communicate something important to the user and would like him/her to take an action like in this case Buffer wanted me to install their chrome extension as I was using Google Chrome. Typically, users develop a blind eye to some of these layout patterns and it becomes very challenging for the interface designer to craft an experience which could draw user’s attention to an important action.
These simple but important details separates a good design from a great design. In rest part of the post, I would throw some light on implementation details for this wiggle effect. Most of the modern browsers support animation through CSS3 these days.
keyframe definition for wiggle effect would look like this: (omitting the browser prefix for better readability)
Think of keyframes directive as defining a animation function which will be called later on elements like buttons in our UI. We implement wiggle function by first rotating the subject by 2 degree anticlockwise, then to 2 degree clockwise and then rotate it back by 2 degree anticlockwise.
Let say our html markup for flash message looks like this:
<divclass="flash_message">
Install Now
</div>
Inorder to invoke it on a mouseover of the flash message block. Our invokation code in CSS would look like this:
This is a classic example of applying CSS3 techniques at the experience layer in your application. Let me know what you think of such experiences, drop a note below in the comment section or tweet me @sunil .
I ran in to a situation in a project recently where I got an opportunity to use JQuery Deferred Objects. I wanted to implement an Async IF operation. Async IF operation is like watching a condition to become true (may be in future) and then invoking something when it becomes true. So this is essentially an “if” operation in async mode and your logic might involve watching more than one condition to be met.
For example:
Consider a demo web application where colored boxes (red or green) can appear on the screen depending on some logic or user action. We want to do certain things if a red box appears or a green box appears or both of them appears.
Let say we we want to do something when a red box becomes visible on our screen, so it will look something like this:
async_if is_box_visible, “red”
whenever it is true, then do_something
Another one, let say, we want to pop up blue box when we see red and green boxes are visible on our screen for the first time, so it will look something like this
async_if is_box_visible, “red”
async_if is_box_visible, “green”
whenever both the above are true, then inject blue box
So here we are composing operations which involves some async operations because we do not know when these conditions will be met. This is exactly where Deferred objects shines.
I prepared a demo for the above scenario and rest of the part, I will walk you through some samples. I have shared the entire code in github repository at async_if. You can see the demo here.
Async IF Operation: It is a generic construct which takes two arguments:
A function which checks a condition (lets call it checker function henceforth)
Arguments to be passed to the checker function
timeout (milliseconds) for reporting failure if condition is not met within timeout milliseconds
Async IF operation returns an object of type Promise which can be used to compose higher level application logic using jquery’s operations around deferred objects. Following javascript code is generated from the coffee script async_if.coffee.
Use of Async IF Operation: In code below, we are trying to build logic which is when red and green box both appears on the screen, inject a blue box on the screen. Now appearance of red and green box is purely async which will happen on user action like “injecting a box” by clicking on buttons in the demo application.
Let me know your thoughts about this construct. Drop a note below or contact me at @sunil
Log analysis has become a difficult task in our production environment at work because logs are distributed on different machines and in different files. So, we wanted all the exception logs from all of our apps to be tracked centrally and viewed in single console.
And once again, we found another good use case for Redis. Our strategy is to dump all of critical logs in to a Redis List and have a background worker which continuously pulls logs from the Redis List and write stuff in log file.
As we use python for all our backend work, I quickly wrote a Log Handler that can dump log messages in to Redis.
So RedisLogHandler class looks like this:
To hook up this RedisLogHandler to your application logger, all you need to do is following:
I quickly hooked it up to our all of our background jobs in celery and I can see it working. Let me know what you think of this solution.
Redis is one of my favorite data storage platform and I won’t miss a single chance to use it wherever I can. One of the biggest strengths of Redis has been that you can define your data modelling in the most natural form like key-value/hashes/lists/sets. I prefer thinking of data storage in form of list, hashes, sets instead of tables :).
Redis provides a very good set of APIs(commands) which pretty much allows majority of the operations you would like to perform on these data types in a single command.
But in the past, I encountered situations where solution design required the following:
Executing more than one Redis commands.
Outcome of one command would determine whether to run other commands or not.
Atomic execution of 1 & 2 [Transactional].
Contention environement for such operations, so optimistic locking schemes wont work.
Situations like above pretty much made me turn away from Redis in the past.
This is going to change now. About a month ago, @antirez (creator of Redis) released Lua-Scripting support in a different branch by hacking over a weekend (that shows how terrific hacker he is).
Lua-Scripting support Redis pretty much solves majority of the problems of the nature described above. This has great potential and can’t wait to see what community do with it.
I spend sometime today to try out scripting, so thought of doing a quick write up about what I did today.
I started with simple goal of implementing two new commands zpop and zrevpop for sorted set data type using scripting.
ZPOP: This will allow popping out element with lowest score from a sorted set.
ZREVPOP: This will allow popping out element with highest score from a sorted set.
Setup
Follow these steps to get scripting version of Redis running on your machine.
git clone https://github.com/antirez/redis.git
cd redis
git checkout scripting
make
Now you should all the binaries ready in the src folder (redis-server and redis-cli). Run the server by running redis-server binary.
ZPOP Implementation
Redis implements redis.call interface to invoke redis commands from Lua code. Here is Lua script for zpop command.