Posts Tagged 'Development'

November 27, 2012

Tips and Tricks - Building a jQuery Plugin (Part 1)

I've written several blogs detailing the use of different jQuery plugins (like Select2, LazyLoad and equalHeights), and in the process, I've noticed an increasing frustration among the development community when it comes to building jQuery plugins. The resources and documentation I've found online have not as clear and easy as they could be, so in my next few posts, I'll break down the process to make jQuery plugin creation simple and straightforward. In this post, we'll cover the basic structure of a plugin and where to insert your own functionality, and in Part 2, we'll pick a simple task and add on to our already-made structure.

Before I go any further, it's probably important to address a question you might be asking yourself: "Why would I want to make my own plugin?" The best reason that comes to my mind is portability. If you've ever created a large-scale project, take a look back into your source code and note how many of the hundreds of lines of jQuery code you could put into a plugin to reuse on a different project. You probably invested a lot of time and energy into that code, so it doesn't make sense to reinvent the wheel if you ever need that functionality again. If that's not enough of a reason for you, I can also tell you that if you develop your own jQuery plugin, you'll level-up in cool points, and the jQuery community will love you.

For this post, let's create a jQuery plugin that simply returns, "This is our awesome plugin!" Our first step involves putting together the basic skeleton used by every plugin:

(function($) {
    $.fn.slPlugin = function() {
 
            // Awesome plugin stuff goes here
    };
}) (jQuery);

This is your template — your starting point. Practice it. Remember it. Love it. The "slPlugin" piece is what I chose to name this plugin. It's best to name your plugin something unique ... I always run a quick Google search to ensure I don't duplicate the name of a plugin I (or someone else) might need to use in a project alongside my plugin. In this case, we're calling the example plugin slPlugin because SoftLayer is awesome, and I like naming my plugins after awesome things. I'll save this code in a file called jquery.slPlugin.js.

Now that we have our plugin's skeleton, let's add some default values for variables:

(function($) {
    $.fn.slPlugin = function(options) {
            var defaults = {
                myVar: "default", // this will be the default value of this var
                anotherVar: 0,
                coolVar: "this is cool",                
            };
            var options = $.extend(defaults, options);
    };
}) (jQuery);

Let's look at the changes we made between the first example and this one. You'll notice that in our second line we added "options" to become $.fn.slPlugin = function(options) {. We do this because our function is now accepting arguments, and we need to let the function know that. The next difference you come across is the var defaults blurb. In this section, we're providing default values for our variables. If you don't define values for a given variable when you call the plugin, these default values will be used.

Now let's have our plugin return the message we want to send:

(function($) {
    $.fn.slPlugin = function(options) {
            var defaults = {
                myVar: "This is", // this will be the default value of this var
                anotherVar: "our awesome",
                coolVar: "plugin!",
            };
            var options = $.extend(defaults, options);
            this.each(function() {
                ourString = myVar + " " + anotherVar + " " + coolVar;
            });
            return ourString;
    };
}) (jQuery);

We've defined our default values for our variables, concatenated our variables and we've added a return under our variable declaration. If our jQuery plugin is included in a project and no values are provided for our variables, slPlugin will return, "This is our awesome plugin!"

It seems rather rudimentary at this point, but we have to crawl before we walk. This introductory post is laying the groundwork of coding a jQuery plugin, and we'll continue building on this example in the next installment of this series. As you've seen with the LazyLoad, equalHeights and Select2, there are much more complicated things we can do with our plugin, and we'll get there. Sneak Preview: In the next installment, we'll be creating and implementing a truncation function for our plugin ... Get excited!

-Cassandra

November 6, 2012

Tips and Tricks - Pure CSS Sticky Footers

By now, if you've seen my other blog posts, you know that I'm fascinated with how much JavaScript has evolved and how much you can do with jQuery these days. I'm an advocate of working smarter, not harder, and that maxim knows no coding language limits. In this post, I want to share a pure CSS solution that allows for "sticky" footers on a web page. In comparing several different techniques to present this functionality, I found that all of the other routes were overkill when it came to processing time and resource usage.

Our objective is simple: Make the footer of our web page stay at the bottom even if the page's content area is shorter than the user's browser window.

This, by far, is one of my *favorite* things to do. It makes the web layout so much more appealing and creates a very professional feel. I ended up kicking myself the very first time I tried to add this functionality to a project early in my career (ten years ago ... already!?) when I found out just how easy it was. I take solace in knowing that I'm not alone, though ... A quick search for "footer stick bottom" still yields quite a few results from fellow developers who are wrestling with the same frustrating experience I did. If you're in that boat, fear no more! We're going to your footers in shape in a snap.

Here's a diagram of the problem:

CSS Footer

Unfortunately, a lot of people try to handle it with setting a fixed height to the content which would push the footer down. This may work when YOU view it, but there are several different browser window heights, resolutions and variables that make this an *extremely* unreliable solution (notice the emphasis on the word "extremely" ... this basically means "don't do it").

We need a dynamic solution that is able to adapt on the fly to the height of a user's browser window regardless if the resize it, have Firebug open, use a unique resolution or just have a really, really weird browser!

Let's take a look at what the end results should look like:

CSS Footer

To make this happen, let's get our HTML structure in place first:

<div id="page">
 
      <div id="header"> </div>
 
      <div id="main"> </div>
 
      <div id="footer"> </div>
 
</div>

It's pretty simple so far ... Just a skeleton of a web page. The page div contains ALL elements and is immediately below the

tags in the page code hierarchy. The header div is going to be our top content, the main div will include all of our content, and the footer div is all of our copyrights and footer links.

Let's start by coding the CSS for the full page:

Html, body {
      Padding: 0;
      Margin: 0;
      Height: 100%;
}

Adding a 100% height allows us to set the height of the main div later. The height of a div can only be as tall as the parent element encasing it. Now let's see how the rest of our ids are styled:

#page {
      Min-height: 100%;
      position:relative;
}
 
#main {
      Padding-bottom: 75px;   /* This value is the height of your footer */
}
 
#footer {
      Position: absolute;
      Width: 100%;
      Bottom: 0;
      Height: 75px;  /* This value is the height of your footer */
}

These rules position the footer "absolutely" at the bottom of the page, and because we set #page to min-height: 100%, it ensures that #main is exactly the height of the browser's viewing space. One of the best things about this little trick is that it's compliant with all major current browsers — including Firefox, Chrome, Safari *AND* Internet Explorer (after a little tweak). For Internet Explorer to not throw a fit, we need concede that IE doesn't recognize min-height as a valid property, so we have to add Height: 100%; to #page:

#page {
      Min-height: 100%;  /* for all other browsers */
      height: 100%;  /* for IE */
      position:relative;
}

If the user does not have a modern, popular browser, it's still okay! Though their old browser won't detect the magic we've done here, it'll fail gracefully, and the footer will be positioned directly under the content, as it would have been without our little CSS trick.

I can't finish this blog without mentioning my FAVORITE perk of this trick: Should you not have a specially designed mobile version of your site, this trick even works on smart phones!

-Cassandra

October 17, 2012

Tips and Tricks - jQuery Select2 Plugin

Web developers have the unique challenge of marrying coding logic and visual presentation to create an amazing user experience. Trying to find a balance between those two is pretty difficult, and it's easy to follow one or the other down the rabbit hole. What's a web developer to do?

I've always tried to go the "work smarter, not harder" route, and when it comes to balancing functionality and aesthetics, that usually means that I look around for plugins and open source projects that meet my needs. In the process of sprucing up an form, I came across jQuery Select2, and it quickly became one of my favorite plugins for form formatting. With minimal scripting and little modification, you get some pretty phenomenal results.

We've all encountered drop-down selection menus on web forms, and they usually look like this:

Option Select

Those basic drop-downs meet a developer's need for functionality, but they aren't winning any beauty pageants. Beyond the pure aesthetic concerns, when a menu contains dozens (or hundreds) of selectable options, it becomes a little unwieldy. That's why I was so excited to find Select2.

With Select2, you can turn the old, plain, boring-looking select boxes into beautiful, graceful and more-than-functional select widgets:

Pretty Option Select

Not only is the overall presentation of the data improved, Select2 also includes an auto-complete box. A user can narrow down the results quickly ad easily, and if you've got some of those endlessly scrolling select boxes of country names or currencies, your users will absolutely notice the change (and love you for it).

