Sass, Compass, and the Rails 3.1 Asset Pipeline »

Created at: 03.11.2011 19:07, source: Engine Yard Blog, tagged: ruby Technology

Note: Today's guest post is courtesy of Wynn Netherland, CTO at Pure Charity in Dallas and co-author of Sass and Compass in Action, a CSS book. He’s a web designer and a front-end developer, as well as a CSS geek. Check him out on GitHub and Twitter.

TL;DR

Compass and the Rails 3.1 Asset Pipeline can play nice to improve how you create, maintain, and serve stylesheet assets, but you’ll may need to tweak your setup to boost speed during your stylesheet development.

Since the advent of dynamic web pages, there has remained a dichotomy in web development. Developers tend to keep server-side code and templates in one spot and all the other static images, stylesheets, and client-side scripts in another. Agency-driven, split team workflows in which designers hand off static pages to web developers to break them into server-side templates have reinforced this model. We even call our stylesheets, images, and scripts assets, as if they were meant to be deposited into our /public folder, not to be handled with our application code. The Rails 3.1 Asset Pipeline breaks down this firewall and makes static assets first-class citizens in your web application. While it also handles images, CoffeeScript, and many other content types, let’s explore what the asset pipeline does for stylesheet authors.

What does the Pipeline do for me?

For serving CSS, the asset pipeline performs a few key functions.

Concatenation. Stylesheets can be stitched together from multiple source files, reducing the number of HTTP requests for CSS assets. The default application.css in Rails 3.1 is a manifest and tells the pipeline which source files to concatenate and serve to the browser:

/*
 * This is a manifest file that'll automatically include all the stylesheets
 * available in this directory and any sub-directories. You're free to add
 * application-wide styles to this file and they'll appear at the top of the
 * compiled file, but it's generally better to create a new file per style scope.
 *= require_self
 *= require_tree .
 */

By default, all stylesheets will be included. Sprockets, the gem that powers the pipeline, allows for more granular control:

/*
 *= require vars
 *= require typography
 *= require layout
 */

Just like view partials, we now get the benefit of organization by splitting up large stylesheets across several source files.

Minification. Whitespace and comments are removed from stylesheets before getting served up to the browser, reducing file size.

Fingerprinting. In Rails 3.1, cache-busting fingerprinting is baked right into the asset filename instead of relying on querystring parameters which have drawbacks in multi-server environments and some transparent proxy servers.

Pre-processing. Perhaps the biggest feature of the asset pipeline is preprocessing. Stylesheets can now be authored in Sass, Less, even ERB (gasp!), introducing dynamic methods to create static stylesheets.

Compass in the pipeline

Many of the above benefits have been available previously with Compass, the stylesheet framework for Sass. It’s no surprise that someone recently asked on the Compass mailing list if Compass was somehow obsolete with the arrival of the asset pipeline.

While it is true that there is some overlap in functionality between Compass and the asset pipeline, Compass does so much more. In addition to concatenation, minification, and preprocessing via Sass, most importantly Compass provides powerful modules for common stylesheet tasks including:

  • CSS3. The Compass CSS3 module provides Sass mixins for CSS3 features, allowing you to target multiple browsers’ vendor namespaces using a single syntax.
  • CSS sprites. Reducing the number of HTTP requests is a key factor of web application performance. The sprite helpers will create CSS sprites from a folder of separate assets, handling all the geometry for sprite layout, allowing you to reference icons by name.
  • Grid frameworks. Compass has great support for Blueprint, 960.gs, Susy, Grid Coordinates, and more.
  • Typography. Compass makes it easy to create and maintain vertical rhythm, tame lists, and style links with its typography helpers.
  • Plugins and so much more. There is a growing list of community plugins that make it easier to package styles for use across projects.

Installation

To use Compass inside the asset pipeline, be sure to add Compass version 0.11.0 (or edge if you’re brave) to the asset group in your Gemfile:

group :assets do
  gem 'sass-rails',   '~> 3.1.4'
  gem 'coffee-rails', '~> 3.1.1'
  gem 'uglifier',     '>= 1.0.3'
  gem 'compass',      '~> 0.11.0'
end

Once you’ve updated your gem bundle, you can now use Compass mixins in your stylesheets.

Changes for Compass users

If you’ve used Compass prior to Rails 3.1, there are some changes you should be aware of when using Compass in the asset pipeline.

Choose a bundling option. First, decide if you want to let Sprockets manage your stylesheet bundles or simply use Sass partials. You can use Sprockets manifest require and include directives in your Sass files, however there is a simpler approach to include CSS assets in your stylesheets. Simply rename any CSS files to use the .scss. file extension and you can use them as partials in your Sass stylesheets, even if your main stylesheets use the indented syntax and .sass extension.

Watch your assets. If you use the Compass helpers image-url, font-url, etc., note that these helpers will now resolve to /assets instead of /images and /fonts. This means you’ll need to put your images and fonts in app/assets/images and app/assets/fonts respectively instead of their previous homes in the public folder.

Optimizing for development

For all of its features, the asset pipeline comes with tradeoffs. The biggest impact is speed. With the asset pipeline, the entire Rails stack is loaded on each asset request. For small applications, this is trivial. For larger applications with many gem dependencies (especially those employing Rails engines) where many classes are reloaded with every request in the development environment, assets may render much more slowly when rendered via the asset pipeline.

Tweak your setup

If slow asset compilation is slowing down your front-end development, take a look at the rails-dev-tweaks gem from Wavii. The gem provides the ability to tweak Rails’ autoload rules, preventing reloading between requests in development. The default rules skips reloading classes for asset, XHR, and favicon requests:

config.dev_tweaks.autoload_rules do
  keep :all

  skip '/favicon.ico'
  skip :assets
  skip :xhr
  keep :forced
end

You should notice a speed bump, but keep in mind that if you have custom Sass functions, you’ll want to bounce the server to see those changes.

Precompile engine assets

You can speed up your development environment considerably by precompiling assets as you would in production, effectively bypassing the asset pipeline altogether. While this is encouraged for team members who aren’t modifying stylesheets, it doesn’t help stylesheet authors much. There is one noticeable exception - Rails engines.

Rails engines like Devise, Spree, and Refinery are powerful. Just by configuring a gem and running a generator you can add authentication, storefront, or CMS features to your Rails app with little effort. If your app uses engines, and you find your development environment begins to slow to a crawl, make sure your engine assets aren’t clogging the pipeline. In the case of Spree, we can improve asset performance by precompiling assets with a Rails Rake task:

rake assets:precompile RAILS_ENV=development RAILS_ASSETS_NONDIGEST=true

This will compile all application assets into /public/assets, allowing Rails to serve them without needing to recompile on each request:

drwxr-xr-x  17 wynn  staff   578 Nov  2 08:36 .
drwxr-xr-x   8 wynn  staff   272 Nov  2 08:35 ..
drwxr-xr-x  16 wynn  staff   544 Nov  2 08:36 admin
-rw-r--r--   1 wynn  staff   155 Nov  2 08:30 application.css
-rw-r--r--   1 wynn  staff   143 Nov  2 08:30 application.css.gz
drwxr-xr-x   7 wynn  staff   238 Nov  2 08:36 creditcards
drwxr-xr-x   3 wynn  staff   102 Nov  2 08:36 datepicker
-rw-r--r--   1 wynn  staff  1150 Nov  2 08:19 favicon.ico
drwxr-xr-x   6 wynn  staff   204 Nov  2 08:36 icons
drwxr-xr-x   4 wynn  staff   136 Nov  2 08:36 jqPlot
drwxr-xr-x  15 wynn  staff   510 Nov  2 08:36 jquery-ui
drwxr-xr-x   3 wynn  staff   102 Nov  2 08:35 jquery.alerts
drwxr-xr-x   3 wynn  staff   102 Nov  2 08:35 jquery.jstree
-rw-r--r--   1 wynn  staff  6694 Nov  2 08:36 manifest.yml
drwxr-xr-x   5 wynn  staff   170 Nov  2 08:36 noimage
-rw-r--r--   1 wynn  staff  1608 Nov  2 08:19 spinner.gif
drwxr-xr-x   6 wynn  staff   204 Nov  2 08:36 store

With precompiled assets, our load times are reduced dramatically, however we won’t see changes to our own stylesheets. In the example above, we can simply remove application.css and application.css.gz so that those will be compiled on each request via the asset pipeline. However, having our engine-provided stylesheets precompiled is a big win.

As we mentioned above, one of the big gains of the asset pipeline is concatenating our stylesheets into a reduced number of files. If you are serving multiple application-specific stylesheets, consider precompiling all your assets and then removing your current work-in-progress stylesheet from /public/assets.


more »

Let the Engine Yard Cloud dashboard and SSH access help you »

Created at: 25.10.2011 21:06, source: Engine Yard Blog, tagged: cloud Technology Tips & Tricks

A common web application frustration almost everyone can understand is the headache associated with discovering your site is down. The discovery that your site is down can encompass a wide spectrum of situations ranging from 404 errors, to a 500 internal server error, to a no response timeout. What may be even more frustrating, is the fact that you do not always know exactly what the issue is, or how to tackle it, even if you later discover it is merely a trivial error. In this post I’ll walk through ways the Engine Yard Cloud dashboard and SSH access can help users gain better visibility into the issue or issues resulting in site downtime.

