Skip to content

prepor/green

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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 igrigorik/em-synchrony#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

About

Cooperative multitasking for Ruby.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages