Archive

Archive for the ‘Uncategorized’ Category

Goodbye to Google+

03/20/2019 Comments off

Google+ is officially shutting down for consumers on 4/2/2019 and I have surprising feelings about it as a product and a codebase, having worked to re-write it in my time as an engineer at Google in 2014.

Screenshot 2019-03-11 14.45.21

“Looks like you’ve reached the end” – Indeed we have, G+

I’d never been an active G+ user and found the Circles concept confusing/clunky and the feature set too large.  I’ve always viewed Twitter as the ideal, time-based news feed.  When Polar as acquired by Google and we joined G+, we began an exciting project to overhaul G+ with product focus and a delightful newsfeed experience, mobile first.

Internally, we re-wrote a Java monolith using a new isomorphic (client/server-side) web component framework and micro-services.  We designed and built mobile-first creating fast, responsive experiences that worked on both small phones and desktop displays.  We built on the success of Google Photos to embed, analyze, and render content in the news feed beautifully.

Re-writing an application from scratch is generally not the right solution to your problems and often fraught with peril.  Our thesis was to make a faster, mobile first implementation using a new internal framework and simplify the product by cutting features.  Both of these were essential pre-requisites to executing a successful re-write.  We also had the infrastructure to build/validate our prototype and then migrate the application URL path-by-path from the legacy monolith into the new system. We let early-adopters beta test the new system.  This was a technical success, though not without toil and setbacks.

I’ll never forget the full, public launch in the small hours of the night when we ramped production traffic to 100% from the legacy to new version of G+ – only to have our backends overloaded and latency spike.  After 24 hours of urgent debugging, we found a browser toolbar sending high volumes of traffic from all over the world to load a formerly minimal page – just to scrape the unread post count for a user. In the re-write, this page contained an expensive fully rendered news-feed.  With the query cost for that page grown dramatically, the traffic overloaded our newsfeed backends.  We blocked the traffic and re-launched successfully.

Another time, we experienced a production outage when users were served up a blank, white page.  The feature flag/experiment system had a bug resulting in users being shown the HTML markup for one variant and the CSS for another – causing no visible content on the page.  Yet everything was working as far as our automation was concerned and it took manual bug reports to realize what had happened.

I will always remember the teams building G+ and the expertise, idealism, and excitement of the staff in the Social product area fondly.

I won’t miss Google+ in my life, but I am proud of what we built and how we built it.

Categories: Uncategorized

Mapping Rails 3.0 Commands

03/31/2012 Comments off

Rails 3.0 introduces ./script/rails

When Rails 3.0 was released, all of the individual command utilities (the Rails console, Rails generator, etc) were all consolidated into a single script:

./script/rails

That’s Annoying

Being used to typing “./script/console” for the last 4 years of my life, this is annoying. It’s a lot easier to tab complete within the ./script directory to the exact command you want and then fill in the arguments.

My Answer: rails_command_stubs

To solve this, I built a wrapper script you can drop in your Rails ./script directory. You can then symlink in commonly used commands and reference them directly and they pass through to the ./script/rails equivalent.

./script/console production
# Calls ./script/rails console production

Enter rails_command_stubs.

Categories: Uncategorized

Guerilla Scrum: Minimum Viable Process

04/13/2011 Comments off

TL;DR
You can start with the minimum viable process right now (Standups, a Backlog, and Demo/Retro). You can use this foundation to build a customized process framework that works for your team.

Frustrations with Heavy Process
The Software world seems split between process dogmatists and pragmatists. Dogmatists believe that the entire canon of Scrum practices must be enacted as a whole, or “you’re doing it wrong.”

I couldn’t disagree more – every process was designed to solve a problem in a particular context. This attitude runs rampant, and many teams chafe under the weight of heavy process. This post aims to enumerate the minimum viable scrum process.

Think Critically: A Process Should Solve a Problem
Any process or rule should solve a specific, measurable problem. Processes should exist to make your life better. You should know the problem(s) each process is intended to solve and answer:

  1. Is it working?
  2. Do you still need it?

Guerilla Scrum: Core Processes
I call these core Scrum processes Guerilla Scrum, the minimum viable process to get started and generate what you need:

  1. Daily Standups
  2. Single, Prioritized Backlog
  3. Fixed Iterations
  4. Demo & Retrospective

Read more…

Categories: Uncategorized Tags:

Passenger Resource Collision

01/06/2011 1 comment

Passenger and Smart Spawn Mode
Phusion Passenger has an intelligent application server worker pool based on Apache for hosting Rails apps. It uses a clever forking process spawner with Ruby Enterprise Edition to Pre-load your Rails application and environment in a parent process before forking off Child workers.

This allows you to load your application once for N workers, speeding up startup time and reducing memory usage dramatically with REE copy-on-write support.

