Mac_pc

For a few years I have been experimenting with virtualization software and technology. Virtualization is not new, and chances are that some of the programs you use on a daily basis using simulation. Manufacturers want to pack as many features as possible into their products and virtualization allows them to create more attractive offerings to purchasers.

It has been only recently, however, that virtualization has caught the public eye as software has evolved to the level where entire operating systems can now be virtualized. Thanks to virtualization Macs can now run Windows, PC's can run Linux and a single computer can run several systems simultaneously. For Killswitch, virtualization means the ability to assess our development solutions in different computing environments without incurring the overhead of purchasing new machines.

Pros and Cons of Virtualization

Here are some possible benefits of integrating virtualization into your workflow:

  1. It allows businesses and power users to test and assess solutions in different environments and configurations on a single machine.
  2. It gives businesses the ability to test out a new system without having to purchase dedicated hardware for it.
  3. It gives power users and businesses the flexibility to switch between different operational environments (for example, between desktop work and local server environments).
  4. It saves money because a system can run on pre-existing hardware.

There can, however, be certain drawbacks:

  1. Older hardware may not have the processing power to successfully run the native system, virtualization and the guest system.
  2. Some functions and features may not work correctly if there are system incompatibilities with the hardware.
  3. Memory limitations may prohibit the environment you are trying to test from properly installing.

Overcoming Obstacles

In my opinion, the biggest obstacles to widespread virtualization are memory limitations and company end user policies. We are barely breaking out of the 4 GB memory limitation that has plagued the computing world for the past several years. Finally there are motherboards that allow users to upgrade from the 4 gigabyte limit to 8 or 16 GB, provided you use the right processor and operating system. The more memory available on a system, the better a computer running virtual systems can handle errors and bottlenecks.

The other problem, which is progressively getting more annoying, is a company's EULA. I understand a company's need to protect its profit margin, but that should not come at the cost of consumer satisfaction. Allowing virtualization of a product does not take away from it; in fact, if the product in question is stable and user friendly, that product will fly off the shelves!

Let's say that your computer is running Ubuntu, but a piece of software you need is available for Windows only, there simply is no equivalent for the Ubuntu platform. What's a user to do? Obviously, you could go out, spend a lot of money and buy a new Windows machine to that one program. Thanks to virtualization, however, you can now load a copy of Parallels Linux on your machine and install Windows XP or Vista. Note: Virtualizing Vista Business and Ultimate violates the software's EULA. If anything goes wrong, you are on your own.

Here at Killswitch we primarily use Macintosh computers, so virtualizing Windows XP has come in handy. At one point we had a client who misplaced some Flash source files that were used to create a .swf file on their site. Wanting to change the content in this .swf file, we needed a SWF decompiler (and we needed it fast). Though we were concerned when we found out the program we needed was Windows only, we were quickly relieved as it ran perfectly on our Macs using Parallels.

Based on my personal experience, here are some software virtualization solutions that I would recommend:

Mac Software

Parallels: This is one of the premiere software packages that you can use to emulate another computing environment. The interface is clear and everything is well explained. I use this both in the office and personally at home.

VMware: I have used VMware and it is right up there with Parallels. Some of the more advanced functions are a little complicated, but there are several tutorials online that can help clear up confusion.

Windows Software

Virtual PC: This software is a veteran commercial product and is a leading virtualization program for PCs with a robust feature set.

Virtual Box: This program is free and very straight forward. You can load Windows, Linux and other operating systems, as well as server environments.



Rails_conf

Let's face it, everything seems to move at a breakneck pace in our industry. It seems like every other day there is a new start-up with some amazing product that's supposed to change the way all of us work. At least once a week I get software update notifications for some application or another. It is our job (and usually our passion) as developers to keep up with the tools that we use, and constantly be evaluating these upgrades, new features or sometimes even the alternatives. As a Ruby on Rails shop, there is nowhere better to check the pulse of the Rails community than RailsConf 2008.

