Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor re_sdk::Session #1528

Merged
merged 37 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
0c86719
Refactor: clean up Session slightly
emilk Mar 7, 2023
d426029
Simplify the API of RerunArgs
emilk Mar 7, 2023
7e9202f
CI: run `cargo check -p rerun --no-default-features --features sdk`
emilk Mar 7, 2023
326f069
Fix errors and warnings when using only the `sdk` feature of rerun
emilk Mar 7, 2023
1092f99
Make LogSink: Sync
emilk Mar 7, 2023
25623a3
Refactor: clean up the contents of Session
emilk Mar 7, 2023
5a9f46a
Move the tokio runtime out of Session
emilk Mar 7, 2023
7f20c0e
Clean up Session a bit
emilk Mar 7, 2023
c5919dc
Refactor sink names and modules
emilk Mar 7, 2023
1a07f7d
Clone Session as PythonSession
emilk Mar 7, 2023
67e616a
justfile: make sure our just-scripts use `set -euo pipefail`
emilk Mar 7, 2023
ad02d24
Add just rs-lint
emilk Mar 7, 2023
2ef7528
lint.py: white-list "./web_viewer/re_viewer_debug.js"
emilk Mar 7, 2023
0c73ba8
Run `typos` in `just lint`
emilk Mar 7, 2023
eb3d51b
Simplify `Session`, and add `SessionBuilder`
emilk Mar 7, 2023
4dcb345
Use --deny-warnings instead of setting RUSTFLAGS
emilk Mar 7, 2023
5a5e0fa
rust.yml: replace `-D` with more explicit `--deny`
emilk Mar 7, 2023
725d9d5
Make ahash a workspace dependency
emilk Mar 7, 2023
e4d30c8
Remove typos from just py-lint again since it runs on CI
emilk Mar 7, 2023
3a9f7d2
Make Session: Clone
emilk Mar 7, 2023
ec7b2f6
Make sure `Session` is `Send` and `Sync`
emilk Mar 7, 2023
9d8e3ac
Make `tracing` and `tracing-subscriber` workspace dependencies
emilk Mar 7, 2023
70bc204
Less `mut Session`
emilk Mar 7, 2023
de9c490
Remove lint of `dbg!` (clippy checks it now)
emilk Mar 7, 2023
41e1614
MsgSender::send can be used with both Session and LogSink
emilk Mar 7, 2023
ec2de06
bug fix
emilk Mar 7, 2023
f51b839
Cleanup
emilk Mar 7, 2023
c1c59d4
Add Session::sink to access the underlying sink
emilk Mar 8, 2023
16e6704
Document the built-in log level names
emilk Mar 8, 2023
b6a9d7a
Simplify TCP client by removing the `set_addr` method
emilk Mar 8, 2023
129f7b7
Update TcpClient documentation
emilk Mar 8, 2023
5545dc1
Use thiserror to report LogMsg encoding errors
emilk Mar 8, 2023
4ac05fd
Replace some more `anyhow` with `thiserror`
emilk Mar 8, 2023
1408470
fix copy-paste bug
emilk Mar 9, 2023
c069752
fix copy-paste bug
emilk Mar 9, 2023
718d0b3
Sleep longer
emilk Mar 9, 2023
8dfff29
Simplify code with SessionBuilder::buffered
emilk Mar 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ env:
# web_sys_unstable_apis is required to enable the web_sys clipboard API which egui_web uses
# https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html
# https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html
RUSTFLAGS: --cfg=web_sys_unstable_apis -D warnings
RUSTFLAGS: --cfg=web_sys_unstable_apis --deny warnings

# See https://github.com/ericseppanen/cargo-cranky/issues/8
RUSTDOCFLAGS: -D warnings -D rustdoc::missing_crate_level_docs
RUSTDOCFLAGS: --deny warnings --deny rustdoc::missing_crate_level_docs

permissions:
# deployments permission to deploy GitHub pages website
Expand Down Expand Up @@ -122,14 +122,21 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: cranky
args: --all-targets --all-features -- -D warnings
args: --all-targets --all-features -- --deny warnings

- name: Check no default features
uses: actions-rs/cargo@v1
with:
command: check
args: --locked --no-default-features --features __ci --lib

# Check a few important permutations of the feature flags for our `rerun` library:
- name: Check rerun with --features sdk
uses: actions-rs/cargo@v1
with:
command: check
args: --locked --no-default-features --features sdk

- name: Test doc-tests
uses: actions-rs/cargo@v1
with:
Expand Down
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ re_web_viewer_server = { path = "crates/re_web_viewer_server", version = "0.3.0"
re_ws_comms = { path = "crates/re_ws_comms", version = "0.3.0" }
rerun = { path = "crates/rerun", version = "0.3.0" }

ahash = "0.8"
anyhow = "1.0"
arrow2 = "0.16"
arrow2_convert = "0.4.2"
Expand Down
2 changes: 1 addition & 1 deletion crates/re_arrow_store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ re_log_types.workspace = true
re_log.workspace = true

# External dependencies:
ahash = "0.8"
ahash.workspace = true
anyhow.workspace = true
arrow2 = { workspace = true, features = [
"compute_concatenate",
Expand Down
2 changes: 1 addition & 1 deletion crates/re_data_store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ re_log.workspace = true
re_smart_channel.workspace = true
re_string_interner.workspace = true

ahash = "0.8"
ahash.workspace = true
anyhow = "1.0"
document-features = "0.2"
itertools = "0.10"
Expand Down
2 changes: 1 addition & 1 deletion crates/re_log_types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ re_string_interner.workspace = true
re_tuid.workspace = true

# External
ahash = "0.8"
ahash.workspace = true
array-init = "2.1.0"
arrow2 = { workspace = true, features = ["io_ipc", "io_print"] }
arrow2_convert.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/re_memory/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ all-features = true
re_format.workspace = true
re_log.workspace = true

ahash = "0.8"
ahash.workspace = true
backtrace = { version = "0.3" }
emath.workspace = true
instant = { version = "0.1", features = ["wasm-bindgen"] }
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ serde = ["dep:serde"]
re_error.workspace = true
re_log.workspace = true

ahash = "0.8"
ahash.workspace = true
anyhow.workspace = true
bitflags = "1.3"
bytemuck = { version = "1.12", features = ["derive"] }
Expand Down
16 changes: 3 additions & 13 deletions crates/re_sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,16 @@ demo = []
glam = ["re_log_types/glam"]

## Add the `global_session` method.
global_session = ["dep:once_cell", "dep:parking_lot"]
global_session = ["dep:once_cell"]

## Integration with the [`image`](https://crates.io/crates/image/) crate.
image = ["re_log_types/image"]

# Add a tokio runtime to the `Session` type.
tokio_runtime = ["dep:tokio"]


[dependencies]
re_build_info.workspace = true
re_error.workspace = true
re_log_types.workspace = true
re_log_types = { workspace = true, features = ["save"] }
re_log.workspace = true
re_memory.workspace = true
re_sdk_comms = { workspace = true, features = ["client"] }
Expand All @@ -50,18 +47,11 @@ crossbeam = "0.8"
document-features = "0.2"
lazy_static.workspace = true
nohash-hasher = "0.2"
parking_lot.workspace = true
thiserror.workspace = true

# Optional dependencies:
once_cell = { version = "1.12", optional = true }
parking_lot = { version = "0.12", optional = true }

# Native dependencies:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { workspace = true, optional = true, features = [
"macros",
"rt-multi-thread",
] }


[dev-dependencies]
Expand Down
24 changes: 14 additions & 10 deletions crates/re_sdk/src/file_writer.rs → crates/re_sdk/src/file_sink.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
use std::sync::mpsc::Sender;

use anyhow::Context as _;
use parking_lot::Mutex;

use re_log_types::LogMsg;

/// Stream log messages to a file.
pub struct FileWriter {
/// Stream log messages to an `.rrd` file.
pub struct FileSink {
// None = quit
tx: std::sync::mpsc::Sender<Option<LogMsg>>,
tx: Mutex<Sender<Option<LogMsg>>>,
join_handle: Option<std::thread::JoinHandle<()>>,
}

impl Drop for FileWriter {
impl Drop for FileSink {
fn drop(&mut self) {
self.tx.send(None).ok();
self.tx.lock().send(None).ok();
if let Some(join_handle) = self.join_handle.take() {
join_handle.join().ok();
}
}
}

impl FileWriter {
impl FileSink {
/// Start writing log messages to a file at the given path.
pub fn new(path: impl Into<std::path::PathBuf>) -> anyhow::Result<Self> {
let (tx, rx) = std::sync::mpsc::channel();

Expand Down Expand Up @@ -47,14 +51,14 @@ impl FileWriter {
.context("Failed to spawn thread")?;

Ok(Self {
tx,
tx: tx.into(),
join_handle: Some(join_handle),
})
}
}

impl crate::LogSink for FileWriter {
fn send(&mut self, msg: LogMsg) {
self.tx.send(Some(msg)).ok();
impl crate::sink::LogSink for FileSink {
fn send(&self, msg: LogMsg) {
self.tx.lock().send(Some(msg)).ok();
}
}
28 changes: 13 additions & 15 deletions crates/re_sdk/src/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,22 @@ use crate::session::Session;

/// Access a global [`Session`] singleton for convenient logging.
///
/// By default, logging is enabled. To disable logging, call `set_enabled(false)` on the global `Session`, or
/// set the `RERUN` environment variable to `false`.
pub fn global_session() -> parking_lot::MutexGuard<'static, Session> {
let default_enabled = true;
global_session_with_default_enabled(default_enabled)
}

/// Access a global [`Session`] singleton for convenient logging.
/// The default [`Session`] is a disabled dummy-session that ignore all log calls,
/// so you need to explicitly set the global session for it to be useful
///
/// Example usage:
///
/// The given variable controls if Rerun is enabled by default.
/// It can be overridden with the `RERUN` environment variable.
pub fn global_session_with_default_enabled(
default_enabled: bool,
) -> parking_lot::MutexGuard<'static, Session> {
/// ```
/// use re_sdk::{global_session, SessionBuilder, default_server_addr};
///
/// *global_session() = SessionBuilder::new("my_app").connect(default_server_addr());
///
/// // Call code that logs using `global_session`.
/// ```
pub fn global_session() -> parking_lot::MutexGuard<'static, Session> {
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
static INSTANCE: OnceCell<Mutex<Session>> = OnceCell::new();

let mutex = INSTANCE.get_or_init(|| Mutex::new(Session::with_default_enabled(default_enabled)));
let mutex = INSTANCE.get_or_init(|| Mutex::new(Session::disabled()));
mutex.lock()
}
80 changes: 67 additions & 13 deletions crates/re_sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

#![warn(missing_docs)] // Let's keep the this crate well-documented!

// Send data to a rerun session
// ----------------
// Private modules:

#[cfg(not(target_arch = "wasm32"))]
mod file_writer;
mod file_sink;

#[cfg(feature = "global_session")]
mod global;
Expand All @@ -17,17 +19,38 @@ mod log_sink;
mod msg_sender;
mod session;

// -------------
// Public items:

#[cfg(feature = "global_session")]
pub use self::global::{global_session, global_session_with_default_enabled};
pub use self::global::global_session;

pub use self::msg_sender::{MsgSender, MsgSenderError};
pub use self::session::Session;
pub use log_sink::{BufferedSink, LogSink, TcpSink};
pub use self::session::{Session, SessionBuilder};

pub use re_sdk_comms::default_server_addr;

pub use re_log_types::{
msg_bundle::{Component, SerializableComponent},
ApplicationId, ComponentName, EntityPath, RecordingId,
};

// ---------------
// Public modules:

#[cfg(feature = "demo")]
pub mod demo_util;

pub use re_sdk_comms::default_server_addr;
/// Different destinations for log messages.
///
/// This is how you select whether the log stream ends up
/// sent over TCP, written to file, etc.
pub mod sink {
pub use crate::log_sink::{disabled, BufferedSink, LogSink, TcpSink};

#[cfg(not(target_arch = "wasm32"))]
pub use crate::file_sink::FileSink;
}

/// Things directly related to logging.
pub mod log {
Expand Down Expand Up @@ -76,12 +99,8 @@ pub mod external {
pub use re_log_types::external::image;
}

// ---

pub use re_log_types::{
msg_bundle::{Component, SerializableComponent},
ApplicationId, ComponentName, EntityPath, RecordingId,
};
// -----
// Misc:

const RERUN_ENV_VAR: &str = "RERUN";

Expand All @@ -104,7 +123,7 @@ fn get_rerun_env() -> Option<bool> {
/// Checks the `RERUN` environment variable. If not found, returns the argument.
///
/// Also adds some helpful logging.
fn decide_logging_enabled(default_enabled: bool) -> bool {
pub fn decide_logging_enabled(default_enabled: bool) -> bool {
// We use `info_once` so that we can call this function
// multiple times without spamming the log.
match get_rerun_env() {
Expand All @@ -130,3 +149,38 @@ fn decide_logging_enabled(default_enabled: bool) -> bool {
}
}
}

// ----------------------------------------------------------------------------

/// Creates a new [`re_log_types::RecordingInfo`] which can be used with [`Session::new`].
#[track_caller] // track_caller so that we can see if we are being called from an official example.
pub fn new_recording_info(
application_id: impl Into<re_log_types::ApplicationId>,
) -> re_log_types::RecordingInfo {
re_log_types::RecordingInfo {
application_id: application_id.into(),
recording_id: RecordingId::random(),
is_official_example: called_from_official_rust_example(),
started: re_log_types::Time::now(),
recording_source: re_log_types::RecordingSource::RustSdk {
rustc_version: env!("RE_BUILD_RUSTC_VERSION").into(),
llvm_version: env!("RE_BUILD_LLVM_VERSION").into(),
},
}
}

#[track_caller]
fn called_from_official_rust_example() -> bool {
// The sentinel file we use to identify the official examples directory.
const SENTINEL_FILENAME: &str = ".rerun_examples";
let caller = core::panic::Location::caller();
let mut path = std::path::PathBuf::from(caller.file());
let mut is_official_example = false;
for _ in 0..4 {
path.pop(); // first iteration is always a file path in our examples
if path.join(SENTINEL_FILENAME).exists() {
is_official_example = true;
}
}
is_official_example
}
Loading