1. Welcome
  2. Getting Started [+/-]
    1. Installing from RubyGems
    2. Installing from GitHub.com
    3. Installing with Sake
  3. The Basics [+/-]
    1. Hello World
      1. Application Generation Options
    2. Paths
    3. Environments
    4. Rake
  4. Configuration [+/-]
    1. Configatron
    2. Initializers
      1. Gems
      2. Mime-Types
  5. Routing [+/-]
    1. Default Routes
    2. Named Routes
    3. RESTful/Resource Routes
    4. Nested Resource Routes
    5. Regex Routes
    6. Wildcard Routes
    7. Blocks in Routes
    8. Redirecting
    9. Error Handling
    10. Deferred? Routes
    11. Misc. Routing
  6. Controllers [+/-]
    1. Actions
    2. Headers/Status
    3. Handling Content Types
    4. Filters
    5. Helpers
    6. Layouts
    7. Tell Messaging
    8. Redirecting
    9. Rendering
      1. Engines
        1. Erubis
        2. XML Builder
        3. Extending
          1. Case Study: PDF Writer
      2. Types
        1. :action
        2. :text
        3. :inline
        4. :xml
        5. :url
        6. :partial
        7. :template
        8. :public
        9. Extending
          1. Case Study: PDF Writer
  7. Views [+/-]
    1. Helpers
    2. Layouts
    3. Assets Host
    4. Assets Management
    5. Form Builders
  8. Sessions [+/-]
    1. Session Store API
  9. Request/Response [+/-]
    1. Cookies
  10. Testing [+/-]
    1. RSpec
    2. Test::Unit::TestCase
  11. Porlets [+/-]
    1. Developing
    2. Testing
    3. Packaging
    4. Using
  12. Plugins [+/-]
    1. Extending
      1. Case Study: PDF Writer
  13. Deploying [+/-]
    1. Thin
    2. Passenger (mod_rails)
    3. Joyent Accelerator
  14. Mack More [+/-]
    1. mack-active_record
    2. mack-asset_packager
    3. mack-caching
    4. mack-data_factory
    5. mack-data_mapper
    6. mack-distributed
    7. mack-encryption
    8. mack-facets
    9. mack-haml
    10. mack-javascript
    11. mack-localization
    12. mack-markaby
    13. mack-notifier
    14. mack-orm
    15. mack-pdf_writer
  15. Rails to Mack Cheat Sheet
  16. Contributing
  17. APIs [+/-]

Distributed

Building distributed applications with Mack is quick an easy using the mack-distributed gem that can be found in versions of Mack >= 0.7.0.

'Server' side

It should be noted that although we're going to be talking about a 'server' app and a 'client' app, the mack-distributed packages allows for a many-to-many relationship, as far as services go, all apps can be both servers and clients.

Server-side configuration is a snap. First we need to require the mack-distributed gem:

# config/initializers/gems.rb
require_gems do |gem|
  gem.add "mack-data_mapper", :libs => "mack-data_mapper"
  gem.add "mack-distributed", :libs => "mack-distributed"
end

Then we need to make a few configuration setting changes:

# config/configatron/default.rb or your <environment>.rb file of choice

# Share your routes? true/false
configatron.mack.distributed.share_routes = true
# Share your objects? true/false
configatron.mack.distributed.share_objects = true
# Share your views/layouts? true/false
configatron.mack.distributed.share_views = true
# What is the UNIQUE name for this application?
# This is used to be able to register the services
# for this application with Rinda. It's also used
# so other applications can look up those services
# directly.
configatron.mack.distributed.app_name = 'my_cool_app'
# What is the fully qualified host for this application?
# This is used for building the full url for distributed
# routes.
configatron.mack.distributed.site_domain = 'http://www.example.com'

Once we've required the mack-distributed gem and have made our configuration changes all we really need to do is to start the mack_ring_server binary like so:

$ mack_ring_server start

If we were to start the 'server' app right now it would register it's routes and views/layouts with Rinda, and other applications would be able to find and use them.

If we want to register an Object with Rinda, that's really easy too. Let's pretend we have a User class, to share that class with our other applications we simply make the class look like this:

class User
  # By including Mack::Distributable this class will now
  # be registered with Rinda for other Mack applications 
  # to use.
  include Mack::Distributable

  def self.all
    # code here...
  end

  def self.authenticate(username, password)
    # code here....
  end

  def display_name
    # code here...
  end

end

'Client' side

All we need to do in our client application is require the mack-distributed gem:

# config/initializers/gems.rb
require_gems do |gem|
  gem.add "mack-data_mapper", :libs => "mack-data_mapper"
  gem.add "mack-distributed", :libs => "mack-distributed"
end

If were to fire up the Mack console we could do something like this:

Mack::Distributed::User.all

And it will call the all class method on the User class in our 'server' application. You can call any class level method on the User object at this point. Distributed objects/classes behave just as if they were local.

This works by using the 'magical' Mack::Distributed module. It will automatically look up the class you call in that module with Rinda and return back a proxy to the server app that houses that service.

If you want to get a particular service, from a particular application you can look it up like so:

Mack::Distributed.lookup("distributed://my_cool_app/User")

Using distributed routes in your views is also just as easy. You just need to know the name of the application that houses the route you want, and what the name of the route you want is.

Let's assume your 'server' application has a routes file that looks like this:

Mack::Routes.build do |r|

  r.login "/users/login", :controller => :users, :action => :login
  r.do_login "/users/login", :controller => :users, :action => :do_login, :method => :post

  r.resource :users # Added by rake generate:scaffold name=user

  r.with_options(:controller => :pages) do |map|
    map.newest_pages "/pages/newest_pages/:limit", :action => :newest_pages
    map.recently_updated_pages "/pages/recently_updated_pages/:limit", :action => :recently_updated_pages
  end

  r.resource :pages # Added by rake generate:scaffold name=page

  r.handle_error Miki::PageNotFoundError, :controller => :pages, :action => :not_found

  r.wiki_page "/:url", :controller => :pages, :action => :display

  r.home_page "/", :controller => :pages, :action => :display, :url => "home"

  r.defaults

end

In our client application we can get access to the url for the users index page like this:

<%= distributed_url(:my_cool_app, :users_index_url) %>

In our example that would return: 'http://www.example.com/users'

This guide was written for Mack version 0.8.2