Skip to content

Commit c98c991

Browse files
committed
Rejiggered README
Incorporating all of what was on wiki main page, plus any other noticed missing classes. Serves as a table of contents linking to other docs. Examples moved to docs relevant to those examples.
1 parent 6239f09 commit c98c991

File tree

4 files changed

+144
-111
lines changed

4 files changed

+144
-111
lines changed

README.md

Lines changed: 54 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -35,115 +35,68 @@
3535
</tr>
3636
</table>
3737

38-
## Features & Documentation
39-
40-
Please see the [Concurrent Ruby Wiki](https://github.com/ruby-concurrency/concurrent-ruby/wiki)
41-
or the [API documentation](http://ruby-concurrency.github.io/concurrent-ruby/frames.html)
42-
for more information or join our [mailing list](http://groups.google.com/group/concurrent-ruby).
43-
44-
There are many concurrency abstractions in this library. These abstractions can be broadly categorized
45-
into several general groups:
46-
47-
* Asynchronous concurrency abstractions including
48-
[Agent](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Agent.html),
49-
[Async](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Async.html),
50-
[Future](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Future.html),
51-
[Promise](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promise.html),
52-
[ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ScheduledTask.html),
53-
and [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TimerTask.html)
54-
* Fast, light-weight [Actor model](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html) implementation.
55-
* Thread-safe variables including
56-
[I-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/IVar.html),
57-
[M-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MVar.html),
58-
[thread-local variables](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html),
59-
and [software transactional memory](https://github.com/ruby-concurrency/concurrent-ruby/wiki/TVar-(STM))
60-
* Thread synchronization classes and algorithms including
61-
[condition](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Condition.html),
62-
[countdown latch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html),
63-
[dataflow](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Dataflow),
64-
[event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html),
65-
[exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html),
66-
and [timeout](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#timeout-class_method)
67-
* Java-inspired [executors](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Thread%20Pools) (thread pools and more)
68-
* [And many more](http://ruby-concurrency.github.io/concurrent-ruby/index.html)...
69-
70-
### Semantic Versioning
71-
72-
This gem adheres to the rules of [semantic versioning](http://semver.org/).
73-
7438
### Supported Ruby versions
7539

76-
MRI 1.9.3, 2.0, 2.1, JRuby (1.9 mode), and Rubinius 2.x.
40+
MRI 1.9.3, 2.0, 2.1, JRuby (1.9 mode), and Rubinius 2.x are supported.
7741
Although native code is used for performance optimizations on some platforms, all functionality
7842
is available in pure Ruby. This gem should be fully compatible with any interpreter that is
7943
compliant with Ruby 1.9.3 or newer.
8044

81-
### Examples
82-
83-
Many more code examples can be found in the documentation for each class (linked above).
84-
85-
Future and ScheduledTask:
86-
87-
```ruby
88-
require 'concurrent'
89-
require 'thread' # for Queue
90-
require 'open-uri' # for open(uri)
91-
92-
class Ticker
93-
def get_year_end_closing(symbol, year)
94-
uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
95-
data = open(uri) {|f| f.collect{|line| line.strip } }
96-
data[1].split(',')[4].to_f
97-
end
98-
end
99-
100-
# Future
101-
price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
102-
price.state #=> :pending
103-
sleep(1) # do other stuff
104-
price.value #=> 63.65
105-
price.state #=> :fulfilled
106-
107-
# ScheduledTask
108-
task = Concurrent::ScheduledTask.execute(2){ Ticker.new.get_year_end_closing('INTC', 2013) }
109-
task.state #=> :pending
110-
sleep(3) # do other stuff
111-
task.value #=> 25.96
112-
```
45+
## Features & Documentation
46+
47+
We have a roadmap guiding our work toward the [v1.0.0 release](https://github.com/ruby-concurrency/concurrent-ruby/wiki/v1.0-Roadmap).
48+
49+
The primary site for documentation is the automatically generated [API documentation](http://ruby-concurrency.github.io/concurrent-ruby/frames.html)
50+
51+
We also have a [mailing list](http://groups.google.com/group/concurrent-ruby).
52+
53+
This library contains a variety of concurrency abstractions at high and low levels. One of the high-level abstractions is likely to meet most common needs.
54+
55+
### High-level, general-purpose asynchronous concurrency abstractions
56+
57+
* [Actor](./doc/actor/main.md): Implements the Actor Model, where concurrent actors exchange messages.
58+
* [Agent](./doc/agent.md): A single atomic value that represents an identity.
59+
* [Async](./doc/async.md): A mixin module that provides simple asynchronous behavior to any standard class/object or object.
60+
* [Future](./doc/future.md): An asynchronous operation that produces a value.
61+
* [Dataflow](./doc/dataflow.md): Built on Futures, Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available.
62+
* [Promise](./doc/promise.md): Similar to Futures, with more features.
63+
* [ScheduledTask](./doc/scheduled_task.md): Like a Future scheduled for a specific future time.
64+
* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TimerTask.html): A Thread that periodically wakes up to perform work at regular intervals.
65+
66+
67+
### Java-inspired ThreadPools and other executors
68+
69+
* See [ThreadPool](./doc/thread_pools.md) overview, which also contains a list of other Executors available.
70+
71+
### Thread-safe Observers
72+
73+
* [Concurrent::Observable](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Observable.html) mixin module
74+
* [CopyOnNotifyObserverSet](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CopyOnNotifyObserverSet.html)
75+
* [CopyOnWriteObserverSet](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CopyOnWriteObserverSet.html)
76+
77+
### Thread synchronization classes and algorithms
78+
Lower-level abstractions mainly used as building blocks.
79+
80+
* [condition](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Condition.html)
81+
* [countdown latch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html)
82+
* [cyclic barrier](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CyclicBarrier.html)
83+
* [event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html)
84+
* [exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html)
85+
* [timeout](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#timeout-class_method)
86+
* [timer](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#timer-class_method)
87+
88+
### Thread-safe variables
89+
Lower-level abstractions mainly used as building blocks.
90+
91+
* [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicBoolean.html)
92+
* [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicFixnum.html)
93+
* AtomicReference (no docs currently available, check source)
94+
* [I-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/IVar.html) (IVar)
95+
* [M-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MVar.html) (MVar)
96+
* [thread-local variables](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html)
97+
* [software transactional memory](./doc/tvar.md) (TVar)
11398

114-
Actor:
11599

116-
```ruby
117-
class Counter < Concurrent::Actor::Context
118-
# Include context of an actor which gives this class access to reference
119-
# and other information about the actor
120-
121-
# use initialize as you wish
122-
def initialize(initial_value)
123-
@count = initial_value
124-
end
125-
126-
# override on_message to define actor's behaviour
127-
def on_message(message)
128-
if Integer === message
129-
@count += message
130-
end
131-
end
132-
end #
133-
134-
# Create new actor naming the instance 'first'.
135-
# Return value is a reference to the actor, the actual actor is never returned.
136-
counter = Counter.spawn(:first, 5)
137-
138-
# Tell a message and forget returning self.
139-
counter.tell(1)
140-
counter << 1
141-
# (First counter now contains 7.)
142-
143-
# Send a messages asking for a result.
144-
counter.ask(0).class
145-
counter.ask(0).value
146-
```
147100

148101
## Installing and Building
149102

doc/actor/main.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,40 @@ It is simpler to reason about actors than about locks (and all their possible st
2424

2525
## How to use it
2626

27+
An example:
28+
29+
```ruby
30+
class Counter < Concurrent::Actor::Context
31+
# Include context of an actor which gives this class access to reference
32+
# and other information about the actor
33+
34+
# use initialize as you wish
35+
def initialize(initial_value)
36+
@count = initial_value
37+
end
38+
39+
# override on_message to define actor's behaviour
40+
def on_message(message)
41+
if Integer === message
42+
@count += message
43+
end
44+
end
45+
end #
46+
47+
# Create new actor naming the instance 'first'.
48+
# Return value is a reference to the actor, the actual actor is never returned.
49+
counter = Counter.spawn(:first, 5)
50+
51+
# Tell a message and forget returning self.
52+
counter.tell(1)
53+
counter << 1
54+
# (First counter now contains 7.)
55+
56+
# Send a messages asking for a result.
57+
counter.ask(0).class
58+
counter.ask(0).value
59+
```
60+
2761
{include:file:doc/actor/quick.out.rb}
2862

2963
## Messaging

doc/future.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,35 @@ The `Future` class also includes the behavior of the Ruby standard library [Obse
1919

2020
A fulfilled example:
2121

22-
```ruby
22+
```ruby
2323
require 'concurrent'
24+
require 'thread' # for Queue
25+
require 'open-uri' # for open(uri)
2426

25-
count = Concurrent::Future.new{ sleep(10); 10 }.execute
26-
count.state #=> :pending
27-
count.pending? #=> true
27+
class Ticker
28+
def get_year_end_closing(symbol, year)
29+
uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
30+
data = open(uri) {|f| f.collect{|line| line.strip } }
31+
data[1].split(',')[4].to_f
32+
end
33+
end
2834

29-
# do stuff...
35+
# Future
36+
price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
37+
price.state #=> :pending
38+
price.pending? #=> true
39+
price.value(0) #=> nil (does not block)
3040

31-
count.value(0) #=> nil (does not block)
41+
sleep(1) # do other stuff
3242

33-
count.value #=> 10 (after blocking)
34-
count.state #=> :fulfilled
35-
count.fulfilled? #=> true
36-
count.value #=> 10
43+
price.value #=> 63.65 (after blocking if neccesary)
44+
price.state #=> :fulfilled
45+
price.fulfilled? #=> true
46+
price.value #=> 63.65
3747
```
3848

49+
50+
3951
A rejected example:
4052

4153
```ruby
@@ -48,6 +60,10 @@ count.rejected? #=> true
4860
count.reason #=> #<StandardError: Boom!>
4961
```
5062

63+
64+
65+
66+
5167
An example with observation:
5268

5369
```ruby

doc/scheduled_task.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
`ScheduledTask` is a close relative of `Concurrent::Future` but with one important difference. A `Future` is set to execute as soon as possible whereas a `ScheduledTask` is set to execute at a specific time. This implementation is loosely based on Java's [ScheduledExecutorService](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html).
22

3+
### Example
4+
5+
```ruby
6+
require 'concurrent'
7+
require 'thread' # for Queue
8+
require 'open-uri' # for open(uri)
9+
10+
class Ticker
11+
def get_year_end_closing(symbol, year)
12+
uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
13+
data = open(uri) {|f| f.collect{|line| line.strip } }
14+
data[1].split(',')[4].to_f
15+
end
16+
end
17+
18+
# Future
19+
price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
20+
price.state #=> :pending
21+
sleep(1) # do other stuff
22+
price.value #=> 63.65
23+
price.state #=> :fulfilled
24+
25+
# ScheduledTask
26+
task = Concurrent::ScheduledTask.execute(2){ Ticker.new.get_year_end_closing('INTC', 2013) }
27+
task.state #=> :pending
28+
sleep(3) # do other stuff
29+
task.value #=> 25.96
30+
```
31+
32+
333
### Scheduling
434

535
The *intended* schedule time of task execution is set on object construction with first argument. The time can be a numeric (floating point or integer) representing a number of seconds in the future or it can ba a `Time` object representing the approximate time of execution. Any other value, a numeric equal to or less than zero, or a time in the past will result in an exception.

0 commit comments

Comments
 (0)