Visualization for Timely Dataflow and Differential Dataflow programs

Overview

DDShow

Visualization for Timely Dataflow and Differential Dataflow programs

Getting started with ddshow

First, install ddshow via cargo. As of now ddshow is not published to crates.io, but it will be at a future date. Until then, the recommended way to install ddshow is by using the --git option with cargo install

cargo install --git https://github.com/Kixiron/ddshow

Next you need to set the TIMELY_WORKER_LOG_ADDR environmental variable for your target program. This should be set to the same address that ddshow is pointed (127.0.0.1:51317 by default) to so that they can communicate over TCP.

# Bash
set TIMELY_WORKER_LOG_ADDR=127.0.0.1:51317
# Powershell
$env:TIMELY_WORKER_LOG_ADDR = "127.0.0.1:51317"
:: CMD
set TIMELY_WORKER_LOG_ADDR=127.0.0.1:51317

After setting the environmental variable you can now run ddshow. The --connections argument should be set to the number of timely workers that the target computation has spun up, defaulting to 1 if it's not given and the --address argument for setting the address ddshow should connect to. Note that --address should be the same as whatever you set the TIMELY_WORKER_LOG_ADDR variable to, otherwise ddshow won't be able to connect.

ddshow --connections 1 --address 127.0.0.1:51317

This will create the dataflow-graph/ directory which contains everything that ddshow's UI needs to operate offline. Opening dataflow-graph/graph.html in a browser will allow viewing the graphed dataflow

The full list of arguments ddshow supports and their options can be retrieved by running

ddshow --help

For basic usage

Showcase

Debugging tips:

If the output is empty when it shouldn't be, make sure you aren't overwriting the default loggers set by Timely and DDflow by using Worker::log_register() with a Logger implementation that doesn't forward logging events.

Another common problem is a mismatch of timely versions. Because of how abomonation (used for sending events) works, the structure of events isn't consistent across timely versions (and even different rustc invocations) which can cause errors, incompatibilities and silent failures. The only known solution for this is to make sure ddshow and the target program use the same versions of timely and ddflow, but I'm working on a more stable solution.

When looking for Differential Dataflow insights, make sure you have this (or an equivalent) snippet somewhere within your code in order to forward Differential Dataflow logs

// `worker` should be an `&mut Worker<A>`, generally acquired from the inner
// closure of `timely::execute()`