What's even sexier than the form facelift is that you can add the plugin to your form in a matter of minutes.

After we download Select2 and upload it to our box, we add our the jQuery library and scripts to the <head> of our document:

<script src="jquery.js" type="text/javascript"></script> 
<script src="select2.js" type="text/javascript"></script>

For the gorgeous styling, we'll also add Select2's included style sheet:

<link href="select2.css" rel="stylesheet"/>

Before we close our <head> tag, we invoke the Select2 function:

<script>
$(document).ready(function() { $("#selectPretty").select2(); });
</script>

At this point, Select2 is locked and load, and we just have to add the #selectPretty ID to the select element we want to improve:

<select id="selectPretty">
<option value="Option1">Option 1</option>
<option value="Option2">Option 2</option>
<option value="Option3">Option 3</option>
<option value="Option4">Option 4</option>
</select>

Notice: the selectPretty ID is what we defined when we invoked the Select2 function in our <head> tag.

With miniscule coding effort, we've made huge improvements to the presentation of our usually-boring select menu. It's so easy to implement that even the most black-and-white coding-minded web developers can add some pizzazz to their next form without having to get wrapped up in styling!

-Cassandra

September 12, 2012

How Can I Use SoftLayer Message Queue?

One of the biggest challenges developers run into when coding large, scalable systems is automating batch processes and distributing workloads to optimize compute resource usage. More simply, intra-application and inter-system communications tend to become a bottleneck that affect the user experience, and there is no easy way to get around it. Well ... There *was* no easy way around it.

Meet SoftLayer Message Queue.

As the name would suggest, Message Queue allows you to create one or more "queues" or containers which contain "messages" — strings of text that you can assign attributes to. The queues pass along messages in first-in-first-out order, and in doing so, they allow for parallel processing of high-volume workflows.

That all sounds pretty complex and "out there," but you might be surprised to learn that you're probably using a form of message queuing right now. Message queuing allows for discrete threads or applications to share information with one another without needing to be directly integrated or even operating concurrently. That functionality is at the heart of many of the most common operating systems and applications on the market.

What does it mean in a cloud computing context? Well, Message Queue facilitates more efficient interaction between different pieces of your application or independent software systems. The easiest way demonstrate how that happens is by sharing a quick example:

Creating a Video-Sharing Site

Let's say we have a mobile application providing the ability to upload video content to your website: sharevideoswith.phil. The problem we have is that our webserver and CMS can only share videos in a specific format from a specific location on a CDN. Transcoding the videos on the mobile device before it uploads proves to be far too taxing, what with all of the games left to complete from the last Humble Bundle release. Having the videos transcoded on our webserver would require a lot of time/funds/patience/knowledge, and we don't want to add infrastructure to our deployment for transcoding app servers, so we're faced with a conundrum. A conundrum that's pretty easily answered with Message Queue and SoftLayer's (free) video transcoding service.

What We Need

  • Our Video Site
  • The SoftLayer API Transcoding Service
  • SoftLayer Object Storage
    • A "New Videos" Container
    • A "Transcoded Videos" Container with CDN Enabled
  • SoftLayer Message Queue
    • "New Videos" Queue
    • "Transcoding Jobs" Queue

The Process

  1. Your user uploads the video to sharevideoswith.phil. Your web app creates a page for the video and populates the content with a "processing" message.
  2. The web application saves the video file into the "New Vidoes" container on object storage.
  3. When the video is saved into that container, it creates a new message in the "New Videos" message queue with the video file name as the body.
  4. From here, we have two worker functions. These workers work independently of each other and can be run at any comfortable interval via cron or any scheduling agent:
Worker One: Looks for messages in the "New Videos" message queue. If a message is found, Worker One transfers the video file to the SoftLayer Transcoding Service, starts the transcoding process and creates a message in the "Transcoding Jobs" message queue with the Job ID of the newly created transcoding job. Worker One then deletes the originating message from the "New Videos" message queue to prevent the process from happening again the next time Worker One runs.

Worker Two: Looks for messages in the "Transcoding Jobs" queue. If a message is found, Worker Two checks if the transcoding job is complete. If not, it does nothing with the message, and that message is be placed back into the queue for the next Worker Two to pick up and check. When Worker Two finds a completed job, the newly-transcoded video is pushed to the "Transcoded Videos" container on object storage, and Worker Two updates the page our web app created for the video to display an embedded media player using the CDN location for our transcoded video on object storage.

