Project

parallizer

0.01
No commit activity in last 3 years
No release in over 3 years
Execute your service layer in parallel.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 0
~> 2.9.0

Runtime

>= 0.0.11
 Project Readme

Parallizer - Execute your service layer in parallel

Parallizer executes service methods in parallel, stores the method results, and creates a proxy of your service with those results. Your application then uses the short-lived service proxy (think of a single request for a web application) and calls your methods without again executing the underlying implementation. For applications that make considerable use of web service calls, Parallizer can give you a considerable performance boost.

Installation

gem install parallizer

Examples

Parallizing a service object

Here's an example service.

require 'rubygems'
require 'net/http'
require 'nokogiri'

class SearchService
  def top_urls_for_foo
    parse_search_result_for_urls(Net::HTTP.get('www.google.com', '/search?q=foo'))
  end
  
  def top_urls_for_bar
    parse_search_result_for_urls(Net::HTTP.get('www.google.com', '/search?q=bar'))
  end
  
  private
  
  def parse_search_result_for_urls(content)
    Nokogiri::HTML.parse(content).search('h3.r > a').collect(&:attributes).collect{ |attrs| attrs['href'].value }
  end
end

$search_service = SearchService.new

Now create a Parallizer for that service and add all of the methods you intend to call. This begins the execution of the service methods in worker threads. Then create a service proxy that uses the stored results of the method calls.

require 'parallizer'

parallizer = Parallizer.new($search_service)
parallizer.add.top_urls_for_foo
parallizer.add.top_urls_for_bar
search_service = parallizer.create_proxy

Now use that service proxy in your application logic. Calls to these methods will not make an HTTP request and will not parse HTML. That was done by the parallel worker threads.

puts search_service.top_urls_for_foo
puts search_service.top_urls_for_bar

Additional calls in your application logic will not result in an additional call to the underlying service.

# Called twice, but no extra service call. (Be careful not to mutate the returned object!)
puts search_service.top_urls_for_foo
puts search_service.top_urls_for_foo

If there are additional methods on your service that were not parallized, you can still call them.

puts search_service.top_urls_for_foobar # makes an HTTP request and parses result

Parallizing methods with parameters

Parallizing also works on service methods with parameters.

require 'net/http'
require 'nokogiri'
require 'cgi'

class SearchService
  def top_urls(search_term)
    parse_search_result_for_urls(Net::HTTP.get('www.google.com', "/search?q=#{CGI.escape(search_term)}"))
  end
  
  private
  
  def parse_search_result_for_urls(content)
    Nokogiri::HTML.parse(content).search('h3.r > a').collect(&:attributes).collect{ |attrs| attrs['href'].value }
  end
end

$search_service = SearchService.new

The parallel execution and proxy creation.

require 'parallizer'

parallizer = Parallizer.new($search_service)
parallizer.add.top_urls('foo')
parallizer.add.top_urls('bar')
search_service = parallizer.create_proxy

Using the service proxy in your application logic.

puts search_service.top_urls('foo') # returns stored value
puts search_service.top_urls('bar') # returns stored value
puts search_service.top_urls('foobar') # makes an HTTP request and parses result

Parallizing class methods

You can even parallize class methods.

require 'net/http'
require 'parallizer'

parallizer = Parallizer.new(Net::HTTP)
parallizer.add.get('www.google.com', '/search?q=foo')
parallizer.add.get('www.google.com', '/search?q=bar')
http_service = parallizer.create_proxy

Use the service proxy.

# use your service proxy
http_service.get('www.google.com', '/search?q=foo') # returns stored value
http_service.get('www.google.com', '/search?q=bar') # returns stored value
http_service.get('www.google.com', '/search?q=foobar') # makes an HTTP request and parses result

Service Method Retries

Parallize also allows you to retry methods that fail (any exception raised is considered a failure).

require 'net/http'
require 'parallizer'

parallizer = Parallizer.new(Net::HTTP, :retries => 3)
parallizer.add.get('www.google.com', '/search?q=foo')
http_service = parallizer.create_proxy

http_service.get('www.google.com', '/search?q=foo') # Will be called up to 4 times

Retrieve all results

You can also execute all added methods in parallel and get all the results.

require 'net/http'
require 'parallizer'

parallizer = Parallizer.new(Net::HTTP)
parallizer.add.get('www.google.com', '/search?q=foo')
parallizer.add.get('www.google.com', '/search?q=bar')

call_results = parallizer.all_call_results
# {
#   [:get, 'www.google.com', '/search?q=foo'] => ...,
#   [:get, 'www.google.com', '/search?q=foo'] => ...
# }

Credits

Parallizer is maintained by Michael Pearce and is funded by Rafter.

Rafter Logo

Copyright

Copyright (c) 2012 Michael Pearce, Rafter.com. See LICENSE.txt for further details.