The Engine Yard Cloud dashboard

Before we begin, it’s important to keep in mind that the following steps assume there are no technical issues with the Engine Yard Cloud platform itself. For Engine Yard Cloud system level issues, we recommend following @eycloud on Twitter and subscribing to the Release Notes feed.

Start with visual inspections

From the Dashboard homepage, do you see a red status indicator? This designates that your EC2 instance is experiencing problems. A few things can cause this problem. So, how do you figure out why? Click on the environment that has a red status indicator. As you can see the environment below displays a red status indicator.

Now you can view a handful of logs to diagnose the problem. If a problem was caused by pressing the Upgrade button, the Base Log will display the reason for it. It may be necessary to check the Custom Log if you are using custom Chef recipes.

For example, this particular error was caused by a typo in the custom chef recipe. Here is the custom log displaying the error. The database name was spelled incorrectly in this case.

More often than not, the errors are descriptive enough to resolve once you have identified them. Once you have fixed the error, you will need to “Apply” the changes.

What else could be wrong?

Your next discovery may be found in the alerts tab. Alerts offer you useful information about heavy load, high memory usage, low disk space, etc. For example, if you discover you are running out of memory, you may decide to scale your environment or modify your application in order to resolve such issues.

I see a green status indicator and there are no alerts

If this is the case, there is a strong possibility that your application deployment failed. Let’s visit your application’s View Log. Usually you will find an explanation for the deployment failure somewhere along the bottom of the log. Common culprits may include git errors, RubyGem issues, a typo in your application’s custom Chef recipes, etc.

In this case the error is showing “Permission denied (publickey)”, which is often displayed as a result of failing to add your deploy key to your git repository.

My application is still down

Hopefully the suggestions above will help you diagnose the source of your downtime so that you can get your application back up. Of course situations may also occur where no information on the Engine Yard Cloud Dashboard indicates any potential problems. So, what do you do in this case?

Let’s get down and utilize SSH

Inspect application logs within your instance

Additional logs exist that are not viewable directly through your Dashboard. Since each Engine Yard Cloud instance corresponds to an actual Amazon EC2 instance, you can view files in your instance as you would on any other server.

The first place to check is your application’s logs under /data//current/log. The file production.log may point you in the right direction. Other log files in the same directories may lead you to a discovery as well.

What other processes can fail?

Another common problem can result from Nginx. Due to certain triggers, it is possible for Nginx to be terminated. To determine the Nginx status execute sudo /etc/init.d/nginx status. If the status indicates that Nginx has not started, you can run sudo /etc/init.d/nginix start to fix that. Then, recheck the status to verify you are good to go.

The same principle can be applied to MySQL. You can check the status with sudo /etc/init.d/mysql status and start MySQL with sudo /etc/init.d/mysql start. To check the status of Passenger, run passenger-status and you can restart passenger by restarting Nginix as passenger automatically restarts with passenger. You can also find other useful logs under /var/log, such daemon.log, syslog, etc.

Wrapping up

Downtime is frustrating. Luckily, there are many tools and resources to arm you with useful information to help diagnose and resolve downtime related issues. You can also check out the Site is down: diagnostic checklist on our documentation page for a more formal walk through.

 


more »

Respond to Custom Formats in Rails »

Created at: 24.10.2011 18:09, source: Ruby Rockers, tagged: Solutions Technology rails

We usually respond some of the known formats in Rails Application like HTML, XML, JavaScript, RSS and some custom.

Have you tried to use your own custom format for your Rails Application?

Yes you can use your custom format in Rails Application.

Here showing a simple Rails Application with responding custom formats.

Get a new app

rails new music_library 

Get a scaffold into App

rails generate scaffold mp3 title:string url:string description:text 

Ok so you are ready to serve some music on your app with some formats!

Now you have to register MIME types in the Rails Application.

For that open up Rails.root/config/initializers/mime_types.rb

Mime::Type.register 'audio/mpeg' , :mp3

Now you can serve .mp3 and content

For that your respond block should look like

def show
  @mp3 = Mp3.find(params[:id])
  respond_to do |format|
    format.mp3 { redirect_to @mp3.url }
  end
end

Now if you call this action with .mp3

http://localhost:3000/mp3s/1.mp3

You will redirect_to @mp3 url.

Happy adding custom formats!!


more »

X-Request-Id tracking and TaggedLogging in Rails3.2 »

Created at: 21.10.2011 18:04, source: Ruby Rockers, tagged: Technology rails ruby

