Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Cooperative multitasking for Ruby.
Ruby
Branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
spec
.gitignore
.travis.yml
Gemfile
Gemfile.lock
README.md
Rakefile
app.ru
green.gemspec

README.md

Green Build Status

Cooperative multitasking for Ruby. Proof of concept.

Based on Ruby 1.9 Fibers, but unlike EM::Synchrony it uses symmetric coroutines (only #current and #transfer used) and HUB-orientend architecture. So coroutines transfer control to HUB and HUB transfer control to coroutines. Coroutines never tranfer control to each other.

In comparison with EM-Synchrony it allows:

  • develop real complex cooperative multitasking apps;
  • timeouts. Yes, in common case you cannot add timeout with EM-Synchrony;
  • kill greens. And it safe unlike kill Threads;
  • works with REPL and debugger. EM-Synchrony uses Fiber.yield, so you cannot run nothing in REPL;
  • works with every environment. You can run nonblock web-applications with Unicorn;
  • compatible with Ruby's Enumerator and with any other uses of Fibers themself (see https://github.com/igrigorik/em-synchrony/issues/114)
require 'green'
require 'green/group'
require 'green-em/em-http'

g = Green::Pool.new(size: 2)

urls = ['http://google.com', 'http://yandex.ru']

results = g.enumerator(urls) do |url|
  EventMachine::HttpRequest.new(url).get
end.map { |i| i.response }

p results

You can run it from Irb! ;)

You can add timeout:

require 'green'
require 'green/group'
require 'green-em/em-http'

g = Green::Pool.new(size: 2)

urls = ['http://google.com', 'http://yandex.ru']

begin
  Green.timeout(1) do
    results = g.enumerator(urls) do |url|
      EventMachine::HttpRequest.new(url).get
    end.map { |i| i.response }
    p results
  end
rescue Timeout::Error
  p "Timeout!"
end

You can use net/http (and any gem over it):

require 'green'
require 'green/group'
require 'green/monkey'
require 'net/http'

g = Green::Pool.new(size: 2)

hosts = ['google.com', 'yandex.ru']

results = g.enumerator(hosts) do |host|
  Net::HTTP.get host, '/'
end.map { |i| i }

p results

You can run nonblock Web application with any webserver:

require 'green'
require 'green/group'

app = proc do |env|
  start = Time.now
  g = Green::Group.new
  results = []
  g.spawn do
    Green.sleep 1
    results << :fiz
  end
  g.spawn do
    Green.sleep 1
    results << :buz
  end
  g.join
  [200, {"Content-Type" => 'plain/text'}, ["Execution time: #{Time.now - start}; Results: #{results.inspect}"]]
end
run app 

Run it with unicorn app.ru

Something went wrong with that request. Please try again.