Preventing Resource Collision
However, there is a hidden risk in forking children this way. Each child inherits an initialized Rails environment from the parent, which can cause resource duplication or collision. Passenger resets the database connection out of the box – each Rails worker has it’s own ActiveRecord connection pool.

However, other resources like Redis or Memcache are NOT reset or protected this way. When deploying a production scale application it’s essential to implement this. Otherwise, you could have each of 8+ workers on one server trying to re-use the same connection or file-handle.

PatientsLikeMe solution – Rails Initializer to Reset Resources

require 'passenger_safe_resource'

# Initialize Redis
PassengerSafeResource.load('redis') do
  env = ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
  redis_conf = YAML.load_file("config/redis.yml")[env]
  fail "No configuration for #{env}" unless redis_conf
  host, port, db = redis_conf.split(':')

  REDIS = Redis.new(:host => host, :port => port, :thread_safe => true, :db => db)
end

# Reset Vanity Redis Connection
PassengerSafeResource.load('vanity') do
  Vanity.playground.reconnect!
end

# Reset Memcached Connection
PassengerSafeResource.load('memcache') do
  PassengerSafeResource.reset_memcache(Rails.cache)
end

Helper to Manage Passenger events

module PassengerSafeResource
  # Helper to reset memcache connection
  def self.reset_memcache(cache)
    return unless cache.kind_of?(ActiveSupport::Cache::MemCacheStore)

    cache.instance_variable_get(:@data).reset
  end

  # Helper to load/reset a resource with Passenger
  def self.load(resource_name, &block)
    if defined?(PhusionPassenger)
      PhusionPassenger.on_event(:starting_worker_process) do |forked|
        if forked
          Rails.logger.info "PassengerSafeResource(#{resource_name}): Forking Child, loading in child"
          yield
        else
          Rails.logger.info "PassengerSafeResource(#{resource_name}): Non-Forking Spawn, NOOP"
        end
      end
    else
      Rails.logger.info "PassengerSafeResource(#{resource_name}): Non-Passenger mode, loading resource"
      yield
    end
  end
end
Categories: Uncategorized Tags:

Best of 2010 – Top 5 Books/Albums/Films

12/31/2010 1 comment

Books

  1. William Gibson – Zero History

    This book is the culmination of the trilogy of present-day futurist fiction from Gibson, a great adventure through the streets of London and Paris in search of underground fashion and conspiracy.

  2. Freedom – Jonathan Franzen


    This is the first novel to live up to The Corrections, beautiful writing, horribly true to life characters, and a gift for capturing the modern American situation. Deeply human and flawed characters grappling with building a life, being parents, and finding meaning despite the unintended choices that lead us to our lives.

  3. Although, of Course, You End Up Becoming Yourself – David Lipsky

    Less a book than a fairly raw presentation of a 48 hour road-trip/interview with David Foster Wallace, a solid meal for anyone interested in the world of writers, the life of DFW, or interesting conversations about making a life for yourself.

  4. Read more…

Categories: Uncategorized

Protecting Yourself from Firesheep Using an SSH Tunnel

12/13/2010 Comments off

What is Firesheep?
Firesheep is a recently released packet sniffer with built in side-jacking, that monitors insecure networks (usually open WiFi) for web application traffic, steals session information, and automatically impersonates your logged in session to many sites (Google, Facebook, Yahoo, etc).

SSH Tunneling/Proxy in OSX
The simplest way to protect yourself is to establish a secure VPN/tunnel for all of your web browsing to prevent sniffing of that traffic on the network. This moves the insecure traffic between the server and the web application and off of the local network your browsing.

If you have access to a Linux server with SSH, you can build a local SSH tunnel from a port on your machine out through the server to the internet. For those of you at PatientsLikeMe, dev2 is a great server to use for this. Below is an example SSH command to load a persistent SSH tunnel with a SOCKS proxy locally forwarding traffic over it.

ssh -D 8080 -f -C -q -N wpeterson@dev2.plm

Read more…

Categories: Uncategorized

MacBook Pro SSD Upgrade

12/05/2010 4 comments

I’ve been suffering with abysmal disk performance on my work laptop for some time, so I decided to pick up an OCZ Vertex2 SSD on sale over Black Friday and 8gigs of RAM. Total cost for both was under $300 (though the same from Apple would have been about $1200).

I wanted to get OSX re-installed, data migrated, and my development environment setup on my own time without wasting productive work time, so I did the following:

  • Installed SSD in USB enclosure
  • Installed OSX on SSD Drive as secondary
  • Migrated Data/Apps from old internal drive
  • Boot off of USB/SSD and finish config
  • Install SSD as primary drive

Everything went smoothly. Here’s the disk portion of a system XBench benchmark before/after:
XBench Disk Performance

Overall, about an 8x performance increase split between 4x for Sequential Read/Write and 28x for Random Access. The system boots up in about 15 seconds now. Applications load very quickly, Chrome with 10-12 saved tabs opens in about 1 second.

Categories: Uncategorized