VHX Dev Blog and Documentation

xxxxxx
menu
xxxxxx
0XXXXo         OXXXXKXXXX0       'KXXX00XXXXKd       ,0XXXXk
;0000O'       c0000O:0000O       ,0000d.x00000o     ;O0000o 
 cxxxxd      .xxxxx;.xxxxd       'xxxxl  :xxxxxo.  cxxxxx;  
  lllll;     cllll: .lllll       .llll:   .clllll;lllllc.   
  .:::::.   '::::;  .:::::.      .::::,     ,:::::::::'     
   .'''''   '''''.   ''''''''''''.''''.      .'''''''.      
    ;cccc:.ccccc,   .cccccccccc: .cccc;      ,ccccccc,      
    .OOOOOOOOOOk    .OOOOO.....  ,OOOOd    .kOOOOOOOOOx.    
     lKKKKKKKKK,    .KKKK0       ;KKKKk   cKKKKK0:kKKKK0,   
      OXXXXXXXo     .XXXXK       ;XXXXk .OXXXXXk.  lXXXXXd  
      .KXXXXXO      .XXXXK       ;XXXXO;KXXXXXl     'KXXXXO.
       lXXXXX,      .KXXXO       .XXXXXXXXXXXc       .0XXXX0

############# DEVELOPMENT BLOG & DOCUMENTATION ##############

Behind the Scenes with The VHX iOS App - UI Animation Magic Tutorial

by Gina Binetti @ 12/16/14

Hello! I wanted to share an animation flow I adopted while working on the UI in our brand spanking new VHX iOS app. In this tutorial, I’ll show you how I created the more complex custom animations sprinkled throughout the app.

For this demo, I'll be using the Welcome scripting from the login screen as an example. The animation is created as a Flash FLA and exported to an MOV, which is converted to a PNG sequence. Finally, the sequence is compiled into a sprite sheet and a property list for use with UIKit in Xcode.

VHX Welcome

I’m sure there are a number of ways this can be done, so I’d love to hear any #protips or thoughts. Ok here goes…

You’ll need the following software:

  • Adobe Flash
  • Adobe Media Encoder (or another application that converts .mov to a png sequence)
  • TexturePacker
  • Xcode

Step 1.

Using Adobe Flash, set up your animation however you like. To create a handwritten scripting effect for the Welcome graphic, a mask was drawn over several keyframes.

Tutorial Image 1 - Flash set up

Step 2.

Select File > Export > Export Video… to create an MOV of your animation.

Tutorial Image 2 - Flash exporting menu

In the dialog box, make sure to check “Ignore stage color (generate alpha channel)” to retain transparency for the PNG sequence. If you’ll be using Adobe Media Encoder, check that box too. If you have scripted animation, then set an appropriate amount of time for the animation to be recorded, otherwise just select “When last frame is reached” as the last exporting option.

Tutorial Image 3 - Flash export settings

Step 3.

Open the .mov file in Adobe Media Encoder, and update the Export Settings to the following before exporting:

Format : PNG

Check - Export as Sequence

Frame Rate : 24

Check - Render at Maximum Depth

Check - Include Alpha Channel

(!) Be sure to change the Width and Height to match the dimensions of your Flash movie. You should also make sure the Output Name ends with “00.png”. This is so your sprite sheet can follow the format “0000”, “0001”, and so on, as you will see later.

Tutorial Image 4 - Adobe Media Encoder Export Settings

Step 4.

Open up TexturePacker and select UIKit (Plist) as the framework for the new project.

Tutorial Image 5 - Texture Packer Startup Dialogue

In the new project, drag your PNG sequence folder into the left pane labeled “Sprites”. Select Publish sprite sheet in the top nav. This will create a .png sprite sheet and an accompanying .plist file with the coordinates.

Tutorial Image 6 - Texture Packer Settings

Step 5.

Open up your Xcode project and drag the newly created .png and .plist into your Supporting Files folder in the Project Navigator area. The TexturePacker classes will be looking for the "@2x” extension for retina display devices so be sure to add this suffix to both files or expect a crash.

Tutorial Image 7 - Xcode folders

Drag the TexturePacker class files from CodeAndWeb into your project.

Tutorial Image 8 - Xcode class files

Step 6.

Write the actual code that makes it do stuff! The Welcome animation was added to a custom subclass of UIViewController.

Add the import statements for the TexturePacker classes:

#import "CAWSpriteReader.h"
#import "CAWSpriteLayer.h"

Add a CAWSpriteLayer property to your class interface:

@property (strong, nonatomic) CAWSpriteLayer *animationLayer;

In the viewDidLoad method:

NSDictionary *spriteData = [CAWSpriteReader spritesWithContentOfFile:@"welcomeAnimFinal.plist"];
UIImage *texture = [UIImage imageNamed:@"welcomeAnimFinal.png"];
animationLayer = [CAWSpriteLayer layerWithSpriteData:spriteData andImage:texture];
[_viewLogoLockup.layer addSublayer:animationLayer]; //add the layer to any UIView layer
[animationLayer setShowLastFrame:true];
[animationLayer setPosition:CGPointMake(74.3, 115)]; //your position will vary

Then later in viewDidAppear, the animation is kicked off with this line:

[animationLayer playAnimation:@"welcomeAnim%04d" withRate:40];

You can play with the frame rate as it suits your animation. Be sure that the name you use here matches the name of the items in your .plist (before the numbers) or this will fail. The “%04d” refers to the 4 integers that represent the numbered identity of each sprite.

Step 7.

Build and celebrate!

Animating Welcome

Meet Gina Binetti

by Gina Binetti @ 10/24/14

Gina

Gina is a front-end developer at VHX, specializing in iOS and Flash, with a penchant for spiritual advising and Victorian illustration. Born and raised in the spaghetti-laden streets of NJ, she now resides in the pierogi-laden streets of Brooklyn with her hypoallergenic Siberian Forest cat named Princess Vespa.

How did you get into programming?

As an introverted, geeky high school student in the glory days of grunge and MTV reality, I took to computers like a dread-locked white guy at a Phish concert, but I didn’t know there was such a thing as programming until midway through my zoological studies at college. In transferring schools, I’d been required to take a Visual Basic class and I distinctly remember the absolute delight in writing simple conditional statements and immediately becoming the teacher’s pet in a sea of mostly math-intolerant design students forced to fulfill a curriculum.

Soon after, I picked up HTML, CSS, and JavaScript and became a “web designer,” as back in days of yore, there was no such dichotomy between a designer and developer (hence, the web looked like bile). But my love affair with programming was not solidified until the discovery of a format that married art and science beautifully: Flash. This love would later come to be the object of derision for all the Internet, (not in small part due to an infamous letter by Steve Jobs), but for at least a decade, Flash was an absolutely wonderful, artistic, technical playground that made me a bona fide object-oriented programmer. From my early days as a creatively technical jackie-of-all-trades, my focus became programming in ActionScript 3, with a concentration in game development, and leading big projects for several advertising firms.

What are you working on now?

With Flash making a graceful exit, I wanted to shift gears and make games and apps for mobile devices and landed at VHX a year ago with the intention of building a VHX iOS app. Learning iPhone development has been super challenging, but it's been very rewarding to watch the app come to life in collaboration with developer James Dennis and our designer Michael Eades. It's also really interesting how my Flash skills have played a significant role in my ability to understand and polish the UI. I intend to write a future article on my process of creating fine-tuned animations for XCode using Flash and TexturePacker.

What is something you discovered recently that you really liked?

On the iOS front, I've been using a program called PaintCode for about a month now that has been indispensable in my workflow for making vector assets. Previously I had been using an Illustrator extension called Drawscript, but found it had difficulty with many shapes and could not work with compound paths. With PaintCode, I can import any shape as an SVG and have a complete output of Objective-C with live editing.

I've also discovered this organic coconut oil and Himalayan pink sea salt popcorn that is, as they say, off the hook.

What's a great movie you've seen recently?

I found the Nick Cave documentary, 20,000 Days on Earth at the Film Forum to be pretty inspiring. Many great quotes on the creative process and death, to which I can relate as a dabbler in songwriting. I was also deeply affected by Richard Linklater's extraordinary film, Boyhood. Most recently, we had a movie night here at VHX and watched Harmontown. Though I wasn't terribly familiar with Dan Harmon's podcast, I left with the warm solace of knowing there are so many hopeful freaks and geeks out there.

Foundation And Building A Responsive Front-End

by Scott Robertson & Steven Bone @ 08/26/14

As our codebase grew, adding new features was getting increasingly difficult. Implementation of design elements became less cohesive. Each page was treated inconsistently with the next, leaving a less than optimal user experience. We wanted a way to help combat this pattern. With a new design and styleguide for our application, it was the perfect time to establish a more modular approach.

Instead of trying to build our own front-end framework entirely from scratch, we decided to evaluate popular options out there and see what made sense for our purposes.

Our Criteria

We came up with a few things we knew we needed in a framework:

  • Design agnostic
  • A flexible grid
  • Responsive built-in
  • Utility classes (for common styling patterns)
  • Conventions for common component implementations (buttons, headers, forms)

Candidates

One major caveat with using a framework is having to fight with design assumptions and overriding much of what a framework provides. We knew this could not be avoided completely, but we wanted something that was as design agnostic as possible and that could help us establish conventions for writing our own modules.

Our initial list of candidates included:

We had reservations for overly complex or overly simple frameworks. We knew we wanted something that was well tested and actively developed. Several of the above options could have worked out just fine, but really what swayed us were a few standout features that we found particular useful.

Foundation

In the end, we decided to go with Foundation. We chose Foundation primarily because of their grid system. It was clever in design and gave us the simplicity, flexibility, and readability we wanted. Let's take a quick look at how it works.

Grid System

Every column in a grid can be set to a certain width based on screen size using Foundation's small, medium, large, x-large size denominations:

<div class="row">
  <div class="small-8 medium-10 large-12"></div>
  <div class="small-8 medium-6 large-4"></div>
</div>

With the above we're using a 16 column grid, so each row must add up to 16. On small screen sizes (think mobile phone) the columns would be 8/16 (classes small-8 and small-8). On a medium screen size (think tablet) the first column is 10/16 (class medium-10) and the other 6/16 (class medium-6) and so on. See the image below (showing only small and large screen sizes).

Foundation Grid

But there is more! Say you want a centered container on large screens that is only 8 columns.

<div class="row">
  <div class="small-16 medium-16 large-8 large-centered"></div>
</div>

Foundation Grid

Even further, Foundation gives you offset and end classes that allow for more flexibility.

<div class="row">
  <div class="small-8 medium-10 large-offset-2 large-5"></div>
  <div class="small-8 medium-6 large-4 end"></div>
</div>

Foundation Grid

These examples are just the tip of the iceberg for some of the useful things you can do with Foundation's grid system. You can read more about it here.

More from Foundation

As much as we were won over by Foundation's grid system, we discovered many more useful tools along the way.

Utility & Visibility Classes

Foundation has utility and visiblity classes that proved essential when coupled with their grid system for building a large responsive application.

Utilities include alignment classes like text-center, text-left, and text-right for positioning column content. In responsive Foundation fashion these could be prepended with small, medium, large, etc. to target a specific device/screen size.

Visibility classes like show-for-small-only, hide-for-small-only, and show-for-medium-up, etc. made it easy to hide or show content depending on the screen size.

Foundation's classes were a great starting point, but we didn't solely rely on what was provided. It served as a catalyst to many other utility classes that we added for our specific needs, including classes for spacing, borders, backgrounds, tables, forms, etc. All of which provided a solid base for building out our various modules and pages.

You can read more about Foundation's utility classes and visibility classes in their official documentation.

Class naming

In going all in with Foundation, we adopted their convention of having a base class for a particular style or module and then used additional classes to extend that style. This allowed us to maintain greater consistency. Here's an example of a Foundation button element:

<a href="#" class="button">Button</a>
<a href="#" class="button radius alert">Alert Button (Rounded corners)</article>

Here's an example of one our own custom modules for element agnostic headers:

<h1 class="head primary">Primary Heading</h1>
<h1 class="head primary alt">Primary Heading w/ Alternate Font</h1>

<h1 class="head secondary">Secondary Heading</h1>
<h1 class="head secondary inverse">Secondary Heading w/ Inverse Color</h1>

<h1 class="head alt">Head Alt</h1>

Using this approach allowed us to easily create a typography system based on the designs that looked like this:

Foundation Grid

Handy Javascript utilities

Foundation also has a nice collection of utilities such as throttle and debounce, which we merged into our own Utils object as show below:

Foundation.inherit(VHX.Utils, 'random_str data_options throttle debounce image_loaded random_str');

Handy Javascript plugins

Most of our Javascript was custom written, but we made use of any Foundation plugins we could, including their Modal Reveal and Equalizer plugins.

Foundation Implementation

We first installed Foundation by using their Ruby Gem. In order to have greater control of the ordering of files and to continue to make use of Rails' built in asset pipeline we setup a Foundation include file (named foundation_include.sass) that looked like this:

@import "settings";
@import "foundation";

We imported a settings SASS file with all the customizable Foundation settings and foundation the framework itself.

Each primary section of our site would have a core manifest where we'd include our Foundation include file, other core SASS files, section SASS files, and any shared SASS modules. It looked something like this:

# --- core ---
*= require normalize
*= require ./_core/foundation_include
*= require ./_core/extensions

# --- admin ---
*= require_directory ./admin/_shared

# --- share ---
*= require ./_shared/buttons/buttons
*= require ./_shared/buttons/buttons.line

Conclusion

Foundation was initially created for designers to rapidly prototype, as was evident in its design. This philosophy fit well with our needs, and we have been very pleased with using it.

The only slight tradeoff was having to overwrite a lot of their styles to get the look and feel that we wanted. A majority of our modules and CSS class utilities are custom and in many cases we had to use the dreaded !important to ensure our styles overrode Foundation's. We knew however, that this might be unavoidable to get our specific aesthetic.

In the end, we have been very pleased with the usefulness and efficiency Foundation provided us and would gladly recommend it to anyone else looking to try out a front-end framework.

SVG Spriting with Grunt

by Steven Bone @ 08/21/14

Easy SVG sprites with grunt

The past few months we've been designing and building our own icon system, and implementing it with SVG.

The two most popular approaches both use inline SVG, either in your HTML markup or via CSS classes. We chose to use CSS classes, but sometimes inline SVG HTML in a pinch (more on that later).

Getting Started

All our design assets are in Adobe Illustrator. Each icon is its own Artboard allowing you to easily save each one as its own SVG file. VHX is built on Rails, and we currently rely on the Asset Pipeline and Compass. Compass is great for spriting with PNGs, but it doesn't currently support SVG. (There's a long standing issue in Compass' Github project.)

We'd been wanting to use the JS-based task runner, Grunt, and this was a perfect chance to get started. Chris Coyier's post on CSS-Tricks is a handy reference for this.

Why Grunt?

Grunt is written in Javascript.

Grunt is great for frontend developers. We use Grunt as an asset builder - JS better empowers us to iterate fast, experiment, and refine this process.

Grunt is fast.

Because Grunt handles asset-related tasks exclusively, it's been really speedy. Very important while you're tinkering.

Grunt is portable.

Compared to refining a workflow within the Asset Pipeline, migrating Grunt setups between different apps and frameworks is just a matter of changing file paths.

Implementation

After creating a folder called SVG in our app that stores all our our icons from Illustrator, we use Grunt tasks for the heavy lifting:

  1. file-regex-rename to normalize SVG names
  2. svgmin cleans and minifies the SVGs
  3. grunticon to build the line CSS-inline sprite
  4. copy to create a file of silent classes for @extend usage throughout your app (optional)
  5. svgstore for creating an HTML-inline sprite (optional)

Why are steps 4 and 5 optional?

copy is only needed if you want to use SASS @extends for icons within your CSS, outside of the classnames generated by grunticon. We have it configured to create a duplicate of grunticon's SVG stylesheet, replacing each class' leading . with %. Otherwise, using @import at the top of every SASS file in your app will create hundreds of duplicate lines of CSS.

svgstore is specifically for creating a HTML-inline SVG sprite. Now why would you want one of those?

CSS versus HTML-inlining of SVG

At it's core, the main differentiators of these two approaches are:

  • Inline HTML allows you to leverage common CSS or JS behaviors to change the color of the icon (e.g., on mouse :hover, make the icon a different color).
  • If you design icons with more than one color in it, you will have to use CSS-inline.

Caveats

  • CSS-inline: Your SVG is a background-image, and you can't modify it with CSS or JS. The best we've done is use @extend to use a different colored version (generated by grunticon). You can't add CSS transitions to this.
  • HTML-inline: You cannot target individual paths of an SVG, making multi-colored icons a bit of a bust.

Moving Ahead

One of our icons in multiple colors and sizes, all generated from a single SVG file with Grunt:

Example of rendered SVG output

An icon using HTML inline SVG, with a CSS transition on :hover:

Example of rendered SVG output

Once you have this setup for your app, managing your icons will be a breeze. We're liking this Grunt-based workflow a lot, and are planning to migrate away from the Asset Pipeline entirely for it. Follow-up post once that happens!

Film Personality

by Forest Conner @ 08/05/14

As the resident data scientist, I get to do a lot of interesting things, mostly centered around understanding how to make our platform better for our publishers and their customers. But for our last hack day, I was looking for a way to better understand the content itself. Enter Film Personality.

Film Personality

The ideas stems from something in Brand Strategy called "brand personality," which postulates that there are five major dimensions of personality: Excitement, Sincerity, Competence, Sophistication, and Ruggedness.

Sounds a little hokey, no? While reducing all human traits into five dimensions isn't a great way to describe people, I thought it might serve as a better shorthand for discussing films than the current standard of genre, where the description "Drama" could apply to almost anything (so long as no one is enjoying themselves.)

There are a few key elements needed for putting this together: A common language used to describe films, enough people using this common language, and the ability to quickly parse their conversations to extract the key descriptive words. I found it useful to consider critics' reviews as that source of common language. They say similar things about similar types of films, even if they disagree on the quality of the film. The use of words like "exciting," "intelligent," and "imaginative" are still used, even if the critic then follows it up by saying, "but I still hated this movie."

I figured the simplest way to test this out was to use the Rotten Tomatoes API to pull in reviews for a given film and parse those using the lovely Python package Natural Language Toolkit, or NLTK. I'll walk you through a bit of the code, which turned out to be surprisingly simple for an MVP:

def getMovieID(title):
    url_title = title
    #Form Title For URL
    if " " in url_title:
        parts = url_title.split(" ")
        url_title = "+".join(parts)

    #Call to API
    link = "http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=%s&q=%s"
    url = link % (api_key, url_title)
    res = requests.get(url)
    js = simplejson.loads(res.content)

    #Find Movie ID
    movie_id = 0
    movie_title = ""
    for movie in js["movies"]:
        if title.lower() == movie["title"].lower():
            movie_id = movie["id"]
            movie_title = movie["title"]
            break

    return (movie_id, movie_title)

The first API call to Rotten Tomatoes returns the JSON of the movie the user requested, based on matching title. It's dependent on two things: 1) the Rotten Tomatoes search, and 2) that the user actually spells the film title correctly. Once we have the movie ID, we call the API again to get the reviews.

def getMovieReviews(movie_id):
    url = "http://api.rottentomatoes.com/api/public/v1.0/movies/%s/reviews.json?apikey=%s&review_type=all&page_limit=50"
    res = requests.get(url % (movie_id, api_key))

    data = res.content

    js = simplejson.loads(data)

    all_reviews = []
    reviews = js["reviews"]
    for review in reviews:
        all_reviews.append(review["quote"])

    return all_reviews

Once we get the JSON containing the review snippets, we need to tokenize the parts of speech using NLTK. This returns a list of tuples, each containing an individual word paired with an identifier ('NN' for nouns, 'VB' for verb, etc.) The parts of speech that will be most descriptive of the film's personality are verbs in the gerund form, that is ending in "-ing," and adjectives.

def tokenizeReviews(reviews):
    tagged_words = []

    for review in reviews:
        tagged_words = tagged_words + nltk.pos_tag(nltk.word_tokenize(review))

    return tagged_words

def findAdjVb(tokens):
    verbs_gerund = []
    adjectives = []
    nouns = []

    for token in tokens:
        if token[1] == 'JJ':
            adjectives.append(token[0])
        elif token[1] == 'VBG':
            verbs_gerund.append(token[0])

    return verbs_gerund + adjectives

In order to associate these words with the film dimensions we defined earlier, I created a small dictionary including some seed words and added synonyms from NTLK's Wordnet synonym set. I also removed the words "good" and "bad" because that's, like, your opinion, man.

Film Personality Output

What we get when we run all this madness is a list of descriptive words from the reviews, and a score for each of the five dimensions. While this is currently nothing more than a proof of concept, it shows that we can mine this data for specific words, link those words to personality dimensions, and that this dimensions actually align with our conceptions of the films that are input.

There are definitely areas for improvement. The dictionary needs to be much larger to account for more words, and I would love to bring in full reviews rather than just the snippets from Rotten Tomatoes. Hopefully these iterations will show that there is a better way to define films, and that perhaps film personality is it.

Forest Conner is a Data Scientist at VHX and is also a research fellow at the Cinema Research Institue, studying the interaction between film and technology.

Hack Day 0002

by Casey Pugh @ 06/19/14

We had another great hack day recently. Such hacks. To help get our creative juices flowing, we had three special guests stop by the office, all with amazingly successful Kickstarter projects. James George of CLOUDS, Alex Hague of Monikers, and John Yost of White Creek.

Here's the recap:

Michael and I built a page that allows publishers to easily customize their embeds. Customizable Package Embed

Forest made an internal utility that allows us to have more flexibility when it comes to analyizing all our data VHX's data tools

Steven added some magic to the tab of our video page that allows you to see at a glance if a video is playing. Play button favicon

Gina and Charlie massively upgraded our video player to support thumbnail scrubbing. Thumbnail scrubbing

Sagar and Chris built a more robust monitoring system using Librato so we have better and more immediate insights into our platform. A cool Librato graph

Alex stole the entire team's baby photos and framed them for the office. The Ultimate Hack. VHX Babies

Chad reenvisioned what a 10-foot, internal dashboard could look like. It allows us to at a glance to see how we're doing day to day. Dashboard 1 Dashboard 2 Dashboard 3

Fueled by our inspiration of CLOUDS, James, Charlie, and I helped James George test the possibility of integrating CLOUDS directly with VHX. CLOUDS is basically an interactive movie with hours and hours of content. Because of its unique form, it faces a difficult distribution challenge. That said, by the end of the day, we had a working example of CLOUDS authorizing with the VHX API and dynamically pulling in videos on the fly. Crazy! CLOUDS is built with OpenFrameworks and James hopes to release an OpenFrameworks VHX addon to the ofxAddons community. CLOUDS integrating with VHX

Hack day success.

API Caching on Fastly

by Kevin Sheurs @ 05/28/14

We are moving towards a service-oriented architecture to help us grow and scale out the VHX platform. Given the nature of our releases, we tend to see large and sudden increases in traffic to various resources (site visits, video embeds, purchasing, streaming, apps, etc). We're focused on putting our API at the core of this architecture, with its performance and availability as our top priorities. This post digs into how we are utilizing Fastly and their direct Varnish Configuration Language (VCL) access to cache and accelerate our API.

Varnish and HTTP Caching

Varnish is an HTTP reverse proxy cache that is at the core of Fastly's service. When a request comes in to our API it first goes through Varnish and does a lookup in cache for that item. If it's not found, it passes the request to the backend (our API application), and then puts that response in cache for subsequent requests before finally returning the response to the client. The rules around looking up requests and caching responses are based on standard HTTP headers. Generally by default, HEAD and GET requests are cached and POST, PUT, and DELETE requests are not. There are many other factors to determine the correct caching policy (like Set-Cookie, Authorization, etc), but let's look at some specific cache related headers.

The HTTP Cache-Control header is used to specify directives on how clients should cache a response. With the following header for example, clients would cache the response for 1 hour:

response.headers['Cache-Control'] = 'public, max-age=3600'

Since we have both an intermediate proxy (Fastly/Varnish) and the originating client (browser or library), Cache-Control would be respected by both clients. This can become problematic because our dynamic content would now be cached in two places; giving us only partial cache invalidation control.

Fastly has another caching header that precisely addresses this: Surrogate-Control. By setting our Cache-Control header to no-cache and Surrogate-Control to max-age=3600 we can tell originating clients not to cache responses, but Fastly will. Perfect!

response.headers.merge!(
  'Cache-Control'     => 'public, no-cache, no-store, must-revalidate',
  'Surrogate-Control' => 'max-age=3600'
)

Invalidation

As data changes in our system the API needs to immediatly reflect that. Fastly has great instant invalidation capabilities via the HTTP PURGE method. Upon a database write in our system, we queue up purges to be sent to Fastly (see their Github for some useful libraries). In it's simplest form you can do something like the following to purge a resource:

curl -X PURGE "https://api.vhx.tv/packages/1"

However, in addition to that Surrogate-Control header, there is also the Surrogate-Key header. This allows you in your backend response to group content dependencies together based on various keys. So for example, on an API response that includes both site and package data our cache headers would be:

response.headers.merge!(
  'Cache-Control'     => 'public, no-cache, no-store, must-revalidate',
  'Surrogate-Control' => 'max-age=3600',
  'Surrogate-Key'     => 'sites/1 packages/1'
)

Now when package #1 in our system changes, we can issue a single "purge by key" command via the Fastly API for packages/1 that will invalidate all items in cache that are dependent on that data. Basically a wildcard-like approach to cache invalidation - powerful stuff!

VCL and Varying

VCL is the language in Varnish that let's you have low-level control of request handling and caching policies. You can do things like set or change request and response headers on the fly, have specific logic to do a "pass" to the backend or "lookup" in Varnish cache, route incoming requests to different backends per certain criteria, etc.

One way we utilize this is to inspect an incoming request for the VHX session cookie. For the most part our API does application and user identification via Oauth2, but there are a few endpoints that need to return logged-in content based on the session. By having the following, we can easily pass through logged-in requests to our back-end and continue to serve cached logged-out requests via Fastly:

if (req.http.cookie ~ "_session") {
  return(pass);
}

Vary is another cool HTTP header that Varnish respects that let's you cache variations in content under the same "hash" or cache key. Some of the content served via our API is geographically sensitive. A user from Australia may see different content from a user in the United Kingdom.

With the following VCL and HTTP headers we can now properly vary on our dynamic content giving us the benefit of caching and the ease of invalidation via a single purge command.

VCL:

sub vcl_recv {
  set req.http.X-Geo-Country-Code = geoip.country_code;
}

HTTP headers:

response.headers.merge!(
  'X-Geo-Country-Code' => 'AU',
  'Vary' => 'Accept-Encoding, X-Geo-Country-Code'
)

We look forward to iterating on our API and service oriented archtecture and finding more ways Fastly and Varnish can help accelerate our performance!

Meet Sagar Shah

by Sagar Shah @ 04/16/14

Sagar

Sagar is a full-stack software developer at VHX. But, he wasn't always a computer programmer. He actually got his degree in finance and economics at NYU and worked in consulting for three years before fully committing to his interests in computer science. After spending an intensive 3 months at The Flatiron School, Sagar joined VHX in October 2013 as a developer and hasn't looked back since. Here's a quick Q&A with Sagar.

What draws you to programming?

The cliche, but extremely true answer: I really love building things. It's gratifying to know that people are using something that I worked on. Also, I live for those "A'ha!" moments. You could say I'm kind of addicted to it. Because, let's be honest - programming is a struggle. But, when you solve a problem, or finally connect the dots and learn something new, it's the greatest feeling.

What kinds of things have you made recently?

Currently, I'm working on integrating ChromeCast into the VHX watching experience. So, VHX users, get ready to stream your purchases directly to your TV! It's been great working more with Javascript and learning about streaming protocols, subtitles, and the ChromeCast sender/receiver application structure.

I've also spent a lot of time over the past few months working on our publisher blogging/email communication tool, PayPal payouts for our publishers, spruces to our invoicing system, and some number crunching for our stats page.

What is something you discovered recently that you really liked?

One thing that a coworker introduced me to recently while I was writing some specs was a Ruby Gem called Timecop, which makes it much easier to test time dependent code. It literally freezes time.

In your specs, you can add something like this in a before block:

Timecop.freeze(Time.new(2014, 4, 16))

This will mock any Time.now call during the exeuction of those specs. Then, just specify Timecop.return in an after block to return to normal Rspec execution. Look at that, you just went back in time to run your specs, and you didnt even need a flux capacitor!

What's a great movie you've seen recently?

These are some of my recent favorites:

Documentaries: Mitt and Indie Game: The Movie (shoutout to Lisanne Pajot who is now helping other filmmakers successfully distribute through VHX!)

Features: Mud and Joe. Two films with monosyllabic titles set in the deep south about outlaw alpha males making an impact on Tye Sheridan. Basically the same film, but enjoyed both of 'em!

TV: Cosmos. Who doesn't love Neil Degrasse Tyson. Also, Blue Mountain State because it's hilarious.

VHX Hack Day

by Casey Pugh @ 03/31/14

For those of you who don't know what a hack day is: We spend the whole day working on whatever idea we want as long as it contributes to VHX in some capacity. For example, wouldn't it be great to easily export a GIF from your favorite movie scene on VHX? Not exactly revolutionary, but its fun!

Our team is founded by a bunch of hackers and designers with a passion for video. Hack days to allow us to continue to think beyond the scope of traditional video publishing and consumption.

Our most recent hack day yielded some really exciting results. In just under 8 hours:

  • Sagar and Gina integrated Chromecast into our video player. This feature is in beta and we will release it publicly soon! Chromecast
  • Chad redesigned our main blog and our developer blog. We have a lot of opinions on the future of video, and now we will have a pretty, candy-wrapped face.
    VHX blog redesign
  • Chris and Steven made some nice upgardes to our internal chat program, Hipchat. Now whenever someone does something good (or bad) we can give them Karma points. Yay.
  • Jamie integrated VHX into Popcorn Time. Whoa.
  • James and Charlie integrated VHX into Plex.
  • Michael and Kevin optimized the speed and scalability of our embeds. Death Star is fully operational.
  • Kathleen figured out how to empty an entire wine bottle. Turns out you can just drink it.

Just after one day it allowed us to more concretely define our API and make it even more robust. I'm really looking forward to our next hack day, and hope to host one to the public in the near future.

-Casey