Nov 02

The simplest way to test syntax is to use the administration console via telnet on a Dev/QA Varnish machine. Your current running Varnish should allow your IP/localhost to connect if you have implemented a Varnish ACL.

  • Start up Varnish with single command-line
  • Login to console via telnet
  • Load the config you wish to test
  • Use the config.

On OSX:

sudo /usr/local/sbin/varnishd -F  -a localhost:3000 -b localhost:6081 -T localhost:6082

From another console/shell/ open connection to Varnish management console:

telnet localhost 6082
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Load config and try to use (the config used in this example has a syntax problem. Therefore, you will see compilation errors:

vcl.load error /Users/hbeaver/code/varnish_demo/config/syntax_error.vcl
106 181
Message from VCC-compiler:
Expected one of
	'acl', 'sub', 'backend',  or 'director'
Found: '}' at
(input Line 12 Pos 1)
}
#
Running VCC-compiler failed, exit 1VCL compilation failed

Conversely, if the VCL has good syntax you should see no errors:

vcl.load good_config /Users/hbeaver/code/varnish_demo/config/default.vcl
200 13
VCL compiled.

Tagged with:
Oct 15

You may find yourself needing to test something with a specific version of thin, for whatever reason. If you need start up thin with a specific version of gem you have installed this is how you do it:

<pre>thin _1.2.4_ -R config.ru -p 3001 start</pre>

The first argument represents the gem version prefixed and post-fixed with “_”.

Enjoy.

Tagged with:
Oct 01

Spent a little time scratching my head on this week. @params is reserved in Rspec controller tests apparently much like Rails. @params will contain extra keys like “controller” and “action” which if you try and assert against will fail of you do something like this:

<pre>

@params = {:id => ‘niceid’}

Model.expects(:method).with(@params)

</pre>

Sep 03

I’m am still captivated by the perfect, simple CMS solution in Ruby/Rails (I’ll take another framework too). There are some fantastic projects out there, browsercms.org for example. But posts like THIS , really drive home the point. If Wordpress is so well suited for a simple site and/or blog, why not just use it? Igvita demonstrates easy Rails integration with Apache rewrite rules.

There are others out there stating the same thing: while Rails can be used to create a CMS, a developer’s time is better spent solving business rather than reinventing the wheel in Ruby to keep the whole project/code under one umbrella. And at my current gig, we are starting to retool for this paradigm. Rails and Sinatra apps are purely business focuses and super light weight. These service applications can them be glued together via ESI, rewrites, or Wordpress for consumption. In effect, your complex web app is assembled at request time from a set of simple web services. Here is some mock code to demonstrate:

wordpress_template.php
//some more wonder wordpress stuff
<?= include_rails_service('http://service.app/user/profile',ESI_INCLUDE) ?>
//some more wonder wordpress stuff
<?= include_rails_service('http://service.app2/events/weeks/2',SERVICE) ?>
//end of wordpress.php
...
//function included elsewhere
function include_rails_service(service_url,type){
//could return any of following for the resource url
 switch (type) {
  case ESI_INCLUDE:
   return "<esi include ='" + service_url + "'>";
   break;
  case SERVICE:
   include service_url;
   break;
  case AJAX:
//javascript include with service js, doing doc.write
}
}

The point is Wordpress doesn’t know about Rails and Rails doesn’t know about Wordpress. Keep them seperate, keep them simple and make life better.

Tagged with:
Aug 10

When working with Sinatra + ActiveRecord + MySQL running on the venerable Thin server, you are probably going to see the error after 8 hours(MySQL default connection timeout): “Mysql::Error: MySQL server has gone away” message. The resolution is pretty simple:

class NewApp < Sinatra::Default   

  before do
    ActiveRecord::Base.connection.verify!
  end
...
end #end of Sinatra class

I created a Lighthouse ticket before I discovered the resolution. There are also more technical details here: https://thin.lighthouseapp.com/projects/7212-thin/tickets/101-activerecord-connection-does-not-reconnect-when-using-thinsinatra-but-works-fine-with-just-sinatra#ticket-101-4

Tagged with:
Jul 15

This example uses Ruby to telnet into Varnish and issue the “url.purge .*” command. The only gotcha is that the varnish telnet server does not issue a command prompt which causes Ruby telnet to timeout and get cranky. Well a little exception handling hacks past this. Enjoy.

require 'rubygems'

namespace "varnish" do

  desc "Purge ALL urls from Varnish"
  task :global_purge => :environment do

    #It WILL timeout, just accept it. Varnish does not have a command prompt.
    require 'net/telnet'
    @result = ""
    begin
      localhost = Net::Telnet::new("Host" => "localhost",
      "Port" => 6082,
      "Timeout" => 5)
      localhost.cmd("url.purge .*") { |c| @result = c}
    rescue Exception
      if @result.include? ("200 0")
        puts "varnish purged OK."
      else
        raise "Varnish not purged."
      end
    end
  end

end

Tagged with:
Jul 14

What does this mean? Well for starters, those nice little PCRE shorthands for character classes just don’t work! So putting this in your Varnish VCL will silently do nothing:

if (req.url ~ "/\d+(/$|/\?|\?|$)") ...

whereas this match:

if (req.url ~ "/[0-9]+(/$|/\?|\?|$)") ...

Enjoy.

Tagged with:
Jun 05

When using a BigIP to load balance a Sinatra app via Thin you will need to provide more than just the GET request string in F5’s “send string” field OR you might get “Request Invalid!” error message. Heads up.

Using this will cause issue:

GET /ops/heartbeat

This works:

GET /ops/heartbeat HTTP/1.1\r\nHost: \r\nConnection: Close\r\n\r\n

Tagged with:
Jun 05

Simple but effective regex to monitor when there are issues. In my example below, this will show all response times > 1 second:

 tail -f production.log | egrep "Completed in [0-9]{3,10}"

Tagged with:
Jun 03