Skip to content

Instantly share code, notes, and snippets.

@amanelis
Created September 16, 2014 16:03
Show Gist options
  • Save amanelis/cf869c32e601373c7eaf to your computer and use it in GitHub Desktop.
Save amanelis/cf869c32e601373c7eaf to your computer and use it in GitHub Desktop.
Ruby concurrency using the 'concurrent' package.
# gem install concurrent-ruby
require 'rubygems'
require 'concurrent'
require 'thread'
require 'open-uri'
module Galaxy
class Ticker
def self.get_year_end_closing(symbol, year)
uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
data = open(uri) {|f| f.collect{|line| line.strip } }
data[1].split(',')[4].to_f
end
end
class Hoth
attr_accessor :document
def initialize(args={})
@document = open_document
end
def results
return {
start: Time.now,
count_letters: self.count_letters,
count_unique_letters: self.count_unique_letters,
count_words: self.count_words,
finish: Time.now,
process: Process.pid
}
end
def count_letters
sleep 2
@document.length
end
def count_unique_letters
sleep 2
@document.scan(/\w/).inject(Hash.new(0)){|h, c| h[c] += 1; h}
end
def count_words
sleep 2
@document.split(' ').count
end
def open_document
sleep 2
@document = open(default_text_file).read.gsub(/\r/,"").gsub(/\n/, "").strip.chomp
end
def default_text_file
return 'http://textfiles.com/food/boarchil.txt'
end
end
end
process = []
symbols = [
'aapl',
'goog',
'fb',
'c',
'a',
'm',
'bac',
'intc',
'siri',
'ge',
'msft'
]
# Future (non blocking), will deliver these results, while execution of other code continues
symbols.each { |s| process << Concurrent::Future.execute { Galaxy::Ticker.get_year_end_closing(s, 2013) } }
puts "Enqueued processes to fetch stock prices, they will run behind Galaxy"
puts "Running Galaxy, it is the epitome of blocking code"
# Synchronous blocking code has multiple sleeps, a web request, this will block everything
# except Concurrent::Futures
puts "Start Galaxy: #{Time.now}"
puts " processes before -> #{process.collect(&:state)}"
Galaxy::Hoth.new.results
puts "Finish Galaxy: #{Time.now}"
puts " processes after -> #{process.collect(&:state)}"
# Be sure to wait for any remaining processes, they should all be done...
while process.select { |x| x.state == :pending }.any? do end
process.each_with_index do |e,i|
puts "PROMISE[#{e.state}][#{symbols[i]}] -> #{e.value}"
end
puts "FINISHED: #{Time.now}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment