Archive for the ‘Web’ Category

You’re on Watch Duty!

August 11, 2021
 by 

Watch Duty

The past ninety days have been some of the most exciting and challenging of my career. I am deeply moved by the generosity of my community, both in Silicon Valley and the Russian River Valley, that came together to create the first citizen driven disaster intelligence platform.

With almost no capital and only donations of human capital and services from companies like Zenput, Amazon Web Services, Heroku (a Salesforce Company), and Sixième Son, we went from a team with an idea to deployment to growth in one quarter.

As many of you know, I left my company a little less than one year ago to build my first non-profit, the Sherwood Forestry Service. It was founded with the belief that given the right environment and leadership with no money changing hands we can take idle human potential and make it dangerously kinetic.

Today, I am happy to announce that we have done just that with the public release of Watch Duty. Our application is piloted by skilled radio operators, firefighters, and citizen information officers who will provide up-to-the-minute information pushed directly to your phone. Citizens will also be able upload geotagged photos of what they’re seeing on the ground to help first responders and other citizens find danger. Our goal is to help discover and track wildfire hazards in real time without having to look for it. What we are creating will be the most actionable and accurate system of record for disaster intelligence built to date.

The Next Language Your Engineers Should Learn Is Product

June 25, 2014
 by 

This article was originally published in Forbes.

As a technical co-founder, the second most-asked question I receive (behind “where do I find a technical co-founder”) is from engineers asking me, “What language/framework/ new-hip-thing should I learn?”

This question has always puzzled me, especially when it comes from seasoned veterans who have well-respected jobs. Although my alma mater taught me this way as well, this is not the way I think — and neither should veteran engineers. Why would you want to learn yet another language, when that language is nothing more than a set of instructions that tell a machine how to behave? Any engineer worth his salt can pick up a new language in a matter of weeks. The same goes for a new framework. If you’ve been writing software for 10 years and you’re worried about the new hot framework out in the world, you’ve lost the forest for the trees.

The bigger question is, how do you take your knowledge of language and software systems to hack real-world systems? I look at this as a form of social engineering; instead of the goal being to teach a machine how to behave, you are attempting to create a machine that mimics the way humans behave. Or better yet, teach the machine to behave the way the user expects it to behave.

This is the difference between a good product and a great one, and it has nothing to do with software. Companies like Twitter had to change the way humans behaved. It was a long and arduous road, and people still don’t ‘get Twitter,’ whereas companies like Apple and Facebook have painstakingly studied human beings and purposely built products around their needs.

I can’t tell you the amount of times that I’ve come into an engineering meeting where one engineer is bragging to another that in five lines of beautifully succinct code they have been able to complete their task in record time with flawless execution. But I can count on one hand the number of times an engineer has bragged that they changed five lines of HTML and upped the engagement rate 10% on a feature that everyone perceived as useless. A hack is a hack, and that’s what engineers do. I don’t care if it took zero lines of code or a hundred and a roll of duct tape to complete the task, and guess what? Neither do your customers. The product is all that matters.

Both Facebook and Apple have taken this to extremes by hacking human perception. Facebook recently discovered that by changing their loading animation icon to what iOS and Android natively do, the user couldn’t tell if the slowness was coming from their phone, their carrier, or Facebook itself. This simple, genius hack saved so many man hours and millions of dollars of server time it’s hard to even quantify the impact. Apple has done something similar by creating a stripped progress bar that scrolls at just the right speed so you feel as though it is moving faster than it actually is.

These hackers were so perceptive and audacious that rather than engineer a faster application, they decided it was easier to change the users’ perception of time. All of this by changing very little code and no infrastructure.

But let’s get back to the engineer’s original question. I use my current team of three engineers to prove my point. When I began hiring back in May of 2013, not one of them knew our native language of Python, and the other two had barely written any JavaScript (which we have a lot of). Less than a year later, I now have three full-stack engineers who are capable of writing complex interactions on a JavaScript-heavy front-end stack all the way to organizing complex schemaless datasets. If I had attempted to hire three full-stack engineers out the gate, I would be lucky to end with one. Instead, I found three humans who are willing and able to think about the bigger system and realize that often, the best code is the code not written.

Next time you’re hiring an engineer, don’t just ask them the usual whiteboard questions and what they learned in college 10 years ago. Your job is to find out if they are willing and able to program the way users behave — or just program computers.

Stale cache serving strategy with reactive flush

November 27, 2011
 by 

This is a cache I have created that allows me to always serve the user cached data, i.e. never serving a miss. There are times when some data is just too complicated to make the user request thread wait and other times you just want to be sure you have high availability with no user facing recompute time at all. This is a great technique for template caches and API wrappers which I have employed more than once in my career.