Rails 3.2 will come with X-Request-Id tracking and TaggedLogging support!! Recently DHH added this feature here!

This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs.

If you have application on SAS model. Where you have logs filled with mixed request for all your customers. May be you need to filter out requests start with some specific subdomain. TaggedLogging will help you in that.

Where as the X-Request-Id feature will help you to track log with the same request. So in mixed logs you can easily find out the unique id logs for a request.

It will tag the log with the unique id for that request in the log. So later you can easily trace them down.

May be later on you can add more tags for your logs. If those methods are supported by the request object!

I am showing here some logs here with X-Request-Id

[2011-10-21 19:57:55] INFO  WEBrick 1.3.1
[2011-10-21 19:57:55] INFO  ruby 2.0.0 (2011-10-19) [x86_64-darwin11.2.0]
[2011-10-21 19:57:55] INFO  WEBrick::HTTPServer#start: pid=1585 port=3000
[9fda80066583f52e695a089d8622439c] 

Started GET "/blogs" for 127.0.0.1 at 2011-10-21 19:57:59 +0530
[9fda80066583f52e695a089d8622439c]  Processing by BlogsController#index as HTML
[9fda80066583f52e695a089d8622439c]    Blog Load (0.2ms)  SELECT "blogs".* FROM "blogs"
[9fda80066583f52e695a089d8622439c]    Rendered blogs/index.html.erb within layouts/application (8.8ms)
[9fda80066583f52e695a089d8622439c]  Completed 200 OK in 32ms (Views: 30.4ms | ActiveRecord: 0.3ms)
[2011-10-21 19:57:59] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
[0962521e4215d645367b58fa41da9f0d] 

Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2011-10-21 19:57:59 +0530
[0962521e4215d645367b58fa41da9f0d] Served asset /application.css - 304 Not Modified (0ms)
[2011-10-21 19:57:59] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
[a7204cec4d2b2e930ac05b41fa1a5c65] 

Started GET "/assets/jquery_ujs.js?body=1" for 127.0.0.1 at 2011-10-21 19:57:59 +0530
[a7204cec4d2b2e930ac05b41fa1a5c65] Served asset /jquery_ujs.js - 304 Not Modified (1ms)
[2011-10-21 19:57:59] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
[202eadd97820dfbf429f87f4725324c3] 

Started GET "/assets/blogs.css?body=1" for 127.0.0.1 at 2011-10-21 19:57:59 +0530
[202eadd97820dfbf429f87f4725324c3] Served asset /blogs.css - 304 Not Modified (2ms)
[2011-10-21 19:57:59] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
[769a2752906bb0c2c5d1eae0a76ac328]

Here I showed some logs in strong. They are the same request for the index page tagged with the same unique id.
The same concept for the subdomain. The subdomain will also come as a tag.

You can also log some of the custom events in log file with the tags!

