Skip to content

Commit 229c114

Browse files
authored
Rust updates, better doc testing (#598)
Capture a bunch of changes I had sitting around for a while. Fixes a bug in the mdbook, but otherwise no functional changes. Signed-off-by: Moritz Hoffmann <[email protected]>
1 parent 5323fd6 commit 229c114

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+89
-160
lines changed

README.md

+6-10
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@ Be sure to read the [documentation for timely dataflow](https://docs.rs/timely).
1010

1111
To use timely dataflow, add the following to the dependencies section of your project's `Cargo.toml` file:
1212

13-
```
13+
```toml
1414
[dependencies]
1515
timely="*"
1616
```
1717

1818
This will bring in the [`timely` crate](https://crates.io/crates/timely) from [crates.io](http://crates.io), which should allow you to start writing timely dataflow programs like this one (also available in [timely/examples/simple.rs](https://github.com/timelydataflow/timely-dataflow/blob/master/timely/examples/simple.rs)):
1919

2020
```rust
21-
extern crate timely;
22-
2321
use timely::dataflow::operators::*;
2422

2523
fn main() {
@@ -32,7 +30,7 @@ fn main() {
3230

3331
You can run this example from the root directory of the `timely-dataflow` repository by typing
3432

35-
```
33+
```text
3634
% cargo run --example simple
3735
Running `target/debug/examples/simple`
3836
seen: 0
@@ -54,8 +52,6 @@ This is a very simple example (it's in the name), which only just suggests at ho
5452
For a more involved example, consider the very similar (but more explicit) [examples/hello.rs](https://github.com/timelydataflow/timely-dataflow/blob/master/timely/examples/hello.rs), which creates and drives the dataflow separately:
5553

5654
```rust
57-
extern crate timely;
58-
5955
use timely::dataflow::{InputHandle, ProbeHandle};
6056
use timely::dataflow::operators::{Input, Exchange, Inspect, Probe};
6157

@@ -96,7 +92,7 @@ We first build a dataflow graph creating an input stream (with `input_from`), wh
9692
We then drive the computation by repeatedly introducing rounds of data, where the `round` itself is used as the data. In each round, each worker introduces the same data, and then repeatedly takes dataflow steps until the `probe` reveals that all workers have processed all work for that epoch, at which point the computation proceeds.
9793

9894
With two workers, the output looks like
99-
```
95+
```text
10096
% cargo run --example hello -- -w2
10197
Running `target/debug/examples/hello -w2`
10298
worker 0: hello 0
@@ -120,7 +116,7 @@ The `hello.rs` program above will by default use a single worker thread. To use
120116
To use multiple processes, you will need to use the `-h` or `--hostfile` option to specify a text file whose lines are `hostname:port` entries corresponding to the locations you plan on spawning the processes. You will need to use the `-n` or `--processes` argument to indicate how many processes you will spawn (a prefix of the host file), and each process must use the `-p` or `--process` argument to indicate their index out of this number.
121117

122118
Said differently, you want a hostfile that looks like so,
123-
```
119+
```text
124120
% cat hostfile.txt
125121
host0:port
126122
host1:port
@@ -129,7 +125,7 @@ host3:port
129125
...
130126
```
131127
and then to launch the processes like so:
132-
```
128+
```text
133129
host0% cargo run -- -w 2 -h hostfile.txt -n 4 -p 0
134130
host1% cargo run -- -w 2 -h hostfile.txt -n 4 -p 1
135131
host2% cargo run -- -w 2 -h hostfile.txt -n 4 -p 2
@@ -187,7 +183,7 @@ The communication layer is based on a type `Content<T>` which can be backed by t
187183

188184
**NOTE**: Differential dataflow demonstrates how to do this at the user level in its `operators/arrange.rs`, if somewhat sketchily (with a wrapper that lies about the properties of the type it transports).
189185

190-
This would allow us to safely pass Rc<T> types around, as long as we use the `Pipeline` parallelization contract.
186+
This would allow us to safely pass `Rc<T>` types around, as long as we use the `Pipeline` parallelization contract.
191187

192188
## Coarse- vs fine-grained timestamps
193189

communication/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ license = "MIT"
1717
default = ["getopts"]
1818

1919
[dependencies]
20-
getopts = { version = "0.2.14", optional = true }
20+
getopts = { version = "0.2.21", optional = true }
2121
bincode = { version = "1.0" }
2222
byteorder = "1.5"
2323
serde = { version = "1.0", features = ["derive"] }
2424
timely_bytes = { path = "../bytes", version = "0.12" }
2525
timely_logging = { path = "../logging", version = "0.12" }
26-
crossbeam-channel = "0.5.0"
26+
crossbeam-channel = "0.5"

communication/examples/comm_hello.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
extern crate timely_communication;
2-
31
use std::ops::Deref;
42
use timely_communication::{Message, Allocate};
53

communication/src/allocator/zero_copy/allocator.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::cell::RefCell;
44
use std::collections::{VecDeque, HashMap, hash_map::Entry};
55
use crossbeam_channel::{Sender, Receiver};
66

7-
use bytes::arc::Bytes;
7+
use timely_bytes::arc::Bytes;
88

99
use crate::networking::MessageHeader;
1010

@@ -274,4 +274,4 @@ impl<A: Allocate> Allocate for TcpAllocator<A> {
274274
fn await_events(&self, duration: Option<std::time::Duration>) {
275275
self.inner.await_events(duration);
276276
}
277-
}
277+
}

communication/src/allocator/zero_copy/allocator_process.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::cell::RefCell;
55
use std::collections::{VecDeque, HashMap, hash_map::Entry};
66
use crossbeam_channel::{Sender, Receiver};
77

8-
use bytes::arc::Bytes;
8+
use timely_bytes::arc::Bytes;
99

1010
use crate::networking::MessageHeader;
1111

@@ -250,4 +250,4 @@ impl Allocate for ProcessAllocator {
250250
}
251251
}
252252
}
253-
}
253+
}

communication/src/allocator/zero_copy/bytes_exchange.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::sync::{Arc, Mutex};
44
use std::collections::VecDeque;
55

6-
use bytes::arc::Bytes;
6+
use timely_bytes::arc::Bytes;
77
use super::bytes_slab::BytesSlab;
88

99
/// A target for `Bytes`.
@@ -177,4 +177,3 @@ impl<P: BytesPush> Drop for SendEndpoint<P> {
177177
self.send_buffer();
178178
}
179179
}
180-

communication/src/allocator/zero_copy/bytes_slab.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! A large binary allocation for writing and sharing.
22
3-
use bytes::arc::Bytes;
3+
use timely_bytes::arc::Bytes;
44

55
/// A large binary allocation for writing and sharing.
66
///
@@ -91,4 +91,4 @@ impl BytesSlab {
9191
}
9292
}
9393
}
94-
}
94+
}

communication/src/allocator/zero_copy/initialize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl Drop for CommsGuard {
3131
}
3232

3333
use crate::logging::{CommunicationSetup, CommunicationEvent};
34-
use logging_core::Logger;
34+
use timely_logging::Logger;
3535

3636
/// Initializes network connections
3737
pub fn initialize_networking(

communication/src/allocator/zero_copy/push_pull.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::rc::Rc;
44
use std::cell::RefCell;
55
use std::collections::VecDeque;
66

7-
use bytes::arc::Bytes;
7+
use timely_bytes::arc::Bytes;
88

99
use crate::allocator::canary::Canary;
1010
use crate::networking::MessageHeader;
@@ -139,4 +139,4 @@ impl<T:Data> Pull<Message<T>> for PullerInner<T> {
139139
&mut self.current
140140
}
141141
}
142-
}
142+
}

communication/src/allocator/zero_copy/tcp.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use super::bytes_slab::BytesSlab;
99
use super::bytes_exchange::MergeQueue;
1010
use super::stream::Stream;
1111

12-
use logging_core::Logger;
12+
use timely_logging::Logger;
1313

1414
use crate::logging::{CommunicationEvent, CommunicationSetup, MessageEvent, StateEvent};
1515

communication/src/initialize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::allocator::zero_copy::allocator_process::ProcessBuilder;
1515
use crate::allocator::zero_copy::initialize::initialize_networking;
1616

1717
use crate::logging::{CommunicationSetup, CommunicationEvent};
18-
use logging_core::Logger;
18+
use timely_logging::Logger;
1919
use std::fmt::{Debug, Formatter};
2020

2121

communication/src/lib.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//!
1111
//! To be communicated, a type must implement the [`Serialize`](serde::Serialize) trait.
1212
//!
13-
//! Channel endpoints also implement a lower-level `push` and `pull` interface (through the [`Push`](Push) and [`Pull`](Pull)
13+
//! Channel endpoints also implement a lower-level `push` and `pull` interface (through the [`Push`] and [`Pull`]
1414
//! traits), which is used for more precise control of resources.
1515
//!
1616
//! # Examples
@@ -59,7 +59,7 @@
5959
//! else { println!("error in computation"); }
6060
//! ```
6161
//!
62-
//! The should produce output like:
62+
//! This should produce output like:
6363
//!
6464
//! ```ignore
6565
//! worker 0 started
@@ -74,14 +74,6 @@
7474
7575
#![forbid(missing_docs)]
7676

77-
#[cfg(feature = "getopts")]
78-
extern crate getopts;
79-
extern crate bincode;
80-
extern crate serde;
81-
82-
extern crate timely_bytes as bytes;
83-
extern crate timely_logging as logging_core;
84-
8577
pub mod allocator;
8678
pub mod networking;
8779
pub mod initialize;
@@ -171,4 +163,4 @@ fn promise_futures<T>(sends: usize, recvs: usize) -> (Vec<Vec<Sender<T>>>, Vec<V
171163
}
172164

173165
(senders, recvers)
174-
}
166+
}

communication/src/message.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Types wrapping typed data.
22
3-
use bytes::arc::Bytes;
3+
use timely_bytes::arc::Bytes;
44
use crate::Data;
55

66
/// A wrapped message which supports serialization and deserialization.

mdbook/src/chapter_0/chapter_0_0.md

+7-11
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,14 @@
33
Let's start with what may be the simplest non-trivial timely dataflow program.
44

55
```rust
6-
extern crate timely;
6+
# extern crate timely;
77

88
use timely::dataflow::operators::{ToStream, Inspect};
99

10-
fn main() {
11-
timely::example(|scope| {
12-
(0..10).to_stream(scope)
13-
.inspect(|x| println!("seen: {:?}", x));
14-
});
15-
}
10+
timely::example(|scope| {
11+
(0..10).to_stream(scope)
12+
.inspect(|x| println!("seen: {:?}", x));
13+
});
1614
```
1715

1816
This program gives us a bit of a flavor for what a timely dataflow program might look like, including a bit of what Rust looks like, without getting too bogged down in weird stream processing details. Not to worry; we will do that in just a moment!
@@ -39,9 +37,7 @@ If we run the program up above, we see it print out the numbers zero through nin
3937
This isn't very different from a Rust program that would do this much more simply, namely the program
4038

4139
```rust
42-
fn main() {
43-
(0..10).for_each(|x| println!("seen: {:?}", x));
44-
}
40+
(0..10).for_each(|x| println!("seen: {:?}", x));
4541
```
4642

47-
Why would we want to make our life so complicated? The main reason is that we can make our program *reactive*, so that we can run it without knowing ahead of time the data we will use, and it will respond as we produce new data.
43+
Why would we want to make our life so complicated? The main reason is that we can make our program *reactive*, so that we can run it without knowing ahead of time the data we will use, and it will respond as we produce new data.

mdbook/src/chapter_0/chapter_0_1.md

+24-26
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,31 @@ extern crate timely;
1010
use timely::dataflow::InputHandle;
1111
use timely::dataflow::operators::{Input, Exchange, Inspect, Probe};
1212

13-
fn main() {
14-
// initializes and runs a timely dataflow.
15-
timely::execute_from_args(std::env::args(), |worker| {
16-
17-
let index = worker.index();
18-
let mut input = InputHandle::new();
19-
20-
// create a new input, exchange data, and inspect its output
21-
let probe = worker.dataflow(|scope|
22-
scope.input_from(&mut input)
23-
.exchange(|x| *x)
24-
.inspect(move |x| println!("worker {}:\thello {}", index, x))
25-
.probe()
26-
);
27-
28-
// introduce data and watch!
29-
for round in 0..10 {
30-
if index == 0 {
31-
input.send(round);
32-
}
33-
input.advance_to(round + 1);
34-
while probe.less_than(input.time()) {
35-
worker.step();
36-
}
13+
// initializes and runs a timely dataflow.
14+
timely::execute_from_args(std::env::args(), |worker| {
15+
16+
let index = worker.index();
17+
let mut input = InputHandle::new();
18+
19+
// create a new input, exchange data, and inspect its output
20+
let probe = worker.dataflow(|scope|
21+
scope.input_from(&mut input)
22+
.exchange(|x| *x)
23+
.inspect(move |x| println!("worker {}:\thello {}", index, x))
24+
.probe()
25+
);
26+
27+
// introduce data and watch!
28+
for round in 0..10 {
29+
if index == 0 {
30+
input.send(round);
3731
}
38-
}).unwrap();
39-
}
32+
input.advance_to(round + 1);
33+
while probe.less_than(input.time()) {
34+
worker.step();
35+
}
36+
}
37+
}).unwrap();
4038
```
4139

4240
We can run this program in a variety of configurations: with just a single worker thread, with one process and multiple worker threads, and with multiple processes each with multiple worker threads.

mdbook/src/chapter_4/chapter_4_1.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,4 @@ fn main() {
123123

124124
});
125125
}
126-
```
126+
```

mdbook/src/chapter_4/chapter_4_4.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ We can check out the examples `examples/capture_send.rs` and `examples/capture_r
114114

115115
The `capture_send` example creates a new TCP connection for each worker, which it wraps and uses as an `EventPusher`. Timely dataflow takes care of all the serialization and stuff like that (warning: it uses abomonation, so this is not great for long-term storage).
116116

117-
```rust,ignore
117+
```rust,no_run
118118
extern crate timely;
119119
120120
use std::net::TcpStream;
@@ -138,7 +138,7 @@ fn main() {
138138

139139
The `capture_recv` example is more complicated, because we may have a different number of workers replaying the stream than initially captured it.
140140

141-
```rust,ignore
141+
```rust,no_run
142142
extern crate timely;
143143
144144
use std::net::TcpListener;
@@ -158,10 +158,10 @@ fn main() {
158158
.collect::<Vec<_>>()
159159
.into_iter()
160160
.map(|l| l.incoming().next().unwrap().unwrap())
161-
.map(|r| EventReader::<_,u64,_>::new(r))
161+
.map(|r| EventReader::<_,Vec<u64>,_>::new(r))
162162
.collect::<Vec<_>>();
163163
164-
worker.dataflow::<u64,_,_>(|scope| {
164+
worker.dataflow::<u64,_,_>(move |scope| {
165165
replayers
166166
.replay_into(scope)
167167
.inspect(|x| println!("replayed: {:?}", x));

0 commit comments

Comments
 (0)