Runtime Era

Tuesday, February 17, 2015

As a web developer, my workflow often includes writing a little code, firing up a local web server, and doing a quick smoke test to make sure things look alright. Occasionally, I'll encounter a situation where I'll need someone else (coworker, client, etc.) to provide some feedback on a design decision before moving forward. If I'm in the office, it's easy. I'll just call them over to take a look.

However, there are times when I need to share my local changes with someone remotely and get feedback quickly. If the change is relatively minor, deploying to some staging environment might be overkill. How can I expose my local web server publicly so my clients can view my changes and provide immediate feedback?

Enter, ngrok!

ngrok, creates a secure tunnel from a randomly-assigned, public internet address to a locally running web service. It also captures any traffic moving through the tunnel, allowing users to inspect HTTP request data. ngrok has several uses, and publicly exposing a local web server is one of them.

Installation

There really is no "installation" required. You simply visit the download page and follow the instructions. Since I'm an Ubuntu user, I downloaded the Linux .zip file, unzipped the binary, and began using it. Easy as pie!

Now, if we go to http://localhost:3000, we should see something resembling the following:

Sharing Our Local Web Server

To expose our local web server to anyone over the internet, we simply navigate to our ngrok binary and run the following:

$ ./ngrok 3000

The "3000" argument is the local port of our web server. If you are hosting something other than Rails, it may launch on a different port. In this case, simply replace "3000" with the port number of your web server.

Using the information provided above, we have our public web address: http://2779ffc7.ngrok.com. We can share this URL with our collaborators! Any visits to this URL will be tunneled to our local web server. As people visit the URL, ngrok will update by displaying any HTTP requests flowing through the tunnel:

HTTP Requests
-------------
GET /favicon.ico 200 OK
GET / 200 OK

Further Request Inspection with the Dashboard

ngrok provides a introspection dashboard which is hosted locally at http://localhost:4040/.

Since all HTTP traffic is captured by ngrok, more detailed information about each request can be explored on the dashboard. The dashboard updates in real-time. So, as people view your exposed website, the dashboard will update along with each request. You can explore request time, duration, headers, parameters, etc. It even pretty-prints JSON and XML responses to make them easier to read.

Conclusion

As more companies allow remote-working among their employees, collaborative tools utilizing the web will become more important. In the fast-paced world of web development, gathering feedback quickly is much easier because of tools like ngrok!

Friday, February 13, 2015

Back in 2011, I purchased a Thinkpad X220 to replace my aging Thinkpad T61. It's a great laptop, serving me well for just about four years now! Unfortunately, my screen recently began exhibiting the "vertical line" issue, which is basically a vertical strip of discoloration along a part of the screen. You can read more about this common issue on Thinkpad Forums, Notebook Review, or this Youtube video.

After four years without any major problems, my X220 was finally showing its age. However, it's really easy to replace the LCD panel on the X220 (or any Thinkpad for that matter)!

Tools required:

a small Philips screwdriver

a flat-head screwdriver(for prying)

Finding the Correct Replacement LCD

Lenovo provides a system service parts list document for most of their products. Each document contains a diagram of all the components and information about each part. This is part of the diagram from the X220 System Parts List:

Navigating through the diagram, I found the LED Premuim LCD Service Parts List. (Note: This is for X220s with the IPS screen option.) By clicking the LCD panel on the diagram, I was redirected to the following table:

The Product ID can be found on a sticker underneath the laptop, over to the left. Depending on the configuration of the laptop, this ID will vary.

Field Replaceable Unit (FRU) ID:

An FRU ID is a 7-digit number used to identity specific components in a system. Service technicians can use this number to easily find and ensure a direct replacement for a defective part.

Customer Replaceable Unit (CRU) ID:

A CRU ID is a single-digit number used to specify the difficulty level of replacing a component in a system for a customer. The following describes what each value means:

1 = easy to replace with little or no tools
2 = more difficult to replace
N = customer should not replace

My Product ID happens to be 4286-CTO. However, the table tells us it doesn't matter what the Product ID is. The FRU is the same for all of them! Using the FRU, 93P5675, it should be relatively easy to find a suitable replacement for my broken LCD panel!

Shopping for a Good LCD

There are several places online you can find decent replacement laptop components. I've only had experiences buying LCDs from two stores: Screen Country and East Coast LCDs. Both are really easy to use and have decent pricing. A quick search for the FRU on East Coast LCDs led me to the exact LCD panel I needed!

Remove the battery.

Using a flat-head screwdriver (or knife), gently pry off the screw covers on the front bezel of the LCD housing.

Using a Philips screwdriver, remove the screws holding the bezel in place.

With the aid of a flat-head screwdriver, gently pop the bezel off along the edges. The bottom is tricky. Be patient!

There are four screws holding the LCD panel to the housing. Remove these with a Philips screwdriver.

There are three more screws attaching the LCD panel to the hinges. Remove these with a Philips screwdriver.

Using a flat-head, gently lift the LCD panel up and off the housing, but not all the way off! It is still attached to the motherboard by the LCD cable.

Flip the LCD panel over to the backside and locate the LCD cable near the bottom.

There is a piece of tape securing the LCD cable to the panel. Gently remove the tape and slide the LCD cable down and out.

Voila! The LCD panel can now be fully removed from the LCD housing.

This is the new panel, packaged very securely by East Coast LCDs!

Now, just do the reverse! Reattach the LCD cable to the new LCD panel.

Before screwing everything back in, make sure things work. Looking good so far!

After screwing everything back in, remove the protective plastic left on the new LCD panel.

Good as new!

Conclusion

Thinkpads are really easy to modify and repair. In addition to replacing my broken screen, I ripped out the keyboard for cleaning and installed a new 128 GB solid-state drive. I have even more plans to upgrade the memory to 8 GB from 4 GB. My X220 has never been better and will, hopefully, continue to last a very long time!

Thursday, February 12, 2015

The Open/Closed Principle was first coined by Bertrand Meyer in his book Object Oriented Software Construction. Meyer states that the implementation of any class in a system should be changed only to correct errors. Any new features are introduced by creating additional classes that extend or modify the existing code.

Meyer's idea is more popularly described as follows:

"Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification."

Following this principle brings a major benefit. We are less likely to break the existing system's functionality if we minimize any changes to the original implementation. This increases stability, extensibility, and maintainability.

Open for Extension, Closed for Modification

Classes abiding by the Open/Closed Principle exhibit two important characteristics: they are open for extension and closed for modification.

A class is closed for modification when its internal implementation is hidden away. Its only interactions with the outside world are through a set of public methods known as its interface. All its internal logic is assumed to be correct. Therefore, it shouldn't need to change.

A class is open for extension if its behavior can be enhanced or modified by adding new code on top of the existing implementation. Classes must be designed in a way that lets consumers "plug in" or "inject" new logic.

Abstracting Behaviors

The main key in adhering to the Open/Closed Principle is proper abstraction of key behaviors. These behaviors are abstracted and encapsulated nicely behind a shared interface. By keeping classes dependent on these abstractions, new behaviors can easily be introduced without changing the existing code.

A Simple String Transformer

Suppose we need a simple application that transforms strings. Somewhere in our code, we have a service object called Transformer which takes a string and transforms it into a some other object:

Simple enough! We can transform strings into Ruby hashes. Now, a new feature requires us to transform strings into binary in addition to Ruby hashes. Let's add the new functionality to our Transformer class:

Great! Now we can pass in strings and specify the type of transformation to use. So far, so good. However, yet another new feature requires us to add support for yet another transformation: converting to MD5.

As you can see, our transformed_string method is starting to get quite ugly. It is also brittle, as we keep modifying the logic inside to accommodate new features! How can we make this class more open to extension?

Find and Extract the Abstraction

To make Transformer more open to extension, we need to make it depend on an abstract behavior rather than handling many different transformations. It seems like we keep on adding new types of transformations to our class, so let's abstract this behavior out!

The class looks the same. However, the application will now depend on Transform's sub-classes to implement the transformed_string behavior. Taking this approach, we can now create new types of transformations by adding new classes:

However, we've almost completely rewrote our existing implementation to make way for this solution. What about other classes in our application that depended on instances of Transformer? We would have to change class-names and signatures all over our application to accommodate our refactor.

Better Solution: Dependency Injection

Again, we want to extract and encapsulate the transformation behavior out and make Transform depend on an abstraction. We can achieve this by creating different Transformations and injecting them into Transform through its constructor:

This is a bit better, as the signature of our constructor hardly changes, but the implementation of Transform now depends on an abstraction known as Transformation. Any new (or existing) transformation behaviors can be added by creating new classes and injecting them into Transform!

Conclusion

This is a very simple example of how to design classes that are open for extension and closed for modification. It's important to remember to balance this principle against real-life requirements. If applied too soon, the Open/Closed Principle might lead to unnecessary abstractions, making code difficult to understand. Always take the simplest approach first. Then, if necessary, refactor code with the Open/Closed principle in mind.