Logger.tagged("BCX") { Logger.info "Stuff" }                            # Logs "[BCX] Stuff"
Logger.tagged("BCX", "Jason") { Logger.info "Stuff" }                   # Logs "[BCX] [Jason] Stuff"
Logger.tagged("BCX") { Logger.tagged("Jason") { Logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff"

How to configure it ??

Open up your production.rb or your custom environment file, uncomment the line for log_tags

config.log_tags = [ :subdomain, :uuid ]

And you will get tagged logs with useful information.

Useful links :

Commit URL : https://github.com/rails/rails/commit/afde6fdd5ef3e6b0693a7e330777e85ef4cffddb
Feature Branch : 3.2

Cheers,
@arunagw


more »

A Modern Guide to Threads »

Created at: 21.10.2011 03:49, source: Engine Yard Blog, tagged: Technology code ruby threads

NOTE: Mike Perham from Carbon Five recently wrote a blog post about using threads in Ruby. With his permission, we're reposting it here.

Carbon Five has been building state-of-the-art web applications for startups and large institutions since early 2000. Since their inception, they have focused on quality and value as the critical components of project success.

I spoke recently at Rubyconf 2011 on some advanced topics in threading. What surprised me was how little experience people had with threads so I decided to write this post to give people a little more background on threads. Matz actually recommends not using threads (see below for why) and I think this is a big reason why Rubyists tend not to understand threading.

Simple Threading

Every time you execute ruby, rails or irb, you are creating a process. Within each process, you have something which is executing the code in your process. This is called a thread.

Your operating system starts every process with a "main" thread. Ruby allows you to create as many additional threads as you want by calling Thread.new with a block of code to be executed. Once the block of code has finished executing, the thread is considered dead. If the main thread exits, the process dies.

t1 = Thread.new do
  i = 0
  1_000_000.times do
    i += 1
  end
end
t2 = Thread.new do
  j = 0
  1_000_000.times do
    j += 1
  end
end
t1.join
t2.join

Above we have two threads independently counting up to one million, while the main thread waits for them to finish by calling join on each thread. These two threads will execute concurrently ("operating or occurring at the same time") with your process's main thread. Not so hard, right?

Race Conditions

Generally your computer can execute one thread per core. I have a dual core CPU in this laptop which means I can execute two threads at the exact same time [1]. Now imagine I want to parallelize my counting above. Instead of having one thread count to two million, I will have two threads count to one million each. That should execute twice as fast because I'll be using two threads and thus both cores:

i = 0
t1 = Thread.new do
  1_000_000.times do
    i += 1
  end
end
t2 = Thread.new do
  1_000_000.times do
    i += 1
  end
end
t1.join
t2.join
puts i

You'd expect the result to print "2000000″, right? Nice try.

> jruby threading.rb
1330864

Any time multiple threads try to change the same variables, they have the potential for race conditions. Why is this?

The race condition is fundamentally due to the multi-step process of changing a variable. Even a simple increment in most languages is actually a multi-step process:

register = i              # read the current value from RAM into a register
register = register + 1   # increment it by one
i = register              # write the value back to the variable in RAM

One of the features of threads is that they are controlled by the operating system; the OS can decide to stop Thread 1 and start executing Thread 2 at any point in time. This means that the OS can stop your thread after it has read the value of i into a register. Imagine this sequence of events:

i = 0
# OS is running Thread 1
register = i # 0
register = register + 1 # 1

# OS switches to Thread 2
register = i # 0
register = register + 1 # 1
i = register # 1

# Now OS switches back to Thread 1
i = register # 1

Now technically both threads have incremented i. Will the resulting value be 2? No, because the Thread 2′s increment was lost when Thread 1′s last operation overwrote the memory. This is exactly why we saw 1330864 instead of 2000000; we lost a lot of increments due to this race condition. To avoid race conditions, any variable changes (fancy CS terminology: "mutation of shared state") must be done atomically so that other threads cannot see the change midway through the change process.

Thread Safety

Now you know the fundamental requirement for thread-safe code: mutation of shared state must be done atomically. Any time you change a variable that is shared by many threads, it needs to be done atomically. Unfortunately Ruby and most other mainstream languages only give you one tool to do this: the lock aka the mutex.

Mutex is short for "mutual exclusion" as in "only one thread can be executing this code at a time". Usage is simple:

@mutex = Mutex.new
@mutex.synchronize do
  i += 1
end

Remember that increment is a three-step process but because only one thread can be in the synchronize block at a time, we won't have any problems with race conditions; the Mutex effectively makes the increment atomic.

Here's the dirty secret that everyone who uses threads learns eventually: Threads have such a terrible reputation because locks are very painful to use in practice.

Modern Threading

What are the alternatives? There are several:

  • Atomic Instructions — turn multi-step operations into a single atomic operation
  • Transactional Memory (STM) — ensure that changes are done as part of a transaction which guarantee atomicity
  • Actors — refactor our code so that only one thread may change a variable

My take is that locks exponentially grow the complexity of your codebase and this is a major reason why Matz has always advised Rubyists to use Processes rather than Threads for concurrency. My recent Rubyconf talk on Threads discusses these options. The Clojure language mandates transactional memory for all variable changes. Scala and Erlang offer Actors. Using plain old threads and locks is akin to writing in assembly language: there are better ways now.

In my opinion, the last option is the preferred option since you avoid the race condition in the first place: "Don't communicate by sharing state; share state by communicating". The fundamental idea behind actors is to give each thread a separate responsibility and pass messages between threads according to those responsibilities.

My first piece of advice to Rubyists: avoid Thread.new. This is exactly what Matz is saying also. Instead look for infrastructure that can abstract the use of threads into a safer concurrency model. See Celluloid and girl_friday for instance. Of course, MRI is not particularly suited to high concurrency applications; JRuby is a better choice. Other languages like Clojure or Erlang were designed with concurrency as a language feature right from the start.

I'm not saying that threads and locks should be removed completely from all software. Rather we should treat them for what they are: low-level abstractions that developers should not be using directly. Like threads and locks I see a need for assembly language but it should be used very sparingly. Understanding and knowing how to use higher level concurrency abstractions like actors and STM will make concurrent pieces of your application easier to write and maintain. Unfortunately not all of these options are available to MRI but all are available to JRuby via Java libraries.

1 — True with JRuby, not true with MRI because of the infamous "Global Interpreter Lock". ^


more »