Skip to content

Commit 46e7bb0

Browse files
committed
Merge pull request #100 from ruby-concurrency/actress
Actress post release fixes
2 parents 49417cb + c0ce8b6 commit 46e7bb0

35 files changed

+967
-244
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ tests.txt
66
.ruby-gemset
77
.bundle/*
88
.yardoc/*
9-
doc/*
9+
yardoc/*
1010
tmp/*
1111
man/*
1212
*.tmproj

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ matrix:
1515
- rvm: ruby-head
1616
- rvm: jruby-head
1717
- rvm: 1.9.3
18+
script: "bundle exec rspec --color --backtrace --seed 1 --format documentation ./spec"

.yardopts

+13-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
1-
--protected --no-private --embed-mixins --output-dir ./doc --markup markdown
1+
--protected
2+
--no-private
3+
--embed-mixins
4+
--output-dir ./yardoc
5+
--markup markdown
6+
--title=Concurrent Ruby
7+
--template default
8+
--template-path ./yard-template
9+
10+
./lib/**/*.rb
11+
-
12+
README.md
13+
LICENSE.txt

Gemfile

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ group :development do
88
gem 'countloc', '~> 0.4.0', platforms: :mri
99
gem 'yard', '~> 0.8.7.4'
1010
gem 'inch', '~> 0.4.1', platforms: :mri
11+
gem 'redcarpet', platforms: :mri # understands github markdown
1112
end
1213

1314
group :testing do

LICENSE renamed to LICENSE.txt

File renamed without changes.

README.md

+38-35
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,59 @@
22
[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.png)](http://badge.fury.io/rb/concurrent-ruby) [![Build Status](https://travis-ci.org/ruby-concurrency/concurrent-ruby.svg?branch=master)](https://travis-ci.org/ruby-concurrency/concurrent-ruby) [![Coverage Status](https://coveralls.io/repos/ruby-concurrency/concurrent-ruby/badge.png)](https://coveralls.io/r/ruby-concurrency/concurrent-ruby) [![Code Climate](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby.png)](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby) [![Inline docs](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby.png)](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby) [![Dependency Status](https://gemnasium.com/ruby-concurrency/concurrent-ruby.png)](https://gemnasium.com/ruby-concurrency/concurrent-ruby)
33

44
<table>
5-
<tr>
6-
<td align="left" valign="top">
7-
<p>
8-
Modern concurrency tools for Ruby. Inspired by
9-
<a href="http://www.erlang.org/doc/reference_manual/processes.html">Erlang</a>,
10-
<a href="http://clojure.org/concurrent_programming">Clojure</a>,
11-
<a href="http://www.scala-lang.org/api/current/index.html#scala.actors.Actor">Scala</a>,
12-
<a href="http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell">Haskell</a>,
13-
<a href="http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx">F#</a>,
14-
<a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx">C#</a>,
15-
<a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html">Java</a>,
16-
and classic concurrency patterns.
17-
</p>
18-
<p>
19-
The design goals of this gem are:
20-
<ul>
21-
<li>Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why</li>
22-
<li>Remain free of external gem dependencies</li>
23-
<li>Stay true to the spirit of the languages providing inspiration</li>
24-
<li>But implement in a way that makes sense for Ruby</li>
25-
<li>Keep the semantics as idiomatic Ruby as possible</li>
26-
<li>Support features that make sense in Ruby</li>
27-
<li>Exclude features that don't make sense in Ruby</li>
28-
<li>Be small, lean, and loosely coupled</li>
29-
</ul>
30-
</p>
31-
</td>
32-
<td align="right" valign="top">
33-
<img src="https://raw.githubusercontent.com/wiki/ruby-concurrency/concurrent-ruby/logo/concurrent-ruby-logo-300x300.png"/>
34-
</td>
35-
</tr>
5+
<tr>
6+
<td align="left" valign="top">
7+
<p>
8+
Modern concurrency tools for Ruby. Inspired by
9+
<a href="http://www.erlang.org/doc/reference_manual/processes.html">Erlang</a>,
10+
<a href="http://clojure.org/concurrent_programming">Clojure</a>,
11+
<a href="http://www.scala-lang.org/api/current/index.html#scala.actors.Actor">Scala</a>,
12+
<a href="http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell">Haskell</a>,
13+
<a href="http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx">F#</a>,
14+
<a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx">C#</a>,
15+
<a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html">Java</a>,
16+
and classic concurrency patterns.
17+
</p>
18+
<p>
19+
The design goals of this gem are:
20+
<ul>
21+
<li>Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why</li>
22+
<li>Remain free of external gem dependencies</li>
23+
<li>Stay true to the spirit of the languages providing inspiration</li>
24+
<li>But implement in a way that makes sense for Ruby</li>
25+
<li>Keep the semantics as idiomatic Ruby as possible</li>
26+
<li>Support features that make sense in Ruby</li>
27+
<li>Exclude features that don't make sense in Ruby</li>
28+
<li>Be small, lean, and loosely coupled</li>
29+
</ul>
30+
</p>
31+
</td>
32+
<td align="right" valign="top">
33+
<img src="https://raw.githubusercontent.com/wiki/ruby-concurrency/concurrent-ruby/logo/concurrent-ruby-logo-300x300.png"/>
34+
</td>
35+
</tr>
3636
</table>
3737

38-
### Install
38+
## Install
3939

4040
```shell
4141
gem install concurrent-ruby
4242
```
43+
4344
or add the following line to Gemfile:
4445

4546
```ruby
4647
gem 'concurrent-ruby'
4748
```
49+
4850
and run `bundle install` from your shell.
4951

50-
*NOTE: There is an old gem from 2007 called "concurrent" that does not appear to be under active development. That isn't us. Please do not run* `gem install concurrent`*. It is not the droid you are looking for.*
52+
_NOTE: There is an old gem from 2007 called "concurrent" that does not appear to be under active development. That isn't us. Please do not run* `gem install concurrent`*. It is not the droid you are looking for._
5153

5254
## Features & Documentation
5355

5456
Please see the [Concurrent Ruby Wiki](https://github.com/ruby-concurrency/concurrent-ruby/wiki)
55-
or the [API documentation](http://rubydoc.info/github/ruby-concurrency/concurrent-ruby/master/frames)
57+
or the [API documentation](http://ruby-concurrency.github.io/concurrent-ruby/frames.html))
5658
for more information or join our [mailing list](http://groups.google.com/group/concurrent-ruby).
5759

5860
There are many concurrency abstractions in this library. These abstractions can be broadly categorized
@@ -74,6 +76,7 @@ into several general groups:
7476
* Thread synchronization classes and algorithms including [dataflow](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Dataflow),
7577
timeout, condition, countdown latch, dependency counter, and event
7678
* Java-inspired [thread pools](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Thread%20Pools)
79+
* New fast light-weighted [Actor model](http://ruby-concurrency.github.io/concurrent-ruby/frames.html#!Concurrent/Actress.html) implementation.
7780
* And many more...
7881

7982
### Semantic Versioning
@@ -91,7 +94,7 @@ It should be fully compatible with any interpreter that is compliant with Ruby 1
9194
Many more code examples can be found in the documentation for each class (linked above).
9295
This one simple example shows some of the power of this gem.
9396

94-
```ruby
97+
```ruby
9598
require 'concurrent'
9699
require 'thread' # for Queue
97100
require 'open-uri' # for open(uri)

doc/actress/celluloid_benchmark.rb

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
require 'benchmark'
2+
require 'concurrent/actress'
3+
Concurrent::Actress.i_know_it_is_experimental!
4+
require 'celluloid'
5+
require 'celluloid/autostart'
6+
7+
logger = Logger.new($stderr)
8+
logger.level = Logger::INFO
9+
Concurrent.configuration.logger = lambda do |level, progname, message = nil, &block|
10+
logger.add level, message, progname, &block
11+
end
12+
13+
scale = 1
14+
ADD_TO = (100 * scale).to_i
15+
counts_size = (500 * scale).to_i
16+
adders_size = (500 * scale).to_i
17+
18+
class Counter
19+
include Celluloid
20+
21+
def initialize(adders, i)
22+
@adders = adders
23+
@i = i
24+
end
25+
26+
def counting(count, ivar)
27+
if count < ADD_TO
28+
@adders[(@i+1) % @adders.size].counting count+1, ivar
29+
else
30+
ivar.set count
31+
end
32+
end
33+
end
34+
35+
threads = []
36+
37+
Benchmark.bmbm(10) do |b|
38+
[2, adders_size, adders_size*2, adders_size*3].each do |adders_size|
39+
40+
b.report(format('%5d %4d %s', ADD_TO*counts_size, adders_size, 'actress')) do
41+
counts = Array.new(counts_size) { [0, Concurrent::IVar.new] }
42+
adders = Array.new(adders_size) do |i|
43+
Concurrent::Actress::AdHoc.spawn("adder#{i}") do
44+
lambda do |(count, ivar)|
45+
if count.nil?
46+
terminate!
47+
else
48+
if count < ADD_TO
49+
adders[(i+1) % adders_size].tell [count+1, ivar]
50+
else
51+
ivar.set count
52+
end
53+
end
54+
end
55+
end
56+
end
57+
58+
counts.each_with_index do |count, i|
59+
adders[i % adders_size].tell count
60+
end
61+
62+
counts.each do |count, ivar|
63+
raise unless ivar.value >= ADD_TO
64+
end
65+
66+
threads << Thread.list.size
67+
68+
adders.each { |a| a << [nil, nil] }
69+
end
70+
71+
b.report(format('%5d %4d %s', ADD_TO*counts_size, adders_size, 'celluloid')) do
72+
counts = []
73+
counts_size.times { counts << [0, Concurrent::IVar.new] }
74+
75+
adders = []
76+
adders_size.times do |i|
77+
adders << Counter.new(adders, i)
78+
end
79+
80+
counts.each_with_index do |count, i|
81+
adders[i % adders_size].counting *count
82+
end
83+
84+
counts.each do |count, ivar|
85+
raise unless ivar.value >= ADD_TO
86+
end
87+
88+
threads << Thread.list.size
89+
90+
adders.each(&:terminate)
91+
end
92+
end
93+
end
94+
95+
p threads
96+

doc/actress/format.rb

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
require 'rubygems'
2+
require 'bundler/setup'
3+
require 'pry'
4+
require 'pp'
5+
6+
input_paths = if ARGV.empty?
7+
Dir.glob("#{File.dirname(__FILE__)}/*.in.rb")
8+
else
9+
ARGV
10+
end.map { |p| File.expand_path p }
11+
12+
input_paths.each_with_index do |input_path, i|
13+
14+
pid = fork do
15+
require_relative 'init.rb'
16+
17+
begin
18+
output_path = input_path.gsub /\.in\.rb$/, '.out.rb'
19+
input = File.readlines(input_path)
20+
21+
chunks = []
22+
line = ''
23+
24+
while !input.empty?
25+
line += input.shift
26+
if Pry::Code.complete_expression? line
27+
chunks << line
28+
line = ''
29+
end
30+
end
31+
32+
raise unless line.empty?
33+
34+
chunks.map! { |chunk| [chunk, [chunk.split($/).size, 1].max] }
35+
environment = Module.new.send :binding
36+
evaluate = ->(code, line) do
37+
eval(code, environment, input_path, line)
38+
end
39+
40+
indent = 50
41+
42+
line_count = 1
43+
output = ''
44+
chunks.each do |chunk, lines|
45+
result = evaluate.(chunk, line_count)
46+
unless chunk.strip.empty? || chunk =~ /\A *#/
47+
pre_lines = chunk.lines.to_a
48+
last_line = pre_lines.pop
49+
output << pre_lines.join
50+
51+
if last_line =~ /\#$/
52+
output << last_line.gsub(/\#$/, '')
53+
else
54+
if last_line.size < indent && result.inspect.size < indent
55+
output << "%-#{indent}s %s" % [last_line.chomp, "# => #{result.inspect}\n"]
56+
else
57+
output << last_line << " # => #{result.inspect}\n"
58+
end
59+
end
60+
else
61+
output << chunk
62+
end
63+
line_count += lines
64+
end
65+
66+
puts "#{input_path}\n -> #{output_path}"
67+
#puts output
68+
File.write(output_path, output)
69+
rescue => ex
70+
puts "#{ex} (#{ex.class})\n#{ex.backtrace * "\n"}"
71+
end
72+
end
73+
74+
Process.wait pid
75+
end

doc/actress/init.rb

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require 'concurrent/actress'
2+
Concurrent::Actress.i_know_it_is_experimental!

0 commit comments

Comments
 (0)