if let Ok(addr) = std::env::var("DIFFERENTIAL_LOG_ADDR") {
    if !addr.is_empty() {
        if let Ok(stream) = std::net::TcpStream::connect(&addr) {
            differential_dataflow::logging::enable(worker, stream);
        } else {
            panic!("Could not connect to differential log address: {:?}", addr);
        }
    }
}
Comments
  • ddshow fails if TIMELY_WORKER_LOG_ADDR is set in ddshow's env

    ddshow fails if TIMELY_WORKER_LOG_ADDR is set in ddshow's env

    The readme admittedly does say TIMELY_WORKER_LOG_ADDR is supposed to be set for the target program (as opposed to for ddshow). But if it is set for both, the result is ddshow crashes the target program, which seems unfortunate.

    $ export TIMELY_WORKER_LOG_ADDR=127.0.0.1:51317
    $ target/release/ddshow 
    [1s] Waiting for 1 connection on 127.0.0.1:51317: connected to 1 trace source
    Press enter to finish collecting trace data (this will crash the source computation if it's currently running and cause data to not be fully processed)...thread 'timely:work-0' panicked at 'Could not connect logging stream to: "127.0.0.1:51317"', /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/timely-0.12.0/src/execute.rs:280:17
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    
    $ export TIMELY_WORKER_LOG_ADDR=127.0.0.1:51317
    $ target/release/timely_test 
    thread 'timely:work-0' panicked at 'Event abomonation/write failed: Os { code: 104, kind: ConnectionReset, message: "Connection reset by peer" }', /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/timely-0.12.0/src/dataflow/operators/capture/event.rs:140:70
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    thread 'timely:work-0' panicked at 'Event abomonation/write failed: Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }', /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/timely-0.12.0/src/dataflow/operators/capture/event.rs:140:70
    stack backtrace:
       0:     0x55c8ab7f1f02 - std::backtrace_rs::backtrace::libunwind::trace::hfa838fc631229987
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
       1:     0x55c8ab7f1f02 - std::backtrace_rs::backtrace::trace_unsynchronized::h93a23e36ec026219
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
       2:     0x55c8ab7f1f02 - std::sys_common::backtrace::_print_fmt::hba56c7f796a4152f
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/sys_common/backtrace.rs:67:5
       3:     0x55c8ab7f1f02 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h214637f1e26310e1
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/sys_common/backtrace.rs:46:22
       4:     0x55c8ab7408dc - core::fmt::write::h7aa6cd0067dca82a
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/core/src/fmt/mod.rs:1110:17
       5:     0x55c8ab7ee885 - std::io::Write::write_fmt::heb07fc0616bbd06d
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/io/mod.rs:1640:15
       6:     0x55c8ab7f3bfb - std::sys_common::backtrace::_print::h2c2441c37e894fb5
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/sys_common/backtrace.rs:49:5
       7:     0x55c8ab7f3bfb - std::sys_common::backtrace::print::h4fb679ac439362ea
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/sys_common/backtrace.rs:36:9
       8:     0x55c8ab7f3bfb - std::panicking::default_hook::{{closure}}::h56bbadec2356e5d2
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/panicking.rs:208:50
       9:     0x55c8ab7f450c - std::panicking::default_hook::hb25822b45f6fdc4e
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/panicking.rs:225:9
      10:     0x55c8ab7f450c - std::panicking::rust_panic_with_hook::h4da5578e7277d2d4
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/panicking.rs:622:17
      11:     0x55c8ab7f3d6a - std::panicking::begin_panic_handler::{{closure}}::h003783ddb3cba4e8
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/panicking.rs:519:13
      12:     0x55c8ab7f238c - std::sys_common::backtrace::__rust_end_short_backtrace::hd138d2032731ed21
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/sys_common/backtrace.rs:141:18
      13:     0x55c8ab7f3cdd - rust_begin_unwind
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/panicking.rs:515:5
      14:     0x55c8ab5f8951 - core::panicking::panic_fmt::hbe99dddd3092ba3c
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/core/src/panicking.rs:92:14
      15:     0x55c8ab5f8a43 - core::result::unwrap_failed::hf79563fef9d11ab8
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/core/src/result.rs:1355:5
      16:     0x55c8ab67d57e - <timely::dataflow::operators::capture::event::binary::EventWriter<T,D,W> as timely::dataflow::operators::capture::event::EventPusher<T,D>>::push::h79ed4662796f3a42
      17:     0x55c8ab6824d7 - timely::logging::BatchLogger<T,E,P>::publish_batch::hefb22ff72491367b
      18:     0x55c8ab629e98 - <timely_logging::Logger<T,E> as timely_logging::Flush>::flush::h8e669a79068c3f5e
      19:     0x55c8ab7249a2 - core::ptr::drop_in_place<timely_logging::Logger<timely::logging::TimelyEvent,usize>>::heee7345d7759d1ab
      20:     0x55c8ab6fe0b8 - core::ptr::drop_in_place<core::cell::UnsafeCell<timely::progress::subgraph::SubgraphBuilder<(),usize>>>::h050c9c5f30c0bea9
      21:     0x55c8ab6ca600 - timely::worker::Worker<A>::dataflow::h08d459fe68cbd868
      22:     0x55c8ab6b08c9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h86d2f85671b8fe4b
      23:     0x55c8ab6f95d5 - core::ops::function::FnOnce::call_once{{vtable.shim}}::h6124a11eda510dbe
      24:     0x55c8ab7f87d7 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hd1f9b751a68dd2ac
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/alloc/src/boxed.rs:1575:9
      25:     0x55c8ab7f87d7 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h22d732940e85619f
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/alloc/src/boxed.rs:1575:9
      26:     0x55c8ab7f87d7 - std::sys::unix::thread::Thread::new::thread_start::h04c7a9e17ed1032c
                                   at /rustc/150fad30ea25e812d481a784d02c95d3394b234b/library/std/src/sys/unix/thread.rs:71:17
      27:     0x7efc8f2ba609 - start_thread
      28:     0x7efc8f1db293 - clone
      29:                0x0 - <unknown>
    thread panicked while panicking. aborting.
    Illegal instruction (core dumped)
    
    opened by dtolnay 5
  • Installation problems

    Installation problems

    cargo install --git https://github.com/Kixiron/ddshow seems not work now

     cargo install --git https://github.com/Kixiron/ddshow
        Updating git repository `https://github.com/Kixiron/ddshow`
      Installing ddshow v0.2.1 (https://github.com/Kixiron/ddshow#61cb7fec)
        Updating crates.io index
       Compiling proc-macro2 v1.0.30
       Compiling unicode-xid v0.2.2
       Compiling syn v1.0.80
       Compiling autocfg v1.0.1
       Compiling cfg-if v1.0.0
       Compiling libc v0.2.104
       Compiling version_check v0.9.3
       Compiling lazy_static v1.4.0
       Compiling crossbeam-utils v0.8.5
       Compiling serde_derive v1.0.130
       Compiling serde v1.0.130
       Compiling memchr v2.4.1
       Compiling unicode-width v0.1.9
       Compiling log v0.4.14
       Compiling once_cell v1.8.0
       Compiling bitflags v1.3.2
       Compiling proc-macro-hack v0.5.19
       Compiling regex-syntax v0.6.25
       Compiling rustversion v1.0.5
       Compiling pin-project-lite v0.2.7
       Compiling anyhow v1.0.44
       Compiling fnv v1.0.7
       Compiling futures-task v0.3.17
       Compiling proc-macro-nested v0.1.7
       Compiling futures-core v0.3.17
       Compiling semver v1.0.4
       Compiling unicode-segmentation v1.8.0
       Compiling scopeguard v1.1.0
       Compiling bytecheck v0.6.5
       Compiling ucd-trie v0.1.3
       Compiling timely_bytes v0.12.0
       Compiling signal-hook v0.3.10
       Compiling timely_logging v0.12.0
       Compiling abomonation v0.7.3
       Compiling rend v0.3.2
       Compiling parking_lot_core v0.8.5
       Compiling pin-utils v0.1.0
       Compiling slab v0.4.5
       Compiling same-file v1.0.6
       Compiling smallvec v1.7.0
       Compiling maplit v1.0.2
       Compiling unic-char-range v0.9.0
       Compiling unic-common v0.9.0
       Compiling rkyv v0.7.3
       Compiling cc v1.0.71
       Compiling tinyvec_macros v0.1.0
       Compiling ryu v1.0.5
       Compiling serde_json v1.0.68
       Compiling seahash v4.1.0
       Compiling crossbeam-epoch v0.9.5
       Compiling ansi_term v0.11.0
       Compiling strsim v0.8.0
       Compiling itoa v0.4.8
       Compiling vec_map v0.8.2
       Compiling ansi_term v0.12.1
       Compiling byteorder v1.4.3
       Compiling colorous v1.0.5
       Compiling xxhash-rust v0.8.2
       Compiling tracing-core v0.1.21
       Compiling sharded-slab v0.1.4
       Compiling instant v0.1.12
       Compiling proc-macro-error-attr v1.0.4
       Compiling proc-macro-error v1.0.4
       Compiling ahash v0.7.6
       Compiling getopts v0.2.21
       Compiling textwrap v0.11.0
       Compiling num-traits v0.2.14
       Compiling num-integer v0.1.44
       Compiling futures-macro v0.3.17
       Compiling memoffset v0.6.4
       Compiling futures-util v0.3.17
       Compiling thread_local v1.1.3
       Compiling lock_api v0.4.5
       Compiling pest v2.1.3
       Compiling heck v0.3.3
       Compiling walkdir v2.3.2
       Compiling unic-char-property v0.9.0
       Compiling unic-ucd-version v0.9.0
       Compiling regex-automata v0.1.10
       Compiling libmimalloc-sys v0.1.22
       Compiling unic-ucd-segment v0.9.0
       Compiling crossbeam-channel v0.5.1
       Compiling quote v1.0.10
       Compiling matchers v0.0.1
       Compiling pest_meta v2.1.3
       Compiling aho-corasick v0.7.18
       Compiling bstr v0.2.17
       Compiling getrandom v0.2.3
       Compiling signal-hook-registry v1.4.0
       Compiling mio v0.7.14
       Compiling atty v0.2.14
       Compiling time v0.1.43
       Compiling rustc_version v0.4.0
       Compiling unic-segment v0.9.0
       Compiling nix v0.23.0
       Compiling regex v1.5.4
       Compiling clap v2.33.3
       Compiling ordered-float v2.8.0
       Compiling parking_lot v0.11.2
       Compiling crossbeam-deque v0.8.1
       Compiling chrono v0.4.19
       Compiling hashbrown v0.11.2
       Compiling signal-hook-mio v0.2.1
       Compiling mimalloc v0.1.26
       Compiling globset v0.4.8
       Compiling crossterm v0.20.0
       Compiling ignore v0.4.18
       Compiling vergen v5.1.16
       Compiling globwalk v0.8.1
       Compiling ctrlc v3.2.1
       Compiling synstructure v0.12.6
       Compiling pest_generator v2.1.3
       Compiling ptr_meta_derive v0.1.4
       Compiling bytecheck_derive v0.6.5
       Compiling abomonation_derive v0.5.0
       Compiling thiserror-impl v1.0.30
       Compiling enum-iterator-derive v0.7.0
       Compiling getset v0.1.1
       Compiling tracing-attributes v0.1.18
       Compiling rkyv_derive v0.7.3
       Compiling strum_macros v0.21.1
       Compiling structopt-derive v0.4.18
       Compiling pest_derive v2.1.0
       Compiling ptr_meta v0.1.4
       Compiling enum-iterator v0.7.0
       Compiling thiserror v1.0.30
       Compiling tracing v0.1.29
       Compiling tracing-subscriber v0.2.25
       Compiling strum v0.21.0
       Compiling comfy-table v4.1.1
       Compiling ddshow v0.2.1 (/home/njuseg/.cargo/git/checkouts/ddshow-f3b4fc931d0b8470/61cb7fe)
       Compiling structopt v0.3.25
       Compiling timely_communication v0.12.0
       Compiling tinyvec v1.5.0
       Compiling timely v0.12.0
       Compiling tera v1.13.0
       Compiling differential-dataflow v0.12.0
       Compiling ddshow-types v0.2.2 (/home/njuseg/.cargo/git/checkouts/ddshow-f3b4fc931d0b8470/61cb7fe/crates/ddshow-types)
       Compiling ddshow-sink v0.2.2 (/home/njuseg/.cargo/git/checkouts/ddshow-f3b4fc931d0b8470/61cb7fe/crates/ddshow-sink)
    error[E0277]: `[&str; 3]` is not an iterator
       --> src/logging.rs:182:22
        |
    182 |     for hook_name in IntoIterator::into_iter(builtin_hooks) {
        |                      ^^^^^^^^^^^^^^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
        |
        = help: the trait `Iterator` is not implemented for `[&str; 3]`
        = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
        = note: required because of the requirements on the impl of `IntoIterator` for `[&str; 3]`
        = note: required by `into_iter`
    
    error[E0277]: `[&str; 3]` is not an iterator
       --> src/logging.rs:182:22
        |
    182 |     for hook_name in IntoIterator::into_iter(builtin_hooks) {
        |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
        |
        = help: the trait `Iterator` is not implemented for `[&str; 3]`
        = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
        = note: required because of the requirements on the impl of `IntoIterator` for `[&str; 3]`
        = note: required by `into_iter`
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:103:42
        |
    103 |           .add_row(IntoIterator::into_iter([
        |  __________________________________________^
    104 | |             Cell::new("Workers"),
    105 | |             Cell::new(data.workers.len()),
    106 | |         ]))
        | |_________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required by `into_iter`
    help: consider borrowing here
        |
    103 |         .add_row(IntoIterator::into_iter(&[
    104 |             Cell::new("Workers"),
    105 |             Cell::new(data.workers.len()),
    106 |         ]))
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:103:18
        |
    103 |           .add_row(IntoIterator::into_iter([
        |  __________________^
    104 | |             Cell::new("Workers"),
    105 | |             Cell::new(data.workers.len()),
    106 | |         ]))
        | |__________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required because of the requirements on the impl of `From<[comfy_table::Cell; 2]>` for `Cells`
        = note: required because of the requirements on the impl of `Into<Cells>` for `[comfy_table::Cell; 2]`
        = note: 2 redundant requirements hidden
        = note: required because of the requirements on the impl of `Into<Row>` for `[comfy_table::Cell; 2]`
    help: consider borrowing here
        |
    103 |         .add_row(&IntoIterator::into_iter([
    104 |             Cell::new("Workers"),
    105 |             Cell::new(data.workers.len()),
    106 |         ]))
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:107:42
        |
    107 |           .add_row(IntoIterator::into_iter([
        |  __________________________________________^
    108 | |             Cell::new("Dataflows"),
    109 | |             Cell::new(data.dataflows.len()),
    110 | |         ]))
        | |_________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required by `into_iter`
    help: consider borrowing here
        |
    107 |         .add_row(IntoIterator::into_iter(&[
    108 |             Cell::new("Dataflows"),
    109 |             Cell::new(data.dataflows.len()),
    110 |         ]))
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:107:18
        |
    107 |           .add_row(IntoIterator::into_iter([
        |  __________________^
    108 | |             Cell::new("Dataflows"),
    109 | |             Cell::new(data.dataflows.len()),
    110 | |         ]))
        | |__________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required because of the requirements on the impl of `From<[comfy_table::Cell; 2]>` for `Cells`
        = note: required because of the requirements on the impl of `Into<Cells>` for `[comfy_table::Cell; 2]`
        = note: 2 redundant requirements hidden
        = note: required because of the requirements on the impl of `Into<Row>` for `[comfy_table::Cell; 2]`
    help: consider borrowing here
        |
    107 |         .add_row(&IntoIterator::into_iter([
    108 |             Cell::new("Dataflows"),
    109 |             Cell::new(data.dataflows.len()),
    110 |         ]))
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:111:42
        |
    111 |           .add_row(IntoIterator::into_iter([
        |  __________________________________________^
    112 | |             Cell::new("Operators"),
    113 | |             Cell::new(data.operators.len()),
    114 | |         ]))
        | |_________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required by `into_iter`
    help: consider borrowing here
        |
    111 |         .add_row(IntoIterator::into_iter(&[
    112 |             Cell::new("Operators"),
    113 |             Cell::new(data.operators.len()),
    114 |         ]))
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:111:18
        |
    111 |           .add_row(IntoIterator::into_iter([
        |  __________________^
    112 | |             Cell::new("Operators"),
    113 | |             Cell::new(data.operators.len()),
    114 | |         ]))
        | |__________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required because of the requirements on the impl of `From<[comfy_table::Cell; 2]>` for `Cells`
        = note: required because of the requirements on the impl of `Into<Cells>` for `[comfy_table::Cell; 2]`
        = note: 2 redundant requirements hidden
        = note: required because of the requirements on the impl of `Into<Row>` for `[comfy_table::Cell; 2]`
    help: consider borrowing here
        |
    111 |         .add_row(&IntoIterator::into_iter([
    112 |             Cell::new("Operators"),
    113 |             Cell::new(data.operators.len()),
    114 |         ]))
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:115:42
        |
    115 |           .add_row(IntoIterator::into_iter([
        |  __________________________________________^
    116 | |             Cell::new("Subgraphs"),
    117 | |             Cell::new(data.subgraphs.len()),
    118 | |         ]))
        | |_________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required by `into_iter`
    help: consider borrowing here
        |
    115 |         .add_row(IntoIterator::into_iter(&[
    116 |             Cell::new("Subgraphs"),
    117 |             Cell::new(data.subgraphs.len()),
    118 |         ]))
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:115:18
        |
    115 |           .add_row(IntoIterator::into_iter([
        |  __________________^
    116 | |             Cell::new("Subgraphs"),
    117 | |             Cell::new(data.subgraphs.len()),
    118 | |         ]))
        | |__________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required because of the requirements on the impl of `From<[comfy_table::Cell; 2]>` for `Cells`
        = note: required because of the requirements on the impl of `Into<Cells>` for `[comfy_table::Cell; 2]`
        = note: 2 redundant requirements hidden
        = note: required because of the requirements on the impl of `Into<Row>` for `[comfy_table::Cell; 2]`
    help: consider borrowing here
        |
    115 |         .add_row(&IntoIterator::into_iter([
    116 |             Cell::new("Subgraphs"),
    117 |             Cell::new(data.subgraphs.len()),
    118 |         ]))
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:119:42
        |
    119 |           .add_row(IntoIterator::into_iter([
        |  __________________________________________^
    120 | |             Cell::new("Channels"),
    121 | |             Cell::new(data.channels.len()),
    122 | |         ]));
        | |_________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required by `into_iter`
    help: consider borrowing here
        |
    119 |         .add_row(IntoIterator::into_iter(&[
    120 |             Cell::new("Channels"),
    121 |             Cell::new(data.channels.len()),
    122 |         ]));
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:119:18
        |
    119 |           .add_row(IntoIterator::into_iter([
        |  __________________^
    120 | |             Cell::new("Channels"),
    121 | |             Cell::new(data.channels.len()),
    122 | |         ]));
        | |__________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required because of the requirements on the impl of `From<[comfy_table::Cell; 2]>` for `Cells`
        = note: required because of the requirements on the impl of `Into<Cells>` for `[comfy_table::Cell; 2]`
        = note: 2 redundant requirements hidden
        = note: required because of the requirements on the impl of `Into<Row>` for `[comfy_table::Cell; 2]`
    help: consider borrowing here
        |
    119 |         .add_row(&IntoIterator::into_iter([
    120 |             Cell::new("Channels"),
    121 |             Cell::new(data.channels.len()),
    122 |         ]));
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:125:47
        |
    125 |           table.add_row(IntoIterator::into_iter([
        |  _______________________________________________^
    126 | |             Cell::new("Arrangements"),
    127 | |             Cell::new(data.arrangement_ids.len()),
    128 | |         ]));
        | |_________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required by `into_iter`
    help: consider borrowing here
        |
    125 |         table.add_row(IntoIterator::into_iter(&[
    126 |             Cell::new("Arrangements"),
    127 |             Cell::new(data.arrangement_ids.len()),
    128 |         ]));
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:125:23
        |
    125 |           table.add_row(IntoIterator::into_iter([
        |  _______________________^
    126 | |             Cell::new("Arrangements"),
    127 | |             Cell::new(data.arrangement_ids.len()),
    128 | |         ]));
        | |__________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required because of the requirements on the impl of `From<[comfy_table::Cell; 2]>` for `Cells`
        = note: required because of the requirements on the impl of `Into<Cells>` for `[comfy_table::Cell; 2]`
        = note: 2 redundant requirements hidden
        = note: required because of the requirements on the impl of `Into<Row>` for `[comfy_table::Cell; 2]`
    help: consider borrowing here
        |
    125 |         table.add_row(&IntoIterator::into_iter([
    126 |             Cell::new("Arrangements"),
    127 |             Cell::new(data.arrangement_ids.len()),
    128 |         ]));
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:142:43
        |
    142 |       table.add_row(IntoIterator::into_iter([
        |  ___________________________________________^
    143 | |         Cell::new("Total Runtime"),
    144 | |         Cell::new(format!("{:#?}", total_runtime)),
    145 | |     ]));
        | |_____^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required by `into_iter`
    help: consider borrowing here
        |
    142 |     table.add_row(IntoIterator::into_iter(&[
    143 |         Cell::new("Total Runtime"),
    144 |         Cell::new(format!("{:#?}", total_runtime)),
    145 |     ]));
        |
    
    error[E0277]: `[comfy_table::Cell; 2]` is not an iterator
       --> src/report/mod.rs:142:19
        |
    142 |       table.add_row(IntoIterator::into_iter([
        |  ___________________^
    143 | |         Cell::new("Total Runtime"),
    144 | |         Cell::new(format!("{:#?}", total_runtime)),
    145 | |     ]));
        | |______^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 2]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 2]`
        = note: required because of the requirements on the impl of `From<[comfy_table::Cell; 2]>` for `Cells`
        = note: required because of the requirements on the impl of `Into<Cells>` for `[comfy_table::Cell; 2]`
        = note: 2 redundant requirements hidden
        = note: required because of the requirements on the impl of `Into<Row>` for `[comfy_table::Cell; 2]`
    help: consider borrowing here
        |
    142 |     table.add_row(&IntoIterator::into_iter([
    143 |         Cell::new("Total Runtime"),
    144 |         Cell::new(format!("{:#?}", total_runtime)),
    145 |     ]));
        |
    
    error[E0277]: `[comfy_table::Cell; 5]` is not an iterator
       --> src/report/mod.rs:168:44
        |
    168 |           row.extend(IntoIterator::into_iter([
        |  ____________________________________________^
    169 | |             Cell::new(format!("Worker {}", worker.into_inner())),
    170 | |             Cell::new(data.dataflows.len()),
    171 | |             Cell::new(data.operators.len()),
    172 | |             Cell::new(data.subgraphs.len()),
    173 | |             Cell::new(data.channels.len()),
    174 | |         ]));
        | |_________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 5]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 5]`
        = note: required by `into_iter`
    help: consider borrowing here
        |
    168 |         row.extend(IntoIterator::into_iter(&[
    169 |             Cell::new(format!("Worker {}", worker.into_inner())),
    170 |             Cell::new(data.dataflows.len()),
    171 |             Cell::new(data.operators.len()),
    172 |             Cell::new(data.subgraphs.len()),
    173 |             Cell::new(data.channels.len()),
      ...
    
    error[E0277]: `[comfy_table::Cell; 5]` is not an iterator
       --> src/report/mod.rs:168:20
        |
    168 |           row.extend(IntoIterator::into_iter([
        |  ____________________^
    169 | |             Cell::new(format!("Worker {}", worker.into_inner())),
    170 | |             Cell::new(data.dataflows.len()),
    171 | |             Cell::new(data.operators.len()),
    172 | |             Cell::new(data.subgraphs.len()),
    173 | |             Cell::new(data.channels.len()),
    174 | |         ]));
        | |__________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 5]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 5]`
    help: consider borrowing here
        |
    168 |         row.extend(&IntoIterator::into_iter([
    169 |             Cell::new(format!("Worker {}", worker.into_inner())),
    170 |             Cell::new(data.dataflows.len()),
    171 |             Cell::new(data.operators.len()),
    172 |             Cell::new(data.subgraphs.len()),
    173 |             Cell::new(data.channels.len()),
      ...
    
    error[E0277]: `[comfy_table::Cell; 7]` is not an iterator
       --> src/report/mod.rs:376:47
        |
    376 |           table.add_row(IntoIterator::into_iter([
        |  _______________________________________________^
    377 | |             Cell::new(name),
    378 | |             Cell::new(operator),
    379 | |             Cell::new(format!(
    ...   |
    393 | |             Cell::new(arrange.batches),
    394 | |         ]));
        | |_________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 7]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 7]`
        = note: required by `into_iter`
    help: consider borrowing here
        |
    376 |         table.add_row(IntoIterator::into_iter(&[
    377 |             Cell::new(name),
    378 |             Cell::new(operator),
    379 |             Cell::new(format!(
    380 |                 "[{}]",
    381 |                 addr.map_or_else(
      ...
    
    error[E0277]: `[comfy_table::Cell; 7]` is not an iterator
       --> src/report/mod.rs:376:23
        |
    376 |           table.add_row(IntoIterator::into_iter([
        |  _______________________^
    377 | |             Cell::new(name),
    378 | |             Cell::new(operator),
    379 | |             Cell::new(format!(
    ...   |
    393 | |             Cell::new(arrange.batches),
    394 | |         ]));
        | |__________^ expected an implementor of trait `IntoIterator`
        |
        = note: the trait bound `[comfy_table::Cell; 7]: IntoIterator` is not satisfied
        = note: required because of the requirements on the impl of `IntoIterator` for `[comfy_table::Cell; 7]`
        = note: required because of the requirements on the impl of `From<[comfy_table::Cell; 7]>` for `Cells`
        = note: required because of the requirements on the impl of `Into<Cells>` for `[comfy_table::Cell; 7]`
        = note: 2 redundant requirements hidden
        = note: required because of the requirements on the impl of `Into<Row>` for `[comfy_table::Cell; 7]`
    help: consider borrowing here
        |
    376 |         table.add_row(&IntoIterator::into_iter([
    377 |             Cell::new(name),
    378 |             Cell::new(operator),
    379 |             Cell::new(format!(
    380 |                 "[{}]",
    381 |                 addr.map_or_else(
      ...
    
    error: aborting due to 20 previous errors
    
    For more information about this error, try `rustc --explain E0277`.
    error: could not compile `ddshow`
    
    To learn more, run the command again with --verbose.
    warning: build failed, waiting for other jobs to finish...
    error: failed to compile `ddshow v0.2.1 (https://github.com/Kixiron/ddshow#61cb7fec)`, intermediate artifacts can be found at `/tmp/cargo-installC6mkk8`
    
    Caused by:
      build failed
    

    here is related software version

    cargo --version cargo 1.52.0 (69767412a 2021-04-21)

    rustc --version rustc 1.52.1 (9bc8c42bb 2021-05-09)

    git --version git version 2.25.1

    I am not familiar with rust programming

    opened by Price1999a 2
  • Panic triggered by conflicting CLI switches

    Panic triggered by conflicting CLI switches

    It appears that --differential and --replay-logs flags are mutually exclusive, but instead of returning an error message to that effect ddshow panics. Also it is not clear from the documentation that --differential (and other flags) are only meaningful in the network mode.

    lryzhyk@nerpa:~/projects/differential-datalog/java/test$ ddshow --differential --replay-logs timely_trace/
    [0s] Loading Timely replay from timely_trace/: loaded 2 replay files
    thread 'main' panicked at 'the differential listener should be created when `args.differential_enabled` is true', src/replay_loading.rs:151:59
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    
    bug 
    opened by ryzhyk 2
  • Panic with two connections

    Panic with two connections

    This does not happen with --connections 1:

    ddshow --stream-encoding rkyv --differential --connections 2
    [2s] Waiting for 2 connections on 127.0.0.1:51317: connected to 2 trace sources
    [0s] Waiting for 2 connections on 127.0.0.1:51318: connected to 2 trace sources
    Press enter to finish collecting trace data (this will crash the source computation if it's currently running and cause data to not be fully processed)...
    [1/2, 0s] ⠂ Replaying timely events: 0 events, 0/s
    [2/2, 0s] ⠂ Replaying differential events: 0 events, 0/s
    thread 'timely:work-0' panicked at 'Attempted to delay Capability { time: 7.387769ms, internal: ... } to 479.523µs, which is not `less_equal` the capability's time.', /home/lryzhyk/.cargo/registry/src/github.com[1/2, 0s]   Finished replaying timely events: 428 events, 9486/s
    [2/2, 0s]   Finished replaying differential events: 754 events, 12416/s
    
    Processing data...Error: failed to join timely worker threads: Any
    

    This is how I run DDlog in another shell:

    ./tutorial_ddlog/target/release/tutorial_cli -w 2 --profile-timely  --profile-differential  < tutorial.dat
    
    opened by ryzhyk 1
  • Add CLI switch to use `rkyv` serialization instead of `Abomonation`.

    Add CLI switch to use `rkyv` serialization instead of `Abomonation`.

    According to @Kixiron , ddshow already supports both serialization formats, but the latter requires that the target app is compiled using exactly the same timely and differential versions as ddshow, which is problematic in practice.

    opened by ryzhyk 1
  • Installation problems

    Installation problems

    $ cargo install --git https://github.com/Kixiron/ddshow
        Updating git repository `https://github.com/Kixiron/ddshow`
    error: failed to parse manifest at `~/.cargo/git/checkouts/ddshow-f3b4fc931d0b8470/290fae8/Cargo.toml`
    
    Caused by:
      feature `resolver` is required
    
      this Cargo does not support nightly features, but if you
      switch to nightly channel you can add
      `cargo-features = ["resolver"]` to enable this feature
    
    opened by mbudiu-vmw 1
  • Installation hangs forever

    Installation hangs forever

    Hello, I noticed that the command indicated on the readme, cargo install --git https://github.com/Kixiron/ddshow, does not work for me. It hangs with 100% CPU usage on one core seemingly forever. If I do cargo install --git https://github.com/Kixiron/ddshow --debug, then it works. Do you have any idea why that might be? Thanks!

    PS:

    $ cargo --version
    cargo 1.60.0-nightly (25fcb13 2022-02-01)
    $ rustc --version
    rustc 1.60.0-nightly (734368a20 2022-02-07)
    

    and if I recall correctly, the same happens on stable 1.58

    opened by dreraic 3
  • Do network reading from dedicated threads

    Do network reading from dedicated threads

    Currently we read from the input connections within timely operators but I suspect this is causing sub-optimal performance both for ddshow and (more importantly) the target program since it means that sometimes ddshow will stop reading from the network for (possibly long) periods of time while other operators run. Reading from input connections in dedicated threads (probably async powered ones, this is where it shines) and making the input operators operate off of a queue would be much more efficient and consistent overall.

    bug enhancement 
    opened by Kixiron 0
  • Split HTML report into several parts.

    Split HTML report into several parts.

    The ddshow report consists of several parts, including the timeline, which can take a very long time to load in the browser. @Kixiron suggested disabling timeline generation using the --disable-timeline switch. Alternatively, ddshow could produce a separate HTML document for each part of the report, with an index page to navigate between them, so one would only need to wait for the timeline to load if they are actually interested in looking at it.

    opened by ryzhyk 0
  • Running ddshow automatically.

    Running ddshow automatically.

    I am adding an option to ddlog CLI to start ddshow before initializing the dataflow graph. This should greatly simplify the profiling workflow as the user only needs to type one command and doesn't need to worry about providing matching arguments (socket address, number of workers). Problem is, there is no easy way to know that ddshow is listening. Starting the graph before ddshow has called bind() returns an error. I noticed that ddshow prints a message to stdout on startup ("Waiting for 2 Timely connections on 127.0.0.1:51317..."), so I thought of to capturing its stdout and waiting for the message; however I checked the source and it does this before actually calling bind. Also, this seems like an ugly hack...

    It's be great to have a more reliable startup protocol (any ideas?) or at least reorder things to print the message once ddshow is actually listening...

    opened by ryzhyk 2
  • Create a custom protocol for ddshow

    Create a custom protocol for ddshow

    In an effort to stay backwards compatible with timely's builtin logging streams, DDShow currently uses separate tcp streams for timely, differential and progress logging. However, with the introduction of ddshow-sink and the rkyv types we have the basis to make an entirely custom protocol that's significantly easier to use

    Pros:

    • Doesn't require up to three separate tcp streams to be specified by users
    • Doesn't require the user to know the number of timely workers in the target program
    • Could allow intermittent logging (currently the builtin timely loggers panic and crash the target program if either side disconnects)

    Cons:

    • Increases complexity some more
    • Loses backcompat with timely stuff (only to an extent though, the current abomonated sink/streams could still be kept and be comparable with timely's stock stuff)

    cc @ryzhyk

    enhancement 
    opened by Kixiron 0
Owner
Chase Wilson
Interested in compiler & optimizer development as well as self-verifying programs that are easy to read and write
Chase Wilson
A modular implementation of timely dataflow in Rust

Timely Dataflow Timely dataflow is a low-latency cyclic dataflow computational model, introduced in the paper Naiad: a timely dataflow system. This pr

Timely Dataflow 2.7k Dec 30, 2022
Dataflow system for building self-driving car and robotics applications.

ERDOS ERDOS is a platform for developing self-driving cars and robotics applications. Getting started The easiest way to get ERDOS running is to use o

ERDOS 163 Dec 29, 2022
🕶 Assorted checks and validations for writing safer Solana programs.

vipers ?? Assorted checks and validations for writing safer Solana programs. Motivation Solana's fee mechanism is unlike Ethereum's, in that the numbe

Saber 131 Sep 14, 2022
Cogo is a high-performance library for programming stackful coroutines with which you can easily develop and maintain massive concurrent programs.

Cogo is a high-performance library for programming stackful coroutines with which you can easily develop and maintain massive concurrent programs.

co-rs 47 Nov 17, 2022
Rust library for compiling and running other programs.

Exers ?? Exers is a rust library for compiling and running code in different languages and runtimes. Usage example fn main() { // Imports...

olix3001 5 Jun 10, 2023
Rust programs written entirely in Rust

mustang Programs written entirely in Rust Mustang is a system for building programs built entirely in Rust, meaning they do not depend on any part of

Dan Gohman 561 Dec 26, 2022
Complete code for the larger example programs from the book.

Code Examples for Programming Rust This repository contains complete code for the larger example programs from the book “Programming Rust”, by Jim Bla

Programming Rust 670 Jan 1, 2023
Write Anchor-compatible Solana programs in Python

seahorse: Write Solana programs in Python The ease of Python with the safety of Rust. Seahorse lets you write Solana programs in Python. It is a commu

✨ amelia chen ✨ 214 Dec 28, 2022
Small programs written in Rust. Warm up for the upcoming Selenium Manager

Rust Examples This repository contains several example programs written in Rust. Selenium Manager These examples are used as warm up for the upcoming

Boni García 5 Dec 30, 2022
A additional Rust compiler pass to detect memory safe bugs of Rust programs.

SafeDrop A additional Rust compiler pass to detect memory safe bugs of Rust programs. SafeDrop performs path-sensitive and field-sensitive inter-proce

Artisan-Lab  (Fn*) 5 Nov 25, 2022
Gain intuition about the goings-on of your multithreaded/multicomponent programs

Intuition: a super simple profiler with a terminal ui based on tui-rs. Gain intuition about the goings-on of your multithreaded/multicomponent program

GenesysGo 9 Mar 2, 2023
An API for getting questions from http://either.io implemented fully in Rust, using reqwest and some regex magic. Provides asynchronous and blocking clients respectively.

eithers_rust An API for getting questions from http://either.io implemented fully in Rust, using reqwest and some regex magic. Provides asynchronous a

null 2 Oct 24, 2021
Safe, efficient, and ergonomic bindings to Wolfram LibraryLink and the Wolfram Language

wolfram-library-link Bindings to the Wolfram LibraryLink interface, making it possible to call Rust code from the Wolfram Language. This library is us

Wolfram Research, Inc. 28 Dec 6, 2022
This blog provides detailed status updates and useful information about Theseus OS and its development

The Theseus OS Blog This blog provides detailed status updates and useful information about Theseus OS and its development. Attribution This blog was

Theseus OS 1 Apr 14, 2022
Omeglib, a portmanteau of "omegle" and "library", is a crate for interacting with omegle, simply and asynchronously

Omeglib, a portmanteau of "omegle" and "library", is a crate for interacting with omegle, simply and asynchronously. It is intended to suit one's every requirement regarding chat on omegle.

null 1 May 25, 2022
Fast and simple datetime, date, time and duration parsing for rust.

speedate Fast and simple datetime, date, time and duration parsing for rust. speedate is a lax† RFC 3339 date and time parser, in other words, it pars

Samuel Colvin 43 Nov 25, 2022
In this repository you can find modules with code and comments that explain rust syntax and all about Rust lang.

Learn Rust What is this? In this repository you can find modules with code and comments that explain rust syntax and all about Rust lang. This is usef

Domagoj Ratko 5 Nov 5, 2022
A tool and library to losslessly join multiple .mp4 files shot with same camera and settings

mp4-merge A tool and library to losslessly join multiple .mp4 files shot with same camera and settings. This is useful to merge multiple files that ar

Gyroflow 7 Jan 2, 2023