RailsConf 2008 was held in Portland, Oregon again this year and Chris and myself had the chance to experience it first hand. It was the first RailsConf for both of us so our expectations were high, and for the most part we weren't disappointed. We met some really cool people from all over the world (including the cool guys from Blue Box Group), picked up a ton of information on where things with the Rails community are headed, and Chris even held a Birds of a Feather (BOF) discussion about his GiftWrap plugin.

There's simply too much to cover in a single blog post for those who couldn't make it, so please excuse my brevity. You can check out O'Reilly's website to read all about the events and schedules, and you can even grab most of the presentation materials there too.

Maybe my surprise was simply because this was my first RailsConf, but some of the best stuff for me wasn't specifically related to Rails! I went to a cool BOF on Rails alternatives, an interesting discussion about frameworks like Merb, Rack, and Mack, and we even got into the DataMapper ORM and replacing Subversion with Git. I also saw some great presentations on meta-programming, the internal workings of Git, and perhaps the topic I was most curious about – Phusion Passenger. I also enjoyed the well-delivered keynotes from Joel Spolsky and DHH. All these things gave me a taste for what else is out there, and how people are using not only Rails but other tools as well in our industry. The BOF sessions were great as well, bringing small groups of really bright people together to just chat about different topics. Oh, and the food rocked – plus all the Starbucks coffee you can handle, sweet.

That said, there were a few things that weren't so great that I thought I should share as well. The topic of scalability has been a hot one since way back when. Maybe it's just because we've built several high-traffic applications, but the scalability issue has been beaten to death in my opinion, and was beaten quite a bit more this year with about 5 talks covering scalability. Also, the tutorials weren't really worth the extra fees in my opinion – don't get me wrong, they were useful and interesting, but several of the topics ended up being covered in other sessions that were part of the conference, some of them were even the exact same presentation! Finally, while it was great to get a feel for a lot of the other tools out there being used, I must admit I was hoping for a bit more Rails-specific content. It was great to see the keynote by Jeremy Kemper announcing Rails 2.1 (some great stuff in there), but I still don't have a feel for the roadmap of development for Rails and where things are going next.

Overall RailsConf was great, and Portland was a great location for it (despite the 4+ hour flight from Chicago). Would I recommend it? Absolutely. You won't find a collection of brighter developers out there than the ones in the Rails community. Everyone seems to 'get it' and they're all interested in advancing the framework and expanding Rails into the main stream. So thanks to everyone who presented, it was quite an experience – see you next year!



Globalize

Just give me the globalize_with_google plugin now!

Anybody who's looked into localizing or internationalizing a Rails app has probably come across the "Globalize" plugin. It's a bit of an 800 lb. gorilla in the sense that it supports potentially hundreds of languages, automatic generation of validation messages, and even multiple pluralization cases based on the exact number of objects being counted. (There's a story about a people whose language only had three numbers- 1, 2, and 'many'. Globalize can handle that!) But as long as installation is as easy as "script/plugin install ...", who cares how much the gorilla weighs?

On a related note, Google recently released a series of AJAX APIs that are dead-simple to plug in to any web app, including one that does automatic translation. Can you guess where I'm going with this?

As soon as I saw Google's announcement that they were offering a free translation API, I started thinking about how to write a plugin that used it to initialize a Globalize database.

My solution, as sketched on the back of a napkin, had two pieces: The first would override Globalize's "String.translate" method. The other one would cache the translations so we still had a checklist of phrases for professional translators to go over, if necessary, and so we weren't dependent on the uptime of Google's servers for the functionality of our application. (Not that Google has lousy uptime; but if by chance they ever take down the service or start charging for translations, we can't have our translations just turn off).

The Actual Translation

This part was the easiest. We just modify Globalize's ".t" method to use Google's translation service:

module String
  def self.included(base)
    base.send :alias_method_chain, :translate, :google
    base.send :alias_method, :t, :translate
  end
  def translate_with_google(default = nil, arg = nil)
    local_base_language = defined?(BASE_LANGUAGE) ? BASE_LANGUAGE : 'en'

    #don't translate this if it's already written in the target language
    return self if Locale.language.iso_639_1 == local_base_language

    result = Locale.translate(self, '__translate__', arg)
    return result unless result ==  '__translate__' 

    return %Q{<span id="translation_#{self.object_id}">#{self}</span>
                <script type="text/javascript"> 
                ......}
    end
  end

The only flaw is that you can't use this on the labels of buttons or in javascript alert()s. Instead of showing a translated string, it would display a huge mess of javascript. I don't think there's a simple workaround for this, though, since the ".t" method can't know what context it is being called in. So in your views, make sure all of your translated buttons use something like

<input type="submit" value="<%= "Submit".translate_without_google %>" />

The Caching

This part nearly killed me. How do you cache the result of a google translation? It never goes through our server! The solution was a little convoluted, but very educational to a guy who had never written a plugin before.

First, we need to make the Javascript report the result of each translation back to our server. Fortunately, Google's "translate" function offers a callback once the translation is complete. So I just told it to execute the following:

new Ajax.Request('/cache_google_translation',{method: 'post', parameters: "phrase=#{self}&translation="+result.translation});

Next, we need a way for our Rails app to recognize the request for caching. But how can a plugin respond to a request like a controller does? It takes two steps. First you need to make a pseudo-controller that will do the caching:

class TricksController < ActionController::Base
  def cache_google_translation
    bound_vars = [params[:translation], params[:phrase]]
    ActiveRecord::Base.connection.execute("UPDATE globalize_translations SET built_in = 2, text = ? WHERE tr_key = ? AND language_id = #{Locale.language.id}".gsub('?'){ActiveRecord::Base.connection.quote(bound_vars.shift)})
    Locale.translator.put_in_cache(params[:phrase],Locale.language.iso_639_1,params[:translation])
    render :text => ''
  end
end

And then you need to extend Rails' route parser to attach a URL to your controller. (alias_method_chain to the rescue!)

module MapperExtensions
  def self.included(base)
    base.send :alias_method_chain, :initialize, :google_caching
  end
  def initialize_with_google_caching(set)
    #we have to add ours FIRST, otherwise the final line of the regular routes.rb is usually a catchall that would intercept OUR route
    set.add_route('/cache_google_translation',{:controller => 'google/tricks', :action => 'cache_google_translation'})
    initialize_without_google_caching(set)
  end
end

Finally, in your plugin's init file you just attach these classes into Rails:

ActionController::Routing::RouteSet::Mapper.send :include, Google::MapperExtensions
ActionView::Helpers::AssetTagHelper.send :include, Google::Javascript

And that's it! Well, not quite. Did you notice the reference to Locale.translator.put_in_cache? If you want to make sure that the auto-translations in your database are easily distinguishable so that you can have them manually translated later (machine translation isn't quite there yet!) then you have to add an extra step. It was easy enough to use a manual update statement instead of Locale.set_translation, which allowed me to set "built_in = 2" (that's how you recognize the auto-translations). But then the 800 lb. gorilla gets in the way. Globalize maintains a separate cache of translations in memory to avoid wear and tear on the database, but if you don't update the copy in memory as well, Globalize will never actually USE your cached version! It's a protected variable, so one more module extension:

module LocalizeCacheAccess
  def put_in_cache(key,language,translation)
    @cache["#{key}:#{language}:1"] = translation
  end
end

and then include it in your app with

Globalize::DbViewTranslator.send :include, Google::LocalizeCacheAccess

And that's it! Now you're REALLY done! To get all of this code in a simple Rails plugin, download globalize_with_google.zip and unpack it in #{RAILS_ROOT}/vendor/plugins/.




RSS Feed


CATEGORIES


ARCHIVES


BOOKMARKED


Add to Technorati Favorites