Each step in the process is handled by an independent component. This allows us to scale or substitute each piece as necessary without needing to refactor the other portions. As long as each piece receives and sends the expected message, its colleague components will keep doing their jobs.

Video transcoding is a simple use-case that shows some of the capabilities of Message Queue. If you check out the Message Queue page on our website, you can see a few other examples — from online banking to real-time stock, score and weather services.

Message Queue leverages Cloudant as the highly scalable low latency data layer for storing and distributing messages, and SoftLayer customers get their first 100,000 messages free every month (with additional messages priced at $0.01 for every 10,000).

What are you waiting for? Go get started with Message Queue!

-Phil (@SoftLayerDevs)

September 6, 2012

Tips and Tricks - jQuery equalHeights Plugin

Last month, I posted a blog about dynamically resizing divs with jQuery, and we received a lot of positive feedback about it. My quest to avoid iframes proved to be helpful, so I thought I'd share a few more esoteric jQuery tips and tricks that may be of use to the developers and designers in the audience. As I thought back about other challenges I've faced as a coder, a great example came to mind: Making divs equal height, regardless of the amount of content inside.

I haven't seen many elegant div-based solutions for that relatively simple (and common) task, so I've noticed that many people struggle with it. Often, developers will turn back to the "Dark Side" of using tables to format the content since all columns would have the same height as the tallest column by default:

JQuery Tutorial

It was easy theme table columns and to achieve the coveted 100% height that many designers seek, but emulating that functionality with divs proves to be much more difficult. A div is like the Superman of HTML elements (faster-loading, more flexible, more dynamic, etc.), and while it has super powers, it also has its own Kryptonite-like weaknesses ... The one relevant to this blog post being that floating three div elements next to each other isn't going to give you the look of a table:

JQuery Tutorial

Each of the three divs has its own height, so if you're doing something as simple as applying background colors, you're going to wind up with an aesthetically unpleasing result: It's going to look funky.

You could get into some nifty HTML/CSS workarounds, but many frustrated theme creators and designers will tell you that if your parent elements don't have a height of a 100%, you're just wasting coding lines. Some complex solutions create the illusion of all three divs being the same height (which is arguably better than setting fixed heights), but that complexity can be difficult to scale and repeat if you need to perform similar tasks throughout your site or your application. The easiest way to get the functionality you want and the simplicity you need: The jQuery equalHeights plugin!

With a few class declarations in your existing HTML, you get the results you want, and with equalHeights, you can also specify the minimum and maximum parameters so it will create scrollable divs if the tallest element happens to be higher than your specified maximum.

How to Use jQuery equalHeights

First and foremost, include your JQuery lirbraries in the <HEAD> of your document:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="jquery.equalheights.js"></script>

The equalHeights plugin is not a hosted library, so you have to host the file on your server (here's the link again).

With the required libraries called in our document, it's time to make the magic happen in your HTML.

Create Your Divs

<div class="divHeight">This DIV is medium sized, not too big and not too small, but just right.</div>
<div class="divHeight">This DIV has a lot of useful content and media that the user can interact with, thus it's very tall.</div>
<div class="divHeight">This DIV is tiny. Period.</div>

To have them line up next to each other, you'd have them float:left; in your CSS, and now you need to apply the equalHeights function.

Call the equalHeights Plugin
In order for the script to recognize the height of the tallest element, you'd need to call $(document).ready just before the </body> tag on your page. This will ensure that the page loads before the function runs.

The call looks like this:

<script type="text/javascript">$(document).ready(function() {
$(".divHeight").equalHeights();
});</script>

If you want to specify a minimum and maximum (i.e. The div should be at least this tall and should be no taller than [adds scrollbar if the div size exceeds] the maximum), just add the parameters:

<script type="text/javascript">$(document).ready(function() {
$(".divHeight").equalHeights(300, 600);
});</script>

The initial call does not change the appearance of the divs, but the time it takes to do the resizing is so miniscule that users will never notice. After that call is made and the height is returned, each div with the class of divHeight will inherit the the same height, and your divs will be nice and pretty:

JQuery Tutorial

This trick saved me a lot of headache and frustration, so hopefully it will do the same for you too!

-Cassandra

August 8, 2012

No iFrames! Dynamically Resize Divs with jQuery.

It's no secret that iframes are one of the most hated methods of web page layouts in the web development world — they are horrible for SEO, user experience and (usually) design. I was recently charged with creating a page that needed functionality similar to what iframes would normally provide, and I thought I'd share the non-iframe way I went about completing that project.

Before I get into the nitty-gritty of the project, I should probably unpack a few of the reasons why iframes are shunned. When a search engine indexes a page with iframes, each iframe is accurately recorded as a separate page — iframes embed the content of one we page inside of another, so it makes sense. Because each of those "pages" is represented in a single layout, if a user wanted to bookmark your site, they'd probably have a frustrating experience when they try to return to your site, only to find that they are sent directly to the content in one of the frames instead of seeing the entire layout. Most often, I see when when someone has a navigation bar in one frame and the main content in the other ... The user will bookmark the content frame, and when they return to the site, they have no way to navigate the pages. So what's a developer to do?

The project I was tasked with required the ability to resize only certain sections of a page, while asynchronously shrinking another section so that the entire page would always stay the same size, with only the two sections inside changing size.

Let's look at an example with two divs, side by side on a web page:

iFrame Tutorial

One div will contain a navigation menu to jump to different pages of the website (#sidebar), and the second div will contain all the content for that page (#content). If some of the elements in #sidebar are too long to read with the default width of the div, we want to let the user freely resize the two divs without changing the width of the page.

Our task is straightforward: When #sidebar expands in width, also expand the navigation and shrink #content along with the main content inside #content. If #sidebar shrinks, the navigation, #content and main content would respond accordingly as well:

iFrame Tutorial

It's a relatively easy concept to do with iFrames ... But then you remember that iframes are no longer cool (yes, there was a time long ago when iframes were cool). I decided to turn to my favorite alternative — jQuery — and the fix was actually a lot easier than I expected, and it worked beautifully. Let's run through a step-by-step tutorial.

1. HTML

Lay out your two divs:

<div id="sidebar"> 
<div class="sidebar-menu">
<!-- all your sidebar/navigational items go here -->
</div>
</div>
<div id="content">
<!-- all your main content goes here -->
</div>

2. CSS

Style your divs:

#sidebar {
       width: 49%;
}
#content {
width: 49%;
        float: left;
}

3. jQuery

Now that we have our two divs side by side, let's apply some jQuery magic. To do that, Let's include our jQuery files in the <HEAD> of our document:

<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>

Now that we have the necessary scripts, we can write our function:

<script type="text/javascript">
  $(document).ready(function() {
    $( "#sidebar" ).resizable({      
    });
    $("#sidebar ").bind("resize", function (event, ui) {
            var setWidth = $("#sidebar").width();
            $('#content).width(1224-setWidth);
            $('.menu).width(setWidth-6);
        });
  });
</script>

I know that might seem like an intimidating amount of information, so let's break it down:

   $( "#sidebar" ).resizable({      
   });

This portion simply makes the div with the ID of "sidebar" resizable (which accomplishes 33% of what we want it to do).

   $("#sidebar ").bind("resize", function (event, ui) {

By using the .bind, we are able to trigger other events when #sidebar is called.

            var setWidth = $("#sidebar").width();
            $('#content).width(1224-setWidth);

This is where the magic happens. We're grabbing the current width of #sidebar and subtracting it from the width you want your site to be. This code is what keeps your page stays the same width with only the divs changing sizes.

            $('.menu).width(setWidth-6);

This part of the code that expands the contents in the navigation along with #sidebar.

You can see a working example of iframe-like functionality with jQuery here: http://jqueryui.com/demos/resizable/

The only part you won't find there is the trick to adjust a corresponding div's size to make it grow/shrink with the first ... I had a heck of a time searching that on the web, so hopefully this quick tutorial will help other developers who might be searching for this kind of functionality!

- Cassandra

August 2, 2012

Meet Memcached: A Developer's Best Friend

Whether you're new to software development or you've been a coder since the punchcard days, at some point, you've probably come across horrendous performance problems with your website or scripts. From the most advanced users — creating scripts so complex that their databases flooded with complex JOINs — to the novice users — putting SQL calls in loops — database queries can be your worst nightmare as a developer. I hate to admit it, but I've experienced some these nightmares first-hand as a result of some less-than-optimal coding practices when writing some of my own scripts. Luckily, I've learned how to use memcached to make life a little easier.

What is Memcached?

Memcached is a free and open source distributed memory object caching system that allows the developer to store any sort of data in a temporary cache for later use, so they don't have to re-query it. By using memcached, a tremendous performance load can be decreased to almost nil. One of the most noteworthy features of the system is that it doesn't cache EVERYTHING on your site/script; it only caches data that is sure to be queried often. Originally developed in 2003 by Brad Fitzpatrick to improve the site performance of LiveJournal.com, memcached has grown tremendously in popularity, with some of the worlds biggest sites — Wikipedia, Flickr, Twitter, YouTube and Craigslist — taking advantage of the functionality.

How Do I Use Memcache?

After installing the memcached library on your server (available at http://memcached.org/), it's relatively simple to get started:

<?php
  // Set up connection to Memcached
  $memcache = new Memcached();
  $memcache->connect('host', 11211) or die("Could not connect");
 
  // Connect to database here
 
  // Check the cache for your query
  $key = md5("SELECT * FROM memcached_test WHERE id=1");
  $results = $memcache->get($key);
 
  // if the data exists in the cache, get it!
  if ($results) {
      echo $results['id'];
      echo 'Got it from the cache!';
  } else {
    // data didn't exist in the cache
    $query = "SELECT * FROM memcached_test WHERE id=1");
  $results = mysql_query($query);
  $row = mysql_fetch_array($results);
  print_r($row);
 
  // though we didn't find the data this time, cache it for next time!
  $memcache->set($key, $row, TRUE, 30); 
  // Stores the result of the query for 30 seconds
  echo 'In the cache now!';
 
  }
 
?>

Querying the cache is very similar to querying any table in your database, and if that data isn't cached, you'll run a database query to get the information you're looking for, and you can add that information to the cache for the next query. If another query for the data doesn't come within 30 seconds (or whatever window you specify), memcached will clear it from the cache, and the data will be pulled from the database.

So come on developers! Support memcached and faster load times! What other tools and tricks do you use to make your applications run more efficiently?

-Cassandra

July 26, 2012

Global IP Addresses - What Are They and How Do They Work?

SoftLayer recently released "Global IPs" to a good amount of internal fanfare, and I thought I'd share a little about it with the blog audience in case customers have questions about what Global IPs are and how they work. Simply put, Global IP addresses can be provisioned in any data center on the SoftLayer network and moved to another facility if necessary. You can point it to a server in Dallas, and if you need to perform maintenance on the server in Dallas, you can move the IP address to a server in Amsterdam to seamlessly (and almost immediately) transition your traffic. If you spin up and turn down workloads on cloud computing instances, you have the ability to maintain and a specific IP address when you completely turn down an environment, and you can quickly reprovision the IP on a new instance when you spin up the next workload.

How Do Global IPs Work?

The basics of how the Internet works are simple: Packets are sent between you and a server somewhere based on the location of the content you've requested. That location is pinpointed by an IP address that is assigned to a specific server or cloud. Often for various reasons, blocks of IP addresses are provisioned in one region or location, so Global IPs are a bit of a departure from the norm.

When you're sending/receiving packets, you might thing the packets "know" the exact physical destination as soon as they're directed to an IP address, but in practice, they don't have to ... The packets are forwarded along a path of devices with a general idea of where the exact location will be, but the primary concern of each device is to get the all packets to the next hop in the network path as quickly as possible by using default routes and routing tables. As an example, let's follow a packet as it comes from an external webserver and detail how it gets back to your machine:

  1. The external webserver sends the packet to a local switch.
  2. The switch passes it to a router.
  3. The packet traverses a number of network hops (other routers) and enters the Softlayer network at one of the backbone routers (BBR).
  4. The BBR looks at the IP destination and compares it to a table shared and updated with the other routers on SoftLayer's network, and it locates the subnet the IP belongs to.
  5. The BBR determines behind which distribution aggregate router (DAR) the IP is located, then it to the closest BBR to that DAR.
  6. The DAR gets the packet, looks at its own tables, and finds the front-end customer router (FCR) that the subnet lives on, and sends it there.
  7. The FCR routes the packet to the front-end customer switch (FCS) that has that IP mapped to the proper MAC address.
  8. The switch then delivers the packet through the proper switchport.
  9. Your server gets the packet from the FCS, and the kernel goes, "Oh yes, that IP on the public port, I'll accept this now."

All of those steps happen in an instant, and for you to be reading this blog, the packets carrying this content would have followed a similar pattern to the browser on your computer.

The process is slightly different when it comes to Global IP addresses. When a packet is destined for a Global IP, as soon as it gets onto the SoftLayer network (step 4 above), the routing process changes.

We allocate subnets of IP addresses specifically to the Global IP address pool, and we tell all the BBRs that these IPs are special. When you order a global IP, we peel off one of those IPs and add a static route to your chosen server's IP address, and then tell all the BBRs that route. Rather than the server's IP being an endpoint, the network is expecting your server to act as a router, and do something with the packet when it is received. I know that could sound a little confusing since we aren't really using the server as a router, so let's follow a packet to your Global IP (following the first three steps from above):

  1. The BBR notes that this IP belongs to one of the special Global IP address subnets, and matches the destination IP with the static route to the destination server you chose when you provisioned the Global IP.
  2. The BBR forwards the packet to the DAR, which then finds the FCR, then hands it off to the switch.
  3. The switch hands the packet to your server, and your server accepts it on the public interface like a regular secondary IP.
  4. Your server then essentially "routes" the packet to an IP address on itself.

Because the Global IP address can be moved to different servers in different locations, whenever you change the destination IP, the static route is updated in our routing table quickly. Because the change is happening exclusively on SoftLayer's infrastructure, you don't have to wait on other providers propagate the change. Think of updating your site's domain to a new IP address via DNS as an example: Even after you update your authoritative DNS servers, you have to wait for your users' DNS servers to recognize and update the new IP address. With Global IPs, the IP address would remain the same, and all users will follow the new path as soon as the routers update.

This initial release of Global IP addresses is just the tip of the iceberg when it comes to functionality. The product management and network engineering teams are getting customer feedback and creating roadmaps for the future of the product, so we'd love to hear your feedback and questions. If you want a little more in-depth information about installation and provisioning, check out the Global IP Addresses page on KnowledgeLayer.

-Jason

June 5, 2012

New SoftLayer.com Design: Build the Future

If you've been reading the SoftLayer Blog via an RSS feed or if you find yourself navigating directly to the portal to manage your SoftLayer account, you might not have noticed that the our main website has been updated again — and in dramatic fashion. Last fall we gave the site a slight refresh ... This time, we did a total rework.

We took the site in a new visual direction, with graphics and messaging to complement our mantra of customers using our platform to create their vision — to build the future.

SoftLayer Homepage

The new look — referred to as "SoftLayer at Night" by my fellow SoftLayer developer friend, Seth Thornberry — was designed to reflect our core identity, and it retires the faithful red, white and grey theme that has served us well for more than three years. The new style has received rave reviews from customers, partners and employees, and even if there has been some criticism — everyone has an opinion nowadays — we can generally chalk it up to people simply not liking change.

Highlights of the Redesign:

  • A dramatic new home page design, including visually rich "hero images" (where you see "The InnerLayer" heading if you're reading this on the SoftLayer Blog)
    SoftLayer Homepage Hero Image
  • Expanded main navigation menus at the top of each page
    SoftLayer Homepage Top Nav
  • A new lower-order navigation system on the left of all content pages
  • SoftLayer Homepage Side Nav

  • [For typographically inclined] The new design also leverages web fonts functionality to incorporate "Benton Sans," the corporate font used in print, interactive and other marketing communications.
    SoftLayer Homepage Side Nav

The new design was executed in-house, and our workflow was pretty traditional ... We like to roll up our sleeves. Page templates were created as PSD files and then hand-coded in HTML, PHP, JavaScript and CSS on top of the same framework we use for the SoftLayer Customer Portal.

During the development process, we used our new GIT code repository to facilitate the merging of all of our code onto our staging server. Since it was our first time to use GIT in a major way, there was a bit of a learning curve. The first few merges had to be reworked after finding a few errors in commit messages, but after we got a little practice, the subsequent merges went off without a hitch. The final staging merge was a breeze, and given the struggles we've had with SVN in past projects, this was a huge relief.

When it came time for the design's official launch, we ran into a hiccup related to our automatic regression testing system and problems with cached CSS files, but these issues were quickly resolved, and the new-look SoftLayer.com went live.

It took a lot of hard work from (and a lot of caffeine for) a number of people to get the new site out the door, so I'd like to make sure credit goes where it's due. Our lead designer Carlos ("Los") Ruiz did a majority of the design work, and the implementation of that design fell to Dennis Dolliver (Website Developer), Charles King (SEO Manager) and me. I should also send a shout-out to the entire marketing team who jumped in to help to proof content, test pages and keep everyone sane.

What do you think of the new design? Stay tuned for more website improvements and additions!

-Brad

May 30, 2012

What Does Automation Look Like?

Innovation. Automation. Innovation. Automation. Innovation. Automation. That's been our heartbeat since SoftLayer was born on May 5, 2005. The "Innovation" piece is usually the most visible component of that heartbeat while "Automation" usually hangs out behind the scenes (enabling the "Innovation"). When we launch a new product line like Object Storage, add new functionality to the SoftLayer API, announce a partnership with a service provider like RightScale, or simply receive and rack the latest and greatest server hardware from our vendors, our automated platform allows us to do it quickly and seamlessly. Because our platform is built to do exactly what it's supposed to without any manual intervention, it's easily overlooked.

But what if we wanted to show what automation actually looks like?

It seems like a silly question to ask. If our automated platform is powered by software built by the SoftLayer development team, there's no easy way to show what that automation looks like ... At least not directly. While the bits and bytes aren't easily visible, the operational results of automation are exceptionally photogenic. Let's take a look at a few examples of what automation enables to get an indirect view of what it actually looks like.

Example: A New Server Order

A customer orders a dedicated server. That customer wants a specific hardware configuration with a specific suite of software in a specific data center, and it needs to be delivered within four hours. What does that usually look like from an operations perspective?

SoftLayer Server Rack

If you want to watch those blinking lights for two or three hours, you'll have effectively watched a new server get provisioned at SoftLayer. When an order comes in, the automated provisioning system will find a server matching the order's hardware requirements in the requested data center facility, and the software will be installed before it is handed over to the the customer.

Example: Server Reboot or Operating System Reload

A customer needs to reboot a server or install a new operating system. Whether they want a soft reboot, a hard reboot with a full power cycle or a blank operating system install, the scene in the data center will look eerily familiar:

SoftLayer Server Rack

Gone are the days of server build technicians wheeling a terminal over to every server that needs work done. From thousands of miles away, a customer can remotely "unplug" his or her server via the rack's power strip, initiate a soft reboot or reinstall an operating system. But what if they want even more accessibility?

Example: What's on the Screen?

When remotely rebooting or power cycling a server isn't enough, a customer might want someone in the data center to wheel over to their server in the rack to look at any of the messages that can only be read with a monitor attached. This would generally happen behind the server, but for the sake of this example, we'll just watch the data center technician pass in front of the servers to get to the back:

SoftLayer Server Rack

Yeah, you probably could have seen that one coming.

Because KVM over IP is included on every server, physical carts carrying "keyboard, video and mouse" are few and far between. By automating customers' access to their server and providing as much virtual access as we possibly can, we're able to "get out of the way" of our technical users and only step in to help when that help is needed.

I could go on and on with examples of cloud computing upgrades and downgrades, provisioning a firewall or adding a load balancers, but I'll practice a little restraint. If you want the full effect, you can scroll up and watch the blinking lights a little while longer.

Automation looks like what you don't see. No humanoid robots or needlessly complex machines (that I know of) ... Just a data center humming along with some beautiful flashing server lights.

-Duke

P.S. If you want to be able to remotely bask in the glow of some blinking server lights, bookmark the larger-sized SoftLayer Rack animated gif ... You could even title the bookmark, "Check on the Servers."

Subscribe to development