Skip to content

Instantly share code, notes, and snippets.

@bradgessler
Created April 18, 2012 05:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradgessler/2411360 to your computer and use it in GitHub Desktop.
Save bradgessler/2411360 to your computer and use it in GitHub Desktop.
A faster Sprockets compiler that breaks apart the job into subprocesses
require 'sprockets'
module Sprockets
module Forkin
class Manifest < ::Sprockets::Manifest
attr_reader :workers
# The last argument should be the number of workers
def initialize(environment, path, workers=1)
@workers = workers
super environment, path
end
def compile(*args)
paths = environment.each_logical_path(*args).to_a +
args.flatten.select { |fn| Pathname.new(fn).absolute? if fn.is_a?(String)}
chunk_size = paths.size / (workers - 1)
logger.info "Breaking #{paths.size} assets into #{workers} chunks of #{chunk} paths"
pids = paths.each_slice(chunk_size).map do |paths|
fork do
trap("INT") { exit }
paths.each do |path|
if asset = find_asset(path)
files[asset.digest_path] = {
'logical_path' => asset.logical_path,
'mtime' => asset.mtime.iso8601,
'size' => asset.bytesize,
'digest' => asset.digest
}
assets[asset.logical_path] = asset.digest_path
target = File.join(dir, asset.digest_path)
if File.exist?(target)
logger.debug "Skipping #{target}, already exists"
else
logger.info "Writing #{target}"
asset.write_to target
end
save
asset
end
end
end
end
# Now lets wait for these stupid children to finish.
pids.each do
Process.wait
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment