Air Canada Just Stole My Heart

Lufthansa is probably my favorite airline in the world. I love them so much that when I found out they were on strike, I was more concerned about them finding a solution to their problem than mine.

My flight plan started with an Air Canada flight from Toronto to Montreal then Lufthansa to Lagos via Frankfurt. The strike meant I’d be stuck in Montreal if I took the first leg, so I doubled back to the Air Canada desk in Toronto to see what my options were.

It took a little while but the guy at the desk kept me in good spirits with his polite handling of the situation and the occasional joke.

So a guy walks into a grocery store and asks the cashier for half a lettuce. Confused by the request, he carries the lettuce to the back to ask his manager what to do. “Hey boss … some idiot out there wants to buy half of this lettuce”. He heard a gasp and turned around to realize the customer had followed him to the back. “And this gentleman would like to buy the other half”.

He managed to get me booked on an Air Canada flight to Istanbul, then Turkish Airlines to Lagos. All said and done, I’d be getting to Lagos five hours later than my initial flight plan. Awesome!

The Istanbul leg of the trip was pretty uneventful until I tried boarding the flight to Lagos.

I was pulled aside and told there was something wrong with my ticket and I need to go back to the Turkish Air customer care. When I finally found customer care, I was told it was a ticket office issue. I needed to backtrack to before passport control to find the right office to handle the matter. Missed my flight at this point.

Two hours in and nobody has told me exactly what is wrong with my ticket!

In my journey to find the Turkish Air ticket office, I passed by an Air Canada customer service desk and decided to take my chances there.

While he didn’t explain what was wrong with my ticket (maybe its a Turkish thing?), he arranged for me to get on the next flight to Lagos. Unfortunately the last flight for the day was already out, so Air Canada footed the bill for a night at Radisson Blu.

lobby_1440x550[1]

Air Canada paid for transportation to and from, dinner and breakfast as well as my flight home. I needed a visa to go into town for the night, and the Turkish Ground Services member assigned to me handled getting the visa and paying for it. Every detail was taken care of.

In this trip, Air Canada came through for me when my favorite airline let me down. They took over when the airline they handed me to dropped the ball. They were the Star Alliance partner that really came through for me today.

I’m currently in my hotel room typing this up. In the morning I’ll go down for a swim, have breakfast, stroll around Istanbul to take pics and get back to the lobby in time for a chauffeured ride back to the airport to catch my flight to Lagos.

What had all the makings of an unpleasant trip were smoothed away by the attention to detail and level of care afforded me by Air Canada. Would you believe that even through all the changes my bags didn’t get lost? They’re right here with me in the hotel room.

From now on, I don’t think I’ll plan a trip without finding out if I can take Air Canada instead. At least I can be rest assured they’d do their best to make sure I’m not stuck. If it’s unavoidable, I know I’d be comfortable the whole time.


Postscript
Is this love that I’m feeling? Looks like Air Canada is venturing into servicing African routes soon <3

Build Your Interfaces

layers of tech: hardware to ui

We are in the connected age. People halfway across the planet are only a few clicks away. Pluto, one of the furthest bodies in our solar system, is just as many clicks away.

It’s not enough that we are connected though. Every one of our devices must be too. Your phone, wristwatch and even your lightbulb want to connect with everything around.

A long time ago, you would have needed a deep understanding of every layer of technology and how they inter-operate to tinker, let alone build anything meaningful. These days, the hard parts have been taken care of and are presented as simplified APIs.

You don’t need to understand the intricacies of communication with Bluetooth. Your device probably provides access to the Bluetooth API, so you can harness it without needing to understand the lower levels of it.

With our devices containing more technology and the barriers to harnessing them getting lowered everyday, we have the unique privilege of being able to build our own interfaces for our devices.

I track my clothes to make it easier to simplify my wardrobe, and to guide my purchases.

I started by writing down dates and clothing combinations on an index card in the morning. Since my index card was unlined and my brain is pretty fuzzy early in the day, I occasionally had problems with incorrect dates or items not matching up. Eventually, I built a small Rails application (Quantified Awesome) to keep track of the clothes for me. Adding pictures made it easier to select the right item. Over time, I added little conveniences like the ability to display or sort by the last time I wore something.

Sacha Chua

With a little bit of training, we can harness the awesome power of the devices in our pockets and on our wrists. No longer constrained to interfaces the original programmers and engineers created, we can design how we want to interact with technology. With a little bit more effort, we can weave separate technology together and control them with a single interface.

A friend of mine needed to watermark images for her blog, so I built this interface for her.

I know little to nothing about how image manipulation works on a low-level, but it was trivial to stitch a provided API together with web technology to create an interface she could access from her phone or laptop. Select your pictures and they get automatically watermarked.

Don’t be limited by how technology is presented to you. Create your own interfaces. Shape your world.

 

Why Fashola’s Website Costs 78 Million Naira

Many Nigerians are upset at the news that Lagos State spent N78 Million to maintain a website for their governor.

I can see why many are confused and outraged, considering that blogs are hosted for free on WordPress.com, great dedicated servers cost roughly N2000 a month and a fraction of that budget would retain talented Nigerian staff members to keep the site up to date for his tenure as governor.

As a professional web developer and a Lagosian, it is my duty to help people understand why N78 million is not just a reasonable cost, but actually a bargain. At the end of this, I hope I’d have convinced you, not confused you, that Lagos state was financially prudent in this project.

Continue reading Why Fashola’s Website Costs 78 Million Naira

My First Accepted Pull Request

In the process of creating my first microservice, I used RabbitMQ to create a reliable job queue. I’d never used it before and it’s pretty complicated so I needed to find a library with a simple api for getting started with it.

The library I settled on is jackrabbit.

It has drop-dead simple api which hides the complexity of working with RabbitMQ. Perfect for the first-timer who doesn’t know the nuances of queuing strategies.

While I was monkeying around with it, I noticed my queue wasn’t actually queuing. Messages that don’t get immediately processed disappear without a trace. That sounds like the very opposite effect of what I decided to use RabbitMQ for in the first place!

After some sleuthing, it turned out jackrabbit sets messages to expire after a second, and there was no api access to configure it. You can’t increase the duration or remove it. One second messages and that’s that.

Coincidentally enough, jackrabbit’s maintainer exposed the api a few days later, so I didn’t need to switch to a more complex library.

Since the default was still one second and it seemed like quite a few people wanted their messages to hang around in their queues, I decided to update jackrabbit docs to show how it’s done.

And he accepted my updates!

https://github.com/hunterloftis/jackrabbit/pull/16

Officially my first contribution to someone else’s project. Sure it’s not functionality or a fix, but it’s better than nothing.

Can’t wait to make bigger and better contributions 🙂

My First Microservice

Last year I built a small app for a blogger friend of mine. It saved him the trouble of downloading a file just to rename it before uploading to the blog. He just supplied a new name, a link to the file, pushed a button and it was automagically done.

It saved him money because he didn’t to consume his data plan downloading the media files he needed to host for the blog.

It was also much faster than doing it manually. I tested it with a 500MB file and it was transferred in 19 seconds. No way he could have downloaded, renamed and uploaded that fast.

(There’s a video of it in action in this old post)

Not long after it was built, I started toying with the idea of setting it up as an app others can use. It took a few months to settle on core features and the architecture for public user but I’m finally happy with the details.

The original was architecturally a monolith. The http server, ftp client and socket.io server were all in the the same file. While it was fine for a single user or a team, it would have started showing signs of stress as soon as it was opened to the public. It needed to be decoupled.

In my defense they weren’t that tightly coupled together. I used an event system to keep each part independent while in the same file, so it was relatively easy to see a path from my monolith to a microservice.

I started by pulling the ftp server component out. It was an obvious first choice because that would be the most process-intensive component. Pulling it out would give me the most breathing room architecturally. I can pull the rest apart as they outgrow the monolith.

The first challenge was keeping all the separate components in sync.

As a monolith, the user’s request to push initiated a socket.io connection which communicated the progress of the push job.

Now that the ftp push is on its own server, it needs a way to communicate with all the components reliably. It needs to collect jobs from the http server and send progress updates to the socket.io server.

I moved the communication between components from an event system over to RabbitMQ and Redis.

FTP push requests are put on a RabbitMQ queue for the ftp server to pick up from. It provides a lot of assurances, like a request won’t be lost no matter what. If the server fails to push it, the request is put back on the queue. The queue is durable so it will persist even if RabbitMQ crashes.

It would be overkill to send progress updates over RabbitMQ, so I use Redis pub/sub to communicate updates to the socket.io server, which sends them to the client.

Of course the monolith needed to connect to Redis and RabbitMQ. That was trivial though, since using events isn’t dramatically different.

I’d learned my lesson about testing, so I needed to modularize the ftp server for testing.

I created an api that abstracted the ftp server’s abilities to receive jobs and send messages and exposed them to the test runner.

At this point, everything is feature complete in comparison to the original monolith, with the added benefit of the most intensive process isolated, independently scalable and tested!

I’m still a little ways away from releasing the app, but I’m really loving this microservice architecture so I’ll continue building new components in this pattern.

Fuck Pressure

I hate pressure.

I hate pressure so much that I do whatever it takes to avoid it, consequences be damned.

The pressure to have a really awesome personal site as a web developer kept me from ever making one.

The pressure to be the kinda guy that girls would wanna date kept me from appreciating myself, quirks and all.

The pressure to live up to people’s expectations kept me from thinking critically about what I was doing and if it really made sense to me.

Pressure inflates certain points and downplays others. It becomes so much harder to make clear-headed rational decisions when it matters most.

“Dude, you can’t get diamonds without pressure”

Fuck diamonds, fuck pressure and fuck you too.

You do have a point though.

Pressure pushes us accomplish things we would never have, under normal circumstances.

I’m not saying pressure is stupid or pointless. It’s definitely made me more aware of how much further out my real boundaries are.

Even when I fail to overcome it, I still learn valuable lessons.

After years of being overwhelmed by the pressure for an awesome site, I learned that waiting for things to be perfect isn’t worth it.

Conditions not being perfect don’t put me under pressure anymore.

I never became the guy I thought girls would want, but I learned that some girls like me for who I am, and it’s much better to be in a pressure-free relationship than to continually struggle to live up to arbitrary expectations.

When you overcome pressure, you expand your limits. When you cave to it, you learn about yourself. As frustrating as it is, it definitely has its benefits.

I guess the best way to summarize this is “fuck pressure but embrace it”.

What Does Success Look Like?

I’m in a Whatsapp group conversation with a few friends of mine. Our conversations typically revolve around hip-hop, decoding lyrics and proving how much more talented our favorite rappers are than everyone else’s favorites.

eminem-performs-in-france-650-430

Eminem is Alex’s favorite. He’s been rapping for many years, has a lot of awards, is critically acclaimed, earned the respect of his peers and is financially successful. He’s also succeeded in an industry that doesn’t have very many people who look like him. Totally understandable pick.

Kendrick-Lamar

Nivlek likes Kendrick Lamar and Lupe Fiasco. Both newer faces than Eminem. More importantly, supremely talented. Layers of cleverly laid references in their lyrics. Definitely not as financially successful as Eminem, but their wordplay is outstanding. They produce high-quality music.

DOOM

 

Me? I like MF DOOM. Crazy intriguing lyrics and overall very talented. Even produces and makes beats. His face is always hidden behind a giant metal mask. Financial success? Who knows. Most hip-hop fans don’t even know him. He’s that obscure.

I brought this up because after my conversations with Ire, I’ve been thinking a fair bit.

What does success look like to me?

Is it looking more like Kendrick? Overflowing with talent and a promising future in the limelight? Or do I want to be like MF DOOM? Completely out of the public’s eye, but those in need my skills know where to find me?

Do I wanna be like Eminem? Most of the world would never consider me successful if I don’t have an obvious pile of money. A nice big house. Great car. Very popular clients. Plenty of accolades. Funded by popular investors. A product that’s considered a unicorn (don’t ask .. it’s a nerd thing). Do I need the trappings of success to be a success?

Can I be more like Kendrick? I’d be the guy the Eminems of software engineering wanna work with because I’m oozing raw talent so they need me to build something amazing, special and really technically impressive that’d give them an edge? Is this what success looks like?

Or is it MF DOOM that speaks to me more? Unknown to the general public, but the person that Kendricks and Lupes of software engineering look up to me because I build things that help them be awesome. It’s probably not as financially rewarding, but do I need mountains of cash to be a success?

Why I Write

Had an interesting lunch with Ire today.

She writes about web development on bitsofcode, which is ridiculously popular. People have shared stuff she’s written on sites like Reddit, and some of her posts have gotten to the front page. Amazing!

In contrast, nobody reads what I write or uses what I’ve made. I’d come to believe that will change over time. Then I met Ire.

She started writing in March and already gets so many people reading her blog and using the things she’s made. She clearly knows a thing or two about making things people want. I asked her if I could buy her lunch, hoping I can pick her brain over the meal, and she agreed.

 

During our conversation, she asked me a few pointed questions. Answering them opened my eyes.

“Who is your audience? Who do you write for?”

“I write for myself.”

“Oh you mean people like you?”

“No .. I actually mean for myself. Once, I wrote a post with literally no objective. I let my mind wander and just wrote.”

Interesting. Why was I surprised nobody else reads my blog?

She writes to help others learn about building websites. She researches and puts together brilliant, concise pieces that help you understand a little bit more. An overwhelming majority of her posts contain information that is valuable to me, and I’ve been building sites for more than 5 years.

People find her posts useful and share it with others. Her traffic isn’t coincidental, really. She writes for others and the results are commensurate.

 

Even the things she’s made gets use.

“When I’m building, I make it really easy for people to initially use and customize. They can go deeper and tweak it more later on, but it needs to be super easy for them to use in the beginning.”

When I build outside work, it’s typically to an audience of one. Myself, or the friend who is going to end up using it. It usually requires modification for others to use it. Why am I surprised nobody uses stuff I’ve made? It requires an upfront commitment in the first place. Nobody has that kind of time.

Overall, it was a very enlightening conversation. I’m writing to an audience of one. I’m building for a user base of one. The results are commensurate.

Adim and I started blogging to start networking with developers in Nigeria. We felt isolated and wanted to get to meet our peers, connect with them and work on interesting things together.

To be honest, I’d also like for people to know what I do, what I’m capable of and want to work with me. That’s why I started writing more frequently, documenting my thought process as I work.

The trouble is I’m writing with no consideration for my target audience.

This is more like a public diary than anything else, at the moment. Nothing wrong with that, but it doesn’t address why I write.  If I want specific results, I need to do things that move me at least one step in that direction.

I need to take some time to write for others if I want them to read my writing. It needs to be packaged in a format that they can quickly glean the information, because apparently other people don’t like reading. I knew this, but since I love reading, never really optimized my posts for most people who don’t like reading.

Making sure things I make are easy for people to pick up and use with as little configuration as possible is super critical. Adim’s always talking about things “it just works” when we get into our Apple vs Android / Windows discussions. Build it so it works with the least amount of fuss and configuration. Make it so that it just works. I guess I’m starting to understand what he means.

I’m not going to stop writing for myself. I like doing these sorts of things. What I need to do is keep in consideration why I write.

On a regular schedule, package posts for others. When I’m extracting some code to form a library, make it as “drop in” as possible, with excellent default settings.

I write and build software for others to enjoy. It’s time I started ensuring the things I make reflect that.

Building on a Shaky Codebase

Yesterday I resolved to thoroughly test my current project before building any new features.

Figured the best place to start would be in a control flow library I wrote, which is used all over the API server. I use it to make complex processes manageable and readable.

upgrade-db-snippet

Comments are practically redundant because the name of each step explains what the snippet of code does.

I use the library all over the codebase, so it makes sense to thoroughly test it and proceed from there.

Imagine how humbled I was when it failed 20% of my tests.

test-stats

I may have gotten away with this for as long as I was the only person using it, but as soon as anyone else decided to use cjs-task, they had a 1 in 5 chance of having it fail them unexpectedly.

I’ve been building on a shaky codebase.

Time to pass all the tests. Then write some more.

Note to self: WRITE AUTOMATED TESTS, STUPID.

Test It Before You Wreck It

I have an embarrassing programming secret. Please don’t judge me harshly.

I don’t use automated tests.

tumblr_mlh11xjqSZ1rzcn8oo1_1280[1]

 

I’m not a complete moron. Whatever I’m currently working on is thoroughly tested manually before being committed in git. And I commit pretty frequently with descriptive commit messages. I also fork and merge religiously.

I haven’t really felt the need to set up automated tests. Not til yesterday.

THAT ONE TIME I WRECKED IT

I’m currently building an API server for a project. An offline-capable smart spreadsheet browser app.

Made some updates to the client and wired it up to the API endpoint to test the feature and the server came crashing down. My changes were to the client, which was in a separate repo, so I didn’t change anything on the server. Restarted the API server and tested it again. Crash and burn.

What went wrong?

A quick investigation pointed to when I renamed a few variables to make things more readable. I didn’t change every instance of a particular variable. Two slipped by me. I didn’t even realize there were two instances til I fixed one, pushed the change up and the server crashed again.

LESSON LEARNED

It’s supremely easy to make mistakes or not check as thoroughly as you think, which introduces bugs into you code.

Manual testing is okay, but you can’t count on it to catch every single problem. And every single problem matters in production. It’s the difference between a well-running app and steaming pile.

No more relying on myself to make sure everything is working properly. I’m writing a complete test suite for the server before I build any further.

From now on, I’ll test it so I don’t wreck it.