Posted by Tres
Sat, 18 Oct 2008 03:41:00 GMT
As a former SVN-evangelist, I can say that I came to Git with quite a bit of speculation – wondering why we need just another revision control system. Subversion already did everything we needed – so why mess around with something else.
After using Git for the last few months, I can say that I’m truly won-over. It seems like more-of-the-same at the outset, but as you get deeper into it, it really proves to be one of those really well thought out things you run into every once in a while; I’d liken the move from Subversion to Git something akin to the move from Procedural to Object Oriented Programming. Once you ‘get it,’ there’s really no going back.
Anyway, on to the point of all this.
So you use git push to push a branch you’ve created back up to the project repository.
git push origin DescriptiveBranchName
Posted in Development | Tags branch, git, push, repository
Posted by Tres
Thu, 28 Aug 2008 12:53:00 GMT
Mixins are one of the most powerful constructs that Ruby provides. Mixins give you the power of multiple inheritance without all the inherent complexities and problems associated with multiple inheritance. The best part of using mixins is how extremely simple they are to use. Just include the module you want to mixin and then call any of the functions defined in the module.
Using mixins with rails is just as easy, the only problem is figuring out where to put your mixin (opinionated programming, you know). Just put your mixin into the lib directory of your rails project and you’ll be good to go. Once you’ve got the file in the right spot, just
require 'module_file_name'
include ModuleName
Then call the function you want to use, and you’re set.
Posted in Ruby, Development, Ruby on Rails | Tags mixins, rails
Posted by Tres
Fri, 15 Aug 2008 18:00:00 GMT
Security policies in flash require that images be loaded from the same domain as the swf file is hosted on. This doesn’t really become an issue until you’re using BitmapData.draw() to convert the flash vector image into a raster graphic.
If you’re seeing SecurityError: Error #2122 when attempting to use BitmapData.draw(), you can fix this by setting up a Policy file on S3 for your bucket.
Now you might be saying, “I don’t have access to anything outside my bucket, how can I set up a file named crossdomain.xml in the root level of s3.amazonaws.com?” Well, never fear, Amazon has already given us a way to access buckets via vhost name. Just use bucket_name.s3.amazonaws.com to access your files, and you’re golden.
Update
15 Aug 2008
My friend, Lyle just wrote to say that you can also use a CNAME with s3 to have the same effect:
BTW, if you set up a CNAME to point to s3.amazonaws.com and create a
bucket with the same name, you can access it that way as well. i.e.
http://s3.vmann.net/public_key.asc is my gpg public key, stored in
bucket named ‘s3.vmann.net’
Posted in Development, Ruby on Rails | Tags flash, s3, SecurityError: Error #2122, BitmapData.draw(), crossdomain.xml
Posted by Tres
Tue, 12 Aug 2008 13:34:00 GMT
Here’s a couple of snippets of goodness – rake seed:dump and rake seed:load
If you’re using yaml fixtures to store seed data for quick db deployment, then these should help out. If you’re still trying to manage seed data with your migrations, you might want to look into using yaml files instead. These rake tasks use a db/fixtures folder by default.
Put these tasks into the lib folder of your rails project.
Here’s dump.rake
namespace :seed do
desc 'Dump a database to yaml fixtures. Set environment variables DB
and DEST to specify the target database and destination path for the
fixtures. DB defaults to development and DEST defaults to RAILS_ROOT/
db/fixtures.'
task :dump => :environment do
path = ENV['DEST'] || "#{RAILS_ROOT}/db/fixtures"
db = ENV['DB'] || 'development'
sql = 'SELECT * FROM %s'
ActiveRecord::Base.establish_connection(db)
ActiveRecord::Base.connection.select_values('show tables').each do |table_name|
i = '000'
File.open("#{path}/#{table_name}.yml", 'wb') do |file|
file.write ActiveRecord::Base.connection.select_all(sql %
table_name).inject({}) { |hash, record|
hash["#{table_name}_#{i.succ!}"] = record
hash
}.to_yaml
end
end
end
# ActiveRecord::Base.connection.select_values('show tables')
# is mysql specific
# SQLite: ActiveRecord::Base.connection.select_values('.table')
# Postgres
# table_names = ActiveRecord::Base.connection.select_values(<<-end_sql)
# SELECT c.relname
# FROM pg_class c
# LEFT JOIN pg_roles r ON r.oid = c.relowner
# LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
# WHERE c.relkind IN ('r','')
# AND n.nspname IN ('myappschema', 'public')
# AND pg_table_is_visible(c.oid)
# end_sql
end
and here’s load.rake
namespace :seed do
desc "Load seed fixtures (from db/fixtures) into the current environment's database."
task :load => :environment do
require 'active_record/fixtures'
Dir.glob(RAILS_ROOT + '/db/fixtures/*.yml').each do |file|
Fixtures.create_fixtures('db/fixtures', File.basename(file, '.*'))
end
end
end
Posted in Development, Ruby on Rails | Tags automate, rails, rake task, seed data
Posted by Tres
Tue, 12 Aug 2008 13:28:00 GMT
This one is pretty easy, but for the fact that the built-in help doesn’t mention git ls-files.
To view deleted files use git ls-files –deleted
To restore deted files just use git checkout – <deleted_file>
Too easy.
Posted in Development | Tags git, oops, recover, restore
Posted by Tres
Sun, 10 Aug 2008 18:08:00 GMT
So there’s lots of documentation out there on creating XML via Rails. The problem is that it’s not really kept up with all the changes that have occurred. Here’s a few quick items that may be helpful when creating XML with Rails 2.1.
• When creating an instance of XMLBuilder, use ::Builder::XmlMarkup.new instead of Builder::XmlMarkup.new.
• When creating your view, use the extension .xml.builder instead of .xml.erb
• When rendering the template from the controller, make sure that the content type headers are set for xml and that you’re not rendering the layout. The controller should have a section that looks something like this:
headers["Content-Type"] = "text/xml"
respond_to do |format|
format.xml { render :template => 'options.xml.builder', :layout => false }
end
Posted in Ruby, Development, Ruby on Rails | Tags XML Builder, Rails 2.1
Posted by Tres
Fri, 08 Aug 2008 07:04:00 GMT
It appears that in cases where :null => false is set for any column in a migration, the entire migration requires the newer migration syntax. Edge rails enforces the new syntax for migrations, not by failing to run, but by creating an invalid SQL statement.
So, a statement like this:
t.column :buzzword_level_id, :string
will end up as SQL like this:
`buzzword_level_id` varchar(255) DEFAULT NULL NULL
and will promptly bomb out. Google is more confusing than helpful in this instance because this was formerly a bug that affected all migrations, and was recently fixed; however, the fix relies upon using the new syntax for migrations. So, rewriting the migration like this:
t.string :buzzword_level_id
fixes the problem.
Posted in Development, Ruby on Rails | Tags DEFAULT NULL NULL, edge rails, migrations
Posted by Tres
Thu, 03 Jul 2008 00:29:00 GMT
MySQL has a 100 character limit on the length of the name of an index, which ActiveRecord will cross when creating an index for a table that has multiple foreign keys and other data that is to be indexed. If you’re seeing a message like the following when building indexes:
Mysql::Error: #42000Identifier name 'index_duper_on_us_id_and_hair_id_and_leaf_id_and_number_id_and_super_id_and_created_at_and' is too long:
CREATE INDEX `index_duper_on_us_id_and_hair_id_and_leaf_id_and_number_id_and_super_id_and_created_at_and_completed` ON `duper`
(`us_id`, `hair_id`, `leaf_id`, `number_id`, `super_id`, `created_at`, `completed`)
just manually assign a name to the index by appending :name => “[MANUALINDEXNAME_HERE]” to the index you’re creating. So in our example above, the line in the migration would look like this:
add_index :duper, [:us_id, :hair_id, :leaf_id, :number_id, :super_id, :created_at, :completed], :name => "duper_index"
Posted in Development, Ruby on Rails | Tags activerecord, index, too long
Posted by Tres
Mon, 12 May 2008 09:31:00 GMT
Since Java 5, we’ve been able to send ICMP Echo requests using java.net.InetAddress; however, under *nix like systems, you’ll need root level permissions to get things running. If you don’t have the correct system permissions, java.net.InetAddress will silently fail, letting you know that every single host you attempt to test is down.
The following utility will do an ICMP Echo check & ensure that the user running the utility has the correct permissions.
import java.net.*;
import com.sun.security.auth.module.UnixSystem;
/**
*
* @author Tres Wong-Godfrey
*/
public class IcmpEcho {
public static void main(String[] args) {
String host = null;
int timeOut = 3000;
boolean isUp = false;
boolean validRequest = true;
String output = "";
long uid = -1;
UnixSystem user = new UnixSystem();
uid = user.getUid();
if (args.length != 1) {
System.out.println("ICMP echo check requires a single argument -- the hostname");
System.exit(1);
}
if (uid != 0) {
System.out.println(" ICMP echo check requires root permissions");
System.exit(2);
}
host = args[0];
try {
isUp = InetAddress.getByName(host).isReachable(timeOut);
} catch (SecurityException $e) {
System.out.println(" ICMP echo check requires root permissions");
validRequest = false;
} catch (UnknownHostException $e) {
System.out.println(" Unknown host: " + host);
validRequest = false;
} catch (Exception $e) {
System.out.println("Unknown error");
$e.printStackTrace();
validRequest = false;
}
if (validRequest == true) {
output = (isUp == true) ? host + " is up" : host + " is down";
}
System.out.println(output);
}
}
Posted in Java, Development | Tags java, ping
Posted by Tres
Sun, 11 May 2008 14:18:00 GMT
One of the biggest problems that we find in the realm of PHP web applications is that there is no native object persistence between page requests. Clients getting around in a PHP application normally means instantiating and re-instantiating objects as needed. A page that needs access to the Client object wound create a
new Client() every time client data were needed, or keep a bunch of global variables held in session data.
Because of the way some web applications are engineered, for some unfortunate databases, this meant that every page hit was another call to the database to populate the instance variables associated with the current client. For some unfortunate web app maintainers, this meant that they needed to figure out why their global session variable wasn't returning expected results.
An easy way to get around this is to use session variables to store objects. It is almost just like object serialization to a file in Java; however, PHP won't serialize anything but the single object you want to store; it doesn't take care of class parents, interfaces being implemented or any other instantiated objects that may be required to maintain state. In PHP the developer is responsible for making sure that any object dependencies are also serialized and de-marshalled as needed.
The upside is that PHP will not only allow you to serialize your objects, but makes the serialization, marshaling process automatic.
So if you're using sessions for your site anyway, you can get object persistence for free. Just assign your object by reference to the session variable that you want to use. So, for our Client example above, we'd do something like this:
$client_object = &$_SESSION['client_object'];
$client_object = new Client( $client_id );
print( "First Name: " . $client_object->getClientFname() . "\n" );
print( "Last Name: " . $client_object->getClientLname() . "\n" );
print( "Balance Due: " . $client_object->getClientBalance() . "\n" );
One caveat here is that your class must be defined before the session_start() function call is made in your program. This is easy if you're using an __autoload() function to provide access to your classes; just place the session_start() call after your __autoload() and everything should Just Work.
Posted in PHP, Development | Tags object, oop, persistence, php
Posted by Tres
Thu, 01 May 2008 02:12:00 GMT
Here’s a little look at big O notation. It’s by no means complete, but it is an initial overview of what big O is, and why it’s important in Computer Science.
By analyzing the complexity of an algorithm, big O allows the estimation of the resources required to complete an operation with a large data set. On a graph, it defines the asymptotic upper bound for the algorithm.
Big O indicates how the resource consumption shifts with the size of the data. It does not deal with the efficiency of an algorithm, it only deals with efficiency via the fundamental fact that efficiency will be affected by algorithms that require more resources to complete an operation than those that require less resources. It’s a subtle, but meaningful difference when you account for the fact that in big O notation, you’re only using the “dominant term” to define the resources required. So for two constant algorithms, one that takes (i) and one that takes (3i), big O would denote both of these as simply O(i). Of course one is three times more efficient than the other, but big O is not concerned with that, only with the growth rate for larger data sets.
Posted in Development | Tags big O, computer science, notation
Posted by Tres
Wed, 30 Apr 2008 06:38:00 GMT
If you’re experiencing problems with TextMate’s subversion commit window, the diff history or other UI windows just crashing, the problem may be because of Mac Ports.
Check out /var/log/system.log to find out where the crash log was written to. You should see something like this:
Apr 12 18:33:50 blas.phemo.us ReportCrash[1486]: Saved crashreport to /Users/tres/Library/Logs/CrashReporter/mate_2008-04-12-183348_ishmael.crash using uid: 512 gid: 512, euid: 512 egid: 512
Check out the contents of the file and you’ll see something like this:
Process: mate [485]
Path: /Applications/TextMate.app/Contents/SharedSupport/Support/bin/mate
Identifier: mate
Version: ??? (???)
Code Type: X86 (Native)
Parent Process: ruby [471]
Date/Time: 2008-04-29 18:33:48.373 -0700
OS Version: Mac OS X 10.5.2 (9C7010)
Report Version: 6
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000
Crashed Thread: 0
Dyld Error Message:
Symbol not found: __cg_jpeg_resync_to_restart
Referenced from: /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Versions/A/ImageIO
Expected in: /opt/local/lib/libJPEG.dylib
The important things to look for is the contents of the Dyld Error Message.
If you’re seeing a libjpeg error, it’s due to the installed version of libjpeg that you’ve got through Mac Ports. Luckily this is an easy one to resolve. Just copy the version from /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Resources/libJPEG.dylib to /opt/local/lib/libJPEG.dylib
sudo cp /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Resources/libJPEG.dylib /opt/local/lib/libJPEG.dylib
Posted in OS X, Development | Tags crash, subversion, textmate, window
Posted by Tres
Sun, 20 Apr 2008 07:26:00 GMT
Sometimes you just need to hand control over to an external command via the exec built-in function in PHP. But
whenever you transfer control of a process to an external command, there’s a chance of your app hanging.
To safely run system commands you should wrap your exec call in the process control functions. The following is an example class that uses process control functions to ensure that a call to an external system command gets returned back.
/**
*
*
*
* @copyright 2008
* @package ProjectX
* @subpackage SystemResources
* @author Tres Wong-Godfrey
*
*/
/**
* Sys handles system execution, ensuring that the external call will be returned to us.
*/
//set up signal callback mechanism
declare(ticks=1);
class Sys {
/**
* Handles the signal alarm timer for the process
*
* @throws TimeoutException when called
* @param integer the signal that will be
*/
public static function alarm( $signal )
{
throw new TimeoutException(__CLASS__.'::'.__FUNCTION__ . ":: a Timeout occured while attempting to run the external system call.");
}
/**
* This sets the timeout for the external command so that we can ensure control gets returned
* to us.
*
* @param int The timeout for the external command in seconds
* @access public
*/
public static function setAlarm($timeout)
{
pcntl_signal(SIGALRM, array($this, 'alarm'));
pcntl_alarm($timeout);
}
/**
* Cancels the previously set alarm
*/
public static function unsetAlarm() { pcntl_alarm(0); }
/**
* This is a modified exec(). It is responsible for setting the
* timeout alarm and handling any invalid returns.
*
* <code>
* $command = "ls /";
* try {
* Sys::execute( $command, 90 );
* } catch( TimeoutException $e ) {
* //handle timeout
* } catch( ExternalApplicationException $e ) {
* //handle problems with external app running
* }
* </code>
*
* @param string $cmd
* @param int Optional. Time in seconds until the process alarm timer expires. Defaults to 10.
* @throws ExternalApplicationException if the external call does not return 0.
* @return string The output from the external command
*/
public static function execute( $cmd, $timeout=10)
{
self::setAlarm($timeout);
$last_line=exec("$cmd 2>&1", $output, $return_value);
self::unsetAlarm();
if ($return_value != 0)
throw new ExternalApplicationException(__CLASS__.'::'.__FUNCTION__ . ":: command $cmd failed. :: output = $output" );
else
return implode("\n", $output);
}
}
pre>
Posted in PHP, Development | Tags control, external, pcntl, php, process, run
Posted by Tres
Sun, 20 Apr 2008 00:36:00 GMT
Here’s a little ruby hackery to do convert the output we got here into something like this:
MB total: 2432.0
MB used: 479.6953125
MB free: 1952.3046875
#!/usr/bin/env ruby
require 'optparse'
options = {}
outprint = {}
ot = String
opts = OptionParser.new do |opts|
opts.on("-p X", "--path X", String, "path to partition for host") do |path|
options[:path] = path
end
end
opts.parse!(ARGV)
output = `dumpe2fs -h #{options[:path]}`
output.squeeze!(" ")
output.each do | line |
line.grep(/Block count:/) { | total | outprint[:total_label] ,outprint[:total_data] = total.chomp.split(/\s*\:\s*/) }
line.grep( /Free blocks:/) { | free | outprint[:free_label], outprint[:free_data] = free.chomp.split(/\s*\:\s*/) }
line.grep(/Block size:/) { | size | outprint[:block_size_label], outprint[:block_size_data] = size.chomp.split(/\s*\:\s*/) }
line.grep(/Reserved block count:/) { | reserved | outprint[:reserved_label], outprint[:reserved_data] = reserved.chomp.split(/\s*\:\s*/) }
end
mb_available = ( outprint[:block_size_data].to_f / 1048576 * outprint[:total_data].to_f )
mb_free = ( outprint[:block_size_data].to_f / 1048576 * outprint[:free_data].to_f )
mb_used = ( mb_available.to_f - mb_free.to_f )
puts "MB total: #{mb_available}"
puts "MB used: #{mb_used}"
puts "MB free: #{mb_free}"
typo:code>
The ruby script takes a single argument, the path to the device that is going to be looked at. It can be passed with either a -p or –path.
Posted in Linux, Ruby, Sysadmin, Xen, Development | Tags DomU, memory, monitor, ruby, script, Xen
Posted by Tres
Sat, 19 Apr 2008 14:12:00 GMT
PHP’s implementation of Exceptions works just like you’d expect it to, except for the missing finally statement.
In Java, we could do something like this:
try {
//create a new widget
Widget widget = new Widget();
//here's where we lock the widget before we take action
widget.lock();
widget.doStuf();
} catch( TimeoutException e ) {
widget.fixTimeoutException();
} catch( ConnectionException e ) {
widget.resetConnection();
} catch( PermissionException e ) {
widget.exit();
} catch( FantasticException e ) {
widget.goBallistic();
} finally {
//make sure that we're unlocking the widget since we put a lock on it before
widget.unlock();
}
But when describing the same thing in PHP, we’ve got to do it like this because there’s no finally available:
try{
//create a new widget
$widget = new Widget();
//here's where we lock the widget before we take action
$widget->lock();
$widget->doStuff();
} catch( TimeoutException $e ) {
$widget->fixTimeoutException();
//make sure that we're unlocking the widget since we put a lock on it before
$widget->unlock();
} catch( ConnectionException $e ) {
$widget->resetConnection();
//make sure that we're unlocking the widget since we put a lock on it before
$widget->unlock();
} catch( PermissionException $e ) {
$widget->exit();
//make sure that we're unlocking the widget since we put a lock on it before
$widget->unlock();
} catch( FantasticException $e ) {
$widget->goBallistic();
//make sure that we're unlocking the widget since we put a lock on it before
$widget->unlock();
}
It’s great to have exceptions in PHP, don’t get me wrong, it just took me by surprise that the implementation wasn’t complete.
Posted in PHP, Java, Development | Tags exceptions, finally, missing, php