I achieve the goal of no cache misses by first building what I call a persistent cache; memcache backed by disk or database. This way if memcache ever takes a miss I look in the database and pull the result from there. I then recache that result in memcache for a short amount of time and return the response to the user. At the same time, I then put a task on my task queue (MQ) to go recalculate the data and then update my persistent cache. If all caches are empty then I hit the API and upon success, cache the results and return the data to the user. If the API throws an error I put a task on the queue and hopefully the next time the user requests that data the cache will be warmed upon a successful API query.

Essentially this creates a type of MRU cache, only using memcache for frequently used data. I could use cron or something like it but I like that my users and bots are the ones who flush my caches based on demand rather than time or some other indicator.

Stale cache serving strategy
(click diagram for a larger version)

The diagram above describes how I built the caching for Klout Widget, a hack I created just to demonstrate this strategy. Their API was a little finicky so I decided to create a persistent cache that would be resilient to bad or missing data. Go ahead, give it a try.

Anyway, hope this strategy is useful. If anyone knows the name for this type of cache I’m all ears. As far as I know its something I dreamed up.

Selenium, Python, and Sauce

April 25, 2011
 by 

With a title like that most people are probably thinking I have some sort of strange fetish — but alas, my sickness is far geekier. I’m talking of course about User Acceptance Testing (UAT). Selenium, for those of you who are unaware, is an automated testing system that will run assertions against a web site. In our case, we use Python to invoke these browser commands but there are many other languages you can write them in.

Since there are many posts about this subject (sources listed at the end) I am not going to chronicle all the intricacies of the entire setup, rather some of the tricks I used and my experiences with it.

At Buyer’s Best Friend we are a Python shop. At first when I brought Selenium to the company I wrote them in HTML to demonstrate their effectiveness as tool to replace the lack of QA and speedup our release process. Once their power was demonstrated naturally I chose Python to keep one common language across our codebases.

This added a interesting challenge however. Since we use Python 2.5 we cannot run them concurrently. To overcome this we run our tests using 2.6 and added the nosetest framework. For a more detailed explanation, read Running Your Selenium Tests in parallel: Python on the Sauce Labs blog.

Although Nosetests are a great tool, it adds another level of abstraction on top of my homemade test harness which I had to throwout due to the introspective nature of Nosetests and the way it wanted to run. One of the main issues I came up with was configuration. I ultimately I made my own configuration which was called in the setUp() method of each test. In my case, my base test would call it and set the config object as a member variable on the test itself. Here is my config.py:

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
import ConfigParser
 
class Config():
  config = ConfigParser.ConfigParser()
  config.read("../config.cfg")
 
  if "config" not in config.sections(): 
    config = ConfigParser.RawConfigParser()
    config.add_section('config')
    config.set('config', 'host', '10.0.1.20')
    config.set('config', 'port', '4444')
    config.set('config', 'browser', 'iehta')
    config.set('config', 'target', 'my-test-server.com')
    config.add_section('sauce')
    config.set('sauce', 'enabled', 'true')
    config.set('sauce', 'browser-version', '8.')
    with open("../config.cfg", "wb") as configfile:
      config.write(configfile)
 
  # our member variables
  host = config.get('config', 'host')
  port = config.get('config', 'port')
  browser = config.get('config', 'browser')
  target = config.get('config', 'target')
 
  sauce_enabled = config.get('sauce', 'enabled')
  browser_version = config.get('sauce', 'browser-version')

As you can see from this configuration, I have two setups here. One more testing locally, or remotely against and instance or grid, or to run them on Sauce. More on that later.

On the grid

As you create more and more tests it becomes increasingly slow to run them on just one machine. Recently it was taking us 30 minutes to run our entire suite of 62 tests and counting. Enter the Selenium Grid. The grid allows you to run many machines or virtual machines and distribute your tests across a farm. Currently I run them across a laptop or two and I have been able to cut the total runtime nearly in half. Although thats good I know I can do better and deal with less configuration and hardware hassle.

Hitting the Sauce

Sauce Labs, founded by Selenium’s creator Jason Huggins, allows you to run your tests in the cloud. Not only that, they also give you an awesome dashboard, a video recording of each of your tests that run, and logging and diagnostic tools to make your tests run faster.

The configuration is brain-dead easy and only takes a matter of minutes to switch your current setup to a sauce setup. Sauce has a setup wizard to help guide you through the process but here’s the configuration I ended up going with. Below is my BaseTest class which extends unittest.TestCase. This ties in with the configuration I setup in the excerpt above.

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
def setUp(self):
  self.config = Config() # from config.py (see above excerpt)
  self.verificationErrors = []
 
  if self.config.sauce_enabled:
    sauce_config = {}
    sauce_config["username"] = "john"
    sauce_config["access-key"] = "xxx"
    sauce_config["os"] = "Windows 2003"
    sauce_config["browser"] = self.config.browser
    sauce_config["browser-version"] = 
      self.config.browser_version
    sauce_config["name"] = self._testMethodName
    self.selenium = 
      selenium('ondemand.saucelabs.com', 80, 
        json.dumps(sauce_config),
        "http://" + self.config.target)
  else:
    self.selenium = 
      selenium(self.config.host, self.config.port, 
        "*" + self.config.browser,
        "http://" + self.config.target)
 
  self.selenium.start()
  self.selenium.set_timeout(90000)

As you can see from the above excerpt, you just need to instantiate your selenium object with a different configuration and you’re running Selenium in the cloud. Now I have my tests running in less than 10 minutes running 4 concurrently.

Conclusion

Selenium is a wonderful tool that I have used many times on the job, this time extensively. It has not only caught more bugs than any other human in our company, it has sped up our release process, and also greatly added to our confidence level at every push. Soon we will most likely add it to our continuous integration to get even earlier warnings. In my mind, Selenium is the key to getting repeatable successful launches week after week — with or without a dedicated QA.

In regards to running your tests, Sauce’s Selenium Grid in the cloud has been a great experience and something I am going to continue to use. I have pushed two major releases using it and I have nothing but great things to say. If you’re considering Selenium, you better consider Sauce otherwise be prepared for more configuration and wiring. Running the grid on your own sure does work and I may try it for continuous integration but Sauce is sure making it hard to go back to running my own machines!

Sources:
Selenium Official Site
Nosetests – Python Unit Test Framework
“Running Selenium Test on Sauce Labs”, Matt Raible
“Running Your Selenium Tests in parallel: Python”, Santiago Suarez Ordoñez

Group text messaging weekend startup project

October 26, 2010
 by 

Its 2010 and there still isn’t an ad-free and non-paid way to have many-to-many text messages with a group of people! Almost a year ago I built a script in PHP that leveraged twitter as the middle man to solve this simple problem for my neighborhood buddies; essentially creating a mobile chat room. Just last weekend a few of my industry friends and I decided to sit down and productize the thing as an exersize. Two days, some pizza, and a bit of open source code we had Twitmob.com. Here’s how it works.

Simply create a Twitter account for your group, say @bffs_4_eva, and invite your friends to follow. Then when a follower tweets “@bbfs_4_eva happy hour!”, Twitmob will re-tweet the message. Now all of your other followers will see, “RT @a_follower: happy hour today!”. Once your friends turn on Twitter’s mobile updates for the group you can chat with them anywhere. No smart phone required!

Check out Twitmob.com to see how it works. Its quite simple and only takes a few minutes.

SanFranVic.com – Let the restoration begin

February 24, 2009
 by 

In true geek blogging obsession/narcissism, I have decided to blog the restoration of my 1890 San Francisco Victorian home at www.sanfranvic.com. Its going to be a long journey and I’ve decided to document it for my friends, family, and any future owner of the house.

It should be interesting to learn what goes into an old house like this one, where it came from, and where its going. Although I have a lot of experience engineering and building many many things, this is my first home restoration. So follow along with me, learn from my mistakes, and try not to yourself like I am going to. Enjoy!

Letter to the editor published in the Roundel

July 23, 2007
 by 

I recently wrote a letter to the editor of the Roundel Magazine, published by the BMW Car Club Of America, about my friend JP Cadoux at A1 Imports Autoworks in an effort to get the word out about what he does. I am kinda surprised they actually published considering I wrote in a serious manner but frustrated after reading silly articles about carbon fiber, xenon headlights, and other useless do-dads. Nevertheless, here it is.


article-about-jp-in-the-rou.gif

More press for A1 Imports

July 10, 2007
 by 

In an effort to the use social media to gain more publicity for the fantastic work that JP does we created this video and posted it on YouTube. Within the first day it recieved a few thousand views and was honored for two weeks on the site. It generated a lot of buzz on the Internet and was picked up by Jalopnik.com due to an anonymous tipster (myself). Here is a link to the post.

This site is complete! Plus 1 for the portfolio.

April 12, 2007
 by 

I have had so many sites over the years and Im really sick of it! I finally have one site that I am happy with, serves its purpose, and is easily updatable. Although I am mostly a Java engineer, PHP is where I came from. There’s a right tool for ever job and this site is no exception. WordPress is a great little app and suits its job well. It even loosely follows a pseudo type of tiles MVC system.


Just in case I get bored of the look I can always modify the view via CSS. Although this site doesnt validate due to WordPress, its strict XHTML. Although tables are great for tabular data and I still believe in them this site is a table-less design.

Copyright © 2005-2011 John Clarke Mills

Wordpress theme is open source and available on github.