PullMonkey Blog


29 Oct

Open Flash Chart #2


Here is a chart created with the Open Flash Chart plugin for ruby.


width="500" height="260" id="ie_chart_41" align="middle"> type="application/x-shockwave-flash" pluginpage="http://ww.macromedia.com/go/getflashplayer" id="chart_41"/>



View Source Code




11 Oct

Cached Assets


I love the CachedAssets plugin for rails. This plugin bundles all your css files into one and all your js files into one which helps make fewer http requests, ultimately making your site respond faster.

The cached assets plugin does a great job of combining the assets, but the one flaw is that the resulting file is simply the MD5 Sum of the file names of the assets to be joined together. No matter the contents or the time-stamp of the asset files, the resulting name never changes. Browsers tend to cache these files, which is good, but not when you made some recent changes. I made a few adjustments to the cached assets plugin to name the resulting file based on the MD5 Sum of the asset files' last modified times. Now the name is guaranteed to be different if something has changed.

Here is a diff of what the plugin gives us and what changes I have made:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

[pullmonkey]$ diff -ru cached_assets/lib/cached_assets.rb cached_assets_pullmonkey/lib/cached_assets.rb
--- cached_assets/lib/cached_assets.rb  2007-04-08 11:52:36.000000000 -0700
+++ cached_assets_pullmonkey/lib/cached_assets.rb       2007-10-09 11:30:48.000000000 -0700
@@ -21,13 +21,13 @@

       private
         def cached_asset(sources, type)
-          cached_name = Digest::MD5.hexdigest(sources.join(',')) + (type == :js ? '.js' : '.css')
-          cached_source = compute_public_cached_path(cached_name)
-          cached_path = compute_store_path(cached_name)
-
           sources = js_defaults(sources) if type == :js && sources.include?(:defaults)

-          assets = sources.map {|s| (type == :js ? javascript_path(s) : stylesheet_path(s)).split('?') }
+          assets = sources.map {|s| (type == :js ? javascript_path2(s) : stylesheet_path2(s)).split('?') }
+
+          cached_name = Digest::MD5.hexdigest(assets.map{|a| File.stat("#{ASSET_CACHE_STORE}/#{a}").mtime}.join(',')) + (type == :js ? '.js' : '.css')
+          cached_source = compute_public_cached_path(cached_name)
+          cached_path = compute_store_path(cached_name)

           if !FileTest.exist?(cached_path) || rails_asset_id(cached_source).to_i < assets.map {|a| a.last.to_i }.max
             FileUtils.makedirs(File.dirname(cached_path))
@@ -38,6 +38,7 @@
             }
           end

+
           cached_source
         end

@@ -53,7 +54,7 @@
         end

         def asset_path(src, type)
-          "#{RAILS_ROOT}/public#{(type == :js ? javascript_path(src) : stylesheet_path(src)).split('?').first}"
+          "#{RAILS_ROOT}/public#{(type == :js ? javascript_path2(src) : stylesheet_path2(src)).split('?').first}"
         end

         def compute_public_cached_path(src)
@@ -63,6 +64,14 @@
         def compute_store_path(src)
           "#{ASSET_CACHE_STORE}#{compute_public_cached_path(src)}"
         end
+
+        def javascript_path2(src)
+          "/javascripts/#{src}.js"
+        end
+
+        def stylesheet_path2(src)
+          "/stylesheets/#{src}.css"
+        end
     end
   end
 end



I am not sure the plugin's intent, but I am sure it was designed to simply combine all the assets together, not to worry about browser caching. I am pretty sure that this plugin in combination with Asset Timestamping plugin would maybe do the trick, in the sense that the filename (resulting from the cached assets plugin) would never change and the asset timestamping plugin would append a timestamp to the end of the asset name, I.e. ?1147898838. There is a problem with this though and it is discussed in great detail in the Optimizing Page Load Time Article.
This article states that in order for the browser to ALWAYS cache the file (which we really, really want until we change the name) then we need to stay away from the use of question mark timestamping. So I believe I have presented the solution that best meets my requirements of having one css file, one js file and a way to avoid the stale browser cache when modifications have been made.



07 Oct

MacroMovers, Inc.


I own a small moving company that does local moves in Albuquerque, NM and the surrounding areas.
We are approaching the end of our first year, and will soon be one year old :)

I run this business on the side with two friends and we have successfully grown it from the ground up.
When we first started it was just the three of us, trying to get a few extra bucks and have some fun.
We started out just doing jobs on the weekend, and over the holidays.

We soon realized how much work it really was and decided that the first order of business would be to hire a couple of guys to do the work for us :). We hired people rather quickly, all through the paper and craigslist. Over this year we have hired, fired, and promoted over 40 people in the Albuquerque area, believe it or not, there is a huge turn around rate.

We have one scheduler, they have been with us since day one, I think the first or second guy we hired. He is awesome and has brought a lot of success our way. He handles the customers, the workers, and tracks all of our day to day, he has taken over EVERYTHING, well except for sending out paychecks, we continue to meet and pay our workers every couple weeks, or in some cases when necessary.


If you are looking to move to, from or within Albuquerque, go to MacroMovers.com.




07 Oct

Open Flash Chart #1


Here is a chart created with the Open Flash Chart plugin for ruby.




width="500" height="250" id="ie_chart_33" align="middle"> type="application/x-shockwave-flash" pluginpage="http://ww.macromedia.com/go/getflashplayer" id="chart_33"/>



View Source Code