Great communication from @Assistly re: downtime

SaaS services are always going to have some downtime. What usually matters most to customers is the way the company responds to it.


Here's a great example from Assistly. Transparent, open, and humble.

---------- Forwarded message ----------
From: Brad Birnbaum <brad@notifications.assistly.com>
Date: Fri, Nov 11, 2011 at 11:34 AM
Subject: No Excuses

Dear Justin,

  I’m the CTO of Assistly. Over the past three days, and at least two other times during the previous weeks, Assistly has experienced lengthy service interruptions. This has undoubtedly interfered with your ability to deliver great service to your customers. I wanted you to hear from me directly, explaining what happened and what we are doing about it.
 
I assure you: When the system we’ve worked so hard to build causes pain for our customers, my whole team feels it. Your success is our success; nothing is more important to us. Getting Assistly running reliably for you is the highest priority for the entire company.
 
On Wednesday of this week, our search clusters started behaving erratically, which caused Assistly to be unresponsive to you. Assistly relies on the search engine to maintain real-time filter updates, search for cases, and to power the Help Center searches. In short: when search is down, Assistly is down. The complete details that caused the issue, and the specific steps we are taking to correct it, are here.
 
This is how seriously we are taking it:
 

  • We’re not making any excuses. This is simply unacceptable.
  • We’re working around the clock to resolve the problem.
  • We’ve escalated this to the highest ranks within Salesforce. They are the leader in cloud computing and they are pulling out all stops to help us stabilize the system.
  • We will be transparent as we work to a resolution.  Updates will be via  @AssistlyOps, on the  Assistly blog, and on http://status.assistly.com

We are experimenting with a real-time status board which you can visit at any time via http://status.assistly.com. While still in beta, we will continue to perfect the data that appears on this status board so that it becomes a reliable and instant source of information for you.

I hope that you will stick with us, as I am confident we will solve all of these problems. But more important to me is that you are able to serve your customers. If that means you need our help in making a transition, we will act as your partner and make it as smooth as possible.

There is no higher value than trust, and we have certainly been testing your trust in us. I know we have let you down.  I hope you will give us an opportunity to make this right and win back your confidence.

Please reach out to me directly if you have any questions or if I can help you with more information.

Sincerely,

Brad Birnbaum

CTO & Co-Founder
Assistly, a division of salesforce.com

 

 

 

 

Forbes. Boom.

Steve Jobs narrates The Crazy Ones

Retaining form data through a login process and resubmitting the form [Rails & Devise]

This is a feature I struggled with for quite awhile, so I thought I’d share my solution. The code is actually pretty simple once I got it figured out. Hopefully it will save somebody else some headaches.

So here’s what we’re doing

To create an easy on-boarding process, I’ve put a New List form on the front page of Favsi.com. However, creating a list requires the user to be authenticated, so I needed to create a way to retain the user’s New List form data through the authentication/registration process, and then post it. Here’s a screenshot of the front page:

Favsi Front Page Form

The flow would go like this

  1. User goes to the front page.
  2. User fills out the New List form and presses the Create List button.
  3. If the user is not logged in, they are prompted to login or register.
  4. User logs in/registers using standard authentication or using the Facebook/Twitter Connect flow.
  5. Once logged in/registered, the form data from Step 2 gets submitted and the user is redirected to view their published list.

After much Googling, StackOverflowing, and asking Portland Ruby folks there seemed to be 2 possible approaches:

  1. Once the form is submitted, carry the form data through the login process in hidden fields then submit it once logged in.
  2. Write the form data to the user’s session then retrieve and submit it once logged in.

Since Favsi offers Facebook and Twitter authentication (which routes the users off of Favsi.com) option 2 was the only choice.

So let’s get to the code (comments inline)

# lists_controller.rb
class ListsController < ApplicationController

# Make sure not to filter 'create' as we'll be handling that with our redirect
before_filter :authenticate_user!, :except => [:show, :index, :create]

...

def create

  # Check to see if the user is registered/logged in
  if current_user.nil?
     # Store the form data in the session so we can retrieve it after login
     session[:list] = params
     # Redirect the user to register/login
     redirect_to new_user_registration_path    

  else
    # If the user is already logged in, proceed as normal
    @list = current_user.lists.new(params[:list])
    respond_to do |format|
      if @list.save
        format.html { redirect_to(user_list_path(@list.user, @list), :notice => 'Sweet, your list has been created.') }
        format.xml  { render :xml => @list, :status => :created, :location => @list }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @list.errors, :status => :unprocessable_entity }
      end
    end
  end
end

Devise has a built in function for redirecting after the user logs in. We’ll be using this redirect to check if there is a temporary list saved in the session and, if so, save it as a new list.

# application_controller.rb
class ApplicationController < ActionController::Base

  def after_sign_in_path_for(resource)

    # Check to see if there is a temporary list saved in the session
    if session[:list].present?

      # Save the list
      @list = current_user.lists.create(session[:list]["list"])
      # Clear the temporary list in the session
      session[:list] = nil
      # Redirect to the list
      flash[:notice] = "Sweet, logged in. Nice list, btw :)"      
      user_list_path(@list.user, @list)

    else
      # If there is not a temp list in the session proceed as normal
      super
    end

  end

That’s it! Works like butter. You can test it on the front page of Favsi.

My latest project: Favsi.com. Check it out :)

Favsi-logo

I'm stoked to finally ship my first development project: http://favsi.com

If I haven't told you already, Favsi is a site to share lists of random stuff. Things you probably wouldn't post anywhere else. Like:

  • Favorite cheesy ninja movies
  • Favorite original NES games
  • Favorite songs to sing in the car

Here's a bit of background

By trade, I've been mostly a business guy *shudders* at startups, but have been working to change that for awhile now. I started learning Ruby a few times last year but had trouble sticking with it. It was tough to see how the stuff I was learning would turn into an actual product. 

Early this year, I decided to jump straight to learning Rails. That actually really helped. The more defined structure and near-instant results of getting *something* running were huge for me. Building that momentum helped me finally start to understand how fun (and addictive) development could be. Rails is a gateway drug.

Favsi is not a huge technical achievement, but it's been amazing for building my confidence to make stuff and dive deeper into programming.

Check it out: http://favsi.com

Cheers!

Justin

 

Chrome's awesome Task Manager & Browser Stats

I was just poking around and discovered that Chrome has a built in Task Manager to manage (or quit out of) tabs and extensions.

It's actually pretty awesome. I tend to get a bunch of open tabs....then my laptop fans kick on and everything starts running slow. It's great for figuring out which tabs are hogging resources (i.e. running Flash).

 

To use it:

Click the Wrench icon to the right side of the toolbar and choose 'View Background Pages':

Task-manager

 

The Task Mager shows you each tab you have open and the extensions that are running. It lists out the Memory, CPU, and Network usage for each:

Screen_shot_2011-07-18_at_12

 

Clicking the 'Stats for nerds' link at the bottom of the panel brings up an in-depth stats page:

Screen_shot_2011-07-18_at_12

If you're like me, you run multiple browsers at once. One cool thing is that it compares the amount of resources Chrome is using compared to Firefox and other browsers.

Pretty slick.

My Twitter Usage Infographic [via Visual.ly]

Google Wallet: Yet another thing to carry in your pocket

First off, Google Wallet sounds pretty awesome. I'm not trying to be a downer. #want

If you haven't seen it yet, basically Google wants to move your wallet onto your phone and smarten it up with near field communications, deals, loyalty cards, gift cards, etc. Pretty sweet, but...

Screen_shot_2011-05-26_at_10

The issue is that traditional merchants are really slow to adopt new technology. There are still tons of places that don't accept credit cards yet. Why don't these merchants adopt Square? The barrier to entry is almost nothing, but it still requires a conscious decision and opt-in from the merchant.

Google Wallet adds another form of payment that we need to carry: cash, credit cards, Google Wallet. You still need cash because it's the lowest common denominator, cards because they're more convenient and accepted 95% of the time, and Google Wallet because it's fun.

Develop a form of payment that's opt-out instead of opt-in and you'll be a bajillionaire.

The Sagan Series: The Frontier Is Everywhere

Why Hello I'm Justin Thiele

Check out this website I found at whyhello.im
Whyhello

Why Hello is an awesome service created by the Alex's. Similar to about.me. Check it out: http://whyhello.im/justinthiele