diff --git a/crates/top/re_sdk/src/recording_stream.rs b/crates/top/re_sdk/src/recording_stream.rs index 8758881f8db5..1e8abc28d071 100644 --- a/crates/top/re_sdk/src/recording_stream.rs +++ b/crates/top/re_sdk/src/recording_stream.rs @@ -310,8 +310,24 @@ impl RecordingStreamBuilder { /// let rec = re_sdk::RecordingStreamBuilder::new("rerun_example_app").connect()?; /// # Ok::<(), Box>(()) /// ``` + #[deprecated(since = "0.20.0", note = "use connect_tcp() instead")] pub fn connect(self) -> RecordingStreamResult { - self.connect_opts(crate::default_server_addr(), crate::default_flush_timeout()) + self.connect_tcp() + } + + /// Creates a new [`RecordingStream`] that is pre-configured to stream the data through to a + /// remote Rerun instance. + /// + /// See also [`Self::connect_opts`] if you wish to configure the TCP connection. + /// + /// ## Example + /// + /// ```no_run + /// let rec = re_sdk::RecordingStreamBuilder::new("rerun_example_app").connect_tcp()?; + /// # Ok::<(), Box>(()) + /// ``` + pub fn connect_tcp(self) -> RecordingStreamResult { + self.connect_tcp_opts(crate::default_server_addr(), crate::default_flush_timeout()) } /// Creates a new [`RecordingStream`] that is pre-configured to stream the data through to a @@ -328,10 +344,33 @@ impl RecordingStreamBuilder { /// .connect_opts(re_sdk::default_server_addr(), re_sdk::default_flush_timeout())?; /// # Ok::<(), Box>(()) /// ``` + #[deprecated(since = "0.20.0", note = "use connect_tcp_opts() instead")] pub fn connect_opts( self, addr: std::net::SocketAddr, flush_timeout: Option, + ) -> RecordingStreamResult { + self.connect_tcp_opts(addr, flush_timeout) + } + + /// Creates a new [`RecordingStream`] that is pre-configured to stream the data through to a + /// remote Rerun instance. + /// + /// `flush_timeout` is the minimum time the [`TcpSink`][`crate::log_sink::TcpSink`] will + /// wait during a flush before potentially dropping data. Note: Passing `None` here can cause a + /// call to `flush` to block indefinitely if a connection cannot be established. + /// + /// ## Example + /// + /// ```no_run + /// let rec = re_sdk::RecordingStreamBuilder::new("rerun_example_app") + /// .connect_opts(re_sdk::default_server_addr(), re_sdk::default_flush_timeout())?; + /// # Ok::<(), Box>(()) + /// ``` + pub fn connect_tcp_opts( + self, + addr: std::net::SocketAddr, + flush_timeout: Option, ) -> RecordingStreamResult { let (enabled, store_info, batcher_config) = self.into_args(); if enabled { @@ -464,12 +503,12 @@ impl RecordingStreamBuilder { // NOTE: If `_RERUN_TEST_FORCE_SAVE` is set, all recording streams will write to disk no matter // what, thus spawning a viewer is pointless (and probably not intended). if forced_sink_path().is_some() { - return self.connect_opts(connect_addr, flush_timeout); + return self.connect_tcp_opts(connect_addr, flush_timeout); } crate::spawn(opts)?; - self.connect_opts(connect_addr, flush_timeout) + self.connect_tcp_opts(connect_addr, flush_timeout) } /// Creates a new [`RecordingStream`] that is pre-configured to stream the data through to a @@ -503,6 +542,7 @@ impl RecordingStreamBuilder { // // # TODO(#5531): keep static data around. #[cfg(feature = "web_viewer")] + #[deprecated(since = "0.20.0", note = "use serve_web() instead")] pub fn serve( self, bind_ip: &str, @@ -510,6 +550,54 @@ impl RecordingStreamBuilder { ws_port: RerunServerPort, server_memory_limit: re_memory::MemoryLimit, open_browser: bool, + ) -> RecordingStreamResult { + self.serve_web( + bind_ip, + web_port, + ws_port, + server_memory_limit, + open_browser, + ) + } + + /// Creates a new [`RecordingStream`] that is pre-configured to stream the data through to a + /// web-based Rerun viewer via WebSockets. + /// + /// If the `open_browser` argument is `true`, your default browser will be opened with a + /// connected web-viewer. + /// + /// If not, you can connect to this server using the `rerun` binary (`cargo install rerun-cli --locked`). + /// + /// ## Details + /// This method will spawn two servers: one HTTPS server serving the Rerun Web Viewer `.html` and `.wasm` files, + /// and then one WebSocket server that streams the log data to the web viewer (or to a native viewer, or to multiple viewers). + /// + /// The WebSocket server will buffer all log data in memory so that late connecting viewers will get all the data. + /// You can limit the amount of data buffered by the WebSocket server with the `server_memory_limit` argument. + /// Once reached, the earliest logged data will be dropped. + /// Note that this means that static data may be dropped if logged early (see ). + /// + /// ## Example + /// + /// ```ignore + /// let rec = re_sdk::RecordingStreamBuilder::new("rerun_example_app") + /// .serve_web("0.0.0.0", + /// Default::default(), + /// Default::default(), + /// re_sdk::MemoryLimit::from_fraction_of_total(0.25), + /// true)?; + /// # Ok::<(), Box>(()) + /// ``` + // + // # TODO(#5531): keep static data around. + #[cfg(feature = "web_viewer")] + pub fn serve_web( + self, + bind_ip: &str, + web_port: WebViewerServerPort, + ws_port: RerunServerPort, + server_memory_limit: re_memory::MemoryLimit, + open_browser: bool, ) -> RecordingStreamResult { let (enabled, store_info, batcher_config) = self.into_args(); if enabled { diff --git a/crates/top/rerun/src/clap.rs b/crates/top/rerun/src/clap.rs index 61c2db5f379b..47ea8d824b9b 100644 --- a/crates/top/rerun/src/clap.rs +++ b/crates/top/rerun/src/clap.rs @@ -112,7 +112,7 @@ impl RerunArgs { RerunBehavior::Connect(addr) => Ok(( RecordingStreamBuilder::new(application_id) - .connect_opts(addr, crate::default_flush_timeout())?, + .connect_tcp_opts(addr, crate::default_flush_timeout())?, Default::default(), )), @@ -132,7 +132,7 @@ impl RerunArgs { .map_err(|err| anyhow::format_err!("Bad --server-memory-limit: {err}"))?; let open_browser = true; - let rec = RecordingStreamBuilder::new(application_id).serve( + let rec = RecordingStreamBuilder::new(application_id).serve_web( &self.bind, Default::default(), Default::default(), diff --git a/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.cpp b/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.cpp index b2144eed9831..1bdd80ab984e 100644 --- a/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.cpp +++ b/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.cpp @@ -6,7 +6,7 @@ using namespace rerun::demo; int main() { // Create a new `RecordingStream` which sends data over TCP to the viewer process. const auto rec = rerun::RecordingStream("rerun_example_quick_start_connect"); - rec.connect().exit_on_failure(); + rec.connect_tcp().exit_on_failure(); // Create some data using the `grid` utility function. std::vector points = grid3d(-10.f, 10.f, 10); diff --git a/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.py b/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.py index 43d082133a78..204393418803 100644 --- a/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.py +++ b/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.py @@ -7,7 +7,7 @@ rr.init("rerun_example_quick_start_connect") # Connect to a local viewer using the default port -rr.connect() +rr.connect_tcp() # Create some data diff --git a/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.rs b/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.rs index 0ccd3064e122..988f0ba019c6 100644 --- a/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.rs +++ b/crates/viewer/re_viewer/data/quick_start_guides/quick_start_connect.rs @@ -4,7 +4,8 @@ use rerun::{demo_util::grid, external::glam}; fn main() -> Result<(), Box> { // Create a new `RecordingStream` which sends data over TCP to the viewer process. - let rec = rerun::RecordingStreamBuilder::new("rerun_example_quick_start_connect").connect()?; + let rec = + rerun::RecordingStreamBuilder::new("rerun_example_quick_start_connect").connect_tcp()?; // Create some data using the `grid` utility function. let points = grid(glam::Vec3::splat(-10.0), glam::Vec3::splat(10.0), 10); diff --git a/docs/content/reference/migration/migration-0-13.md b/docs/content/reference/migration/migration-0-13.md index 1f62440f0286..511e351df01a 100644 --- a/docs/content/reference/migration/migration-0-13.md +++ b/docs/content/reference/migration/migration-0-13.md @@ -1,6 +1,6 @@ --- title: Migrating from 0.12 to 0.13 -order: 130 +order: 996 --- ## `TimeSeriesScalar` deprecated in favor of [Scalar](../types/archetypes/scalar.md) & [SeriesLine](../types/archetypes/series_line.md)/[SeriesPoint](../types/archetypes/series_point.md) diff --git a/docs/content/reference/migration/migration-0-15.md b/docs/content/reference/migration/migration-0-15.md index 7f08871e6ddd..097bc4516b4a 100644 --- a/docs/content/reference/migration/migration-0-15.md +++ b/docs/content/reference/migration/migration-0-15.md @@ -1,6 +1,6 @@ --- title: Migrating from 0.14 to 0.15 -order: 150 +order: 995 --- ## `InstanceKey` removed from our logging APIs diff --git a/docs/content/reference/migration/migration-0-16.md b/docs/content/reference/migration/migration-0-16.md index 4f316a450ba7..3a81e22656c0 100644 --- a/docs/content/reference/migration/migration-0-16.md +++ b/docs/content/reference/migration/migration-0-16.md @@ -1,6 +1,6 @@ --- title: Migrating from 0.15 to 0.16 -order: 160 +order: 994 --- diff --git a/docs/content/reference/migration/migration-0-17.md b/docs/content/reference/migration/migration-0-17.md index 302ce46e9f59..afb233d19080 100644 --- a/docs/content/reference/migration/migration-0-17.md +++ b/docs/content/reference/migration/migration-0-17.md @@ -1,6 +1,6 @@ --- title: Migrating from 0.16 to 0.17 -order: 170 +order: 993 --- diff --git a/docs/content/reference/migration/migration-0-18.md b/docs/content/reference/migration/migration-0-18.md index 27088a602b44..fee00dea4176 100644 --- a/docs/content/reference/migration/migration-0-18.md +++ b/docs/content/reference/migration/migration-0-18.md @@ -1,6 +1,6 @@ --- title: Migrating from 0.17 to 0.18 -order: 180 +order: 992 --- ## ⚠️ Breaking changes diff --git a/docs/content/reference/migration/migration-0-19.md b/docs/content/reference/migration/migration-0-19.md index 2f7388617596..53985ec3bccb 100644 --- a/docs/content/reference/migration/migration-0-19.md +++ b/docs/content/reference/migration/migration-0-19.md @@ -1,6 +1,6 @@ --- title: Migrating from 0.18 to 0.19 -order: 190 +order: 991 --- Blueprint files (.rbl) from previous Rerun versions will no longer load _automatically_. diff --git a/docs/content/reference/migration/migration-0-20.md b/docs/content/reference/migration/migration-0-20.md new file mode 100644 index 000000000000..61984bae4836 --- /dev/null +++ b/docs/content/reference/migration/migration-0-20.md @@ -0,0 +1,20 @@ +--- +title: Migrating from 0.19 to 0.20 +order: 990 +--- + + +## ⚠️ Breaking changes + + +### `connect` -> `connect_tcp` & `serve` -> `serve_web` + +In all SDKs: +* `connect()` is now deprecated in favor `connect_tcp()` +* `serve()` is now deprecated in favor `serve_web()` + +The rationale behind this change is that it was common for users (see https://github.com/rerun-io/rerun/issues/7766). + +We frequently had reports from users that were understandably expecting a serving process (`rr.serve()`) to be ready to accept connections from other processes (`rr.connect()`), when in reality the two things are completely unrelated: one is hosting a websocket server to be polled by the web-viewer, while the other is trying to connect to the TCP SDK comms pipeline. + +You can learn more about Rerun's application model and the different servers and ports by reading our [new documentation page on the matter](../../concepts/app-model.md). diff --git a/docs/content/reference/migration/migration-0-9.md b/docs/content/reference/migration/migration-0-9.md index 5f19a105b7b4..fb9749f08c48 100644 --- a/docs/content/reference/migration/migration-0-9.md +++ b/docs/content/reference/migration/migration-0-9.md @@ -1,6 +1,6 @@ --- title: Migrating from 0.8 to 0.9 -order: 90 +order: 1000 --- Rerun-0.9 introduces a new set of type-oriented logging APIs built on top of an updated, more concrete, diff --git a/docs/snippets/all/concepts/app-model/native-sync.cpp b/docs/snippets/all/concepts/app-model/native-sync.cpp index c36bcc0faa77..1e28f93a0f69 100644 --- a/docs/snippets/all/concepts/app-model/native-sync.cpp +++ b/docs/snippets/all/concepts/app-model/native-sync.cpp @@ -4,7 +4,7 @@ int main() { // Connect to the Rerun TCP server using the default address and // port: localhost:9876 const auto rec = rerun::RecordingStream("rerun_example_native_sync"); - rec.connect().exit_on_failure(); + rec.connect_tcp().exit_on_failure(); // Log data as usual, thereby pushing it into the TCP socket. while (true) { diff --git a/docs/snippets/all/concepts/app-model/native-sync.py b/docs/snippets/all/concepts/app-model/native-sync.py index 6847e4e3fb71..831ff39a7dd0 100755 --- a/docs/snippets/all/concepts/app-model/native-sync.py +++ b/docs/snippets/all/concepts/app-model/native-sync.py @@ -6,7 +6,7 @@ # Connect to the Rerun TCP server using the default address and # port: localhost:9876 -rr.connect() +rr.connect_tcp() # Log data as usual, thereby pushing it into the TCP socket. while True: diff --git a/docs/snippets/all/concepts/app-model/native-sync.rs b/docs/snippets/all/concepts/app-model/native-sync.rs index 2db8313dd9df..9ee90e0ea1ab 100644 --- a/docs/snippets/all/concepts/app-model/native-sync.rs +++ b/docs/snippets/all/concepts/app-model/native-sync.rs @@ -1,7 +1,7 @@ fn main() -> Result<(), Box> { // Connect to the Rerun TCP server using the default address and // port: localhost:9876 - let rec = rerun::RecordingStreamBuilder::new("rerun_example_native_sync").connect()?; + let rec = rerun::RecordingStreamBuilder::new("rerun_example_native_sync").connect_tcp()?; // Log data as usual, thereby pushing it into the TCP socket. loop { diff --git a/docs/snippets/all/quick_start/quick_start_connect.cpp b/docs/snippets/all/quick_start/quick_start_connect.cpp index b2144eed9831..1bdd80ab984e 100644 --- a/docs/snippets/all/quick_start/quick_start_connect.cpp +++ b/docs/snippets/all/quick_start/quick_start_connect.cpp @@ -6,7 +6,7 @@ using namespace rerun::demo; int main() { // Create a new `RecordingStream` which sends data over TCP to the viewer process. const auto rec = rerun::RecordingStream("rerun_example_quick_start_connect"); - rec.connect().exit_on_failure(); + rec.connect_tcp().exit_on_failure(); // Create some data using the `grid` utility function. std::vector points = grid3d(-10.f, 10.f, 10); diff --git a/docs/snippets/all/quick_start/quick_start_connect.py b/docs/snippets/all/quick_start/quick_start_connect.py index 43d082133a78..204393418803 100644 --- a/docs/snippets/all/quick_start/quick_start_connect.py +++ b/docs/snippets/all/quick_start/quick_start_connect.py @@ -7,7 +7,7 @@ rr.init("rerun_example_quick_start_connect") # Connect to a local viewer using the default port -rr.connect() +rr.connect_tcp() # Create some data diff --git a/docs/snippets/all/quick_start/quick_start_connect.rs b/docs/snippets/all/quick_start/quick_start_connect.rs index 0ccd3064e122..988f0ba019c6 100644 --- a/docs/snippets/all/quick_start/quick_start_connect.rs +++ b/docs/snippets/all/quick_start/quick_start_connect.rs @@ -4,7 +4,8 @@ use rerun::{demo_util::grid, external::glam}; fn main() -> Result<(), Box> { // Create a new `RecordingStream` which sends data over TCP to the viewer process. - let rec = rerun::RecordingStreamBuilder::new("rerun_example_quick_start_connect").connect()?; + let rec = + rerun::RecordingStreamBuilder::new("rerun_example_quick_start_connect").connect_tcp()?; // Create some data using the `grid` utility function. let points = grid(glam::Vec3::splat(-10.0), glam::Vec3::splat(10.0), 10); diff --git a/docs/snippets/all/tutorials/data_out.py b/docs/snippets/all/tutorials/data_out.py index c0f6e214c077..cdca9a39ff91 100644 --- a/docs/snippets/all/tutorials/data_out.py +++ b/docs/snippets/all/tutorials/data_out.py @@ -27,7 +27,7 @@ # Connect to the viewer rr.init(recording.application_id(), recording_id=recording.recording_id()) -rr.connect() +rr.connect_tcp() # log the jaw open state signal as a scalar rr.send_columns( diff --git a/examples/cpp/log_file/main.cpp b/examples/cpp/log_file/main.cpp index a1a6871bd78f..cedba41b387d 100644 --- a/examples/cpp/log_file/main.cpp +++ b/examples/cpp/log_file/main.cpp @@ -43,7 +43,7 @@ int main(int argc, char** argv) { if (args["spawn"].as()) { rec.spawn().exit_on_failure(); } else if (args["connect"].as()) { - rec.connect().exit_on_failure(); + rec.connect_tcp().exit_on_failure(); } else if (args["stdout"].as()) { rec.to_stdout().exit_on_failure(); } else if (args.count("save")) { diff --git a/examples/python/multiprocess_logging/README.md b/examples/python/multiprocess_logging/README.md index 48647fb22f89..e49cbfdcc826 100644 --- a/examples/python/multiprocess_logging/README.md +++ b/examples/python/multiprocess_logging/README.md @@ -29,7 +29,7 @@ The function `task` is decorated with `@rr.shutdown_at_exit`. This decorator ens def task(child_index: int) -> None: rr.init("rerun_example_multiprocessing") - rr.connect() + rr.connect_tcp() title = f"task_{child_index}" rr.log( diff --git a/examples/python/multiprocess_logging/multiprocess_logging.py b/examples/python/multiprocess_logging/multiprocess_logging.py index a1a61ba312ce..7721ff4794ab 100755 --- a/examples/python/multiprocess_logging/multiprocess_logging.py +++ b/examples/python/multiprocess_logging/multiprocess_logging.py @@ -24,7 +24,7 @@ def task(child_index: int) -> None: rr.init("rerun_example_multiprocessing") # We then have to connect to the viewer instance. - rr.connect() + rr.connect_tcp() title = f"task_{child_index}" rr.log( diff --git a/examples/rust/chess_robby_fischer/README.md b/examples/rust/chess_robby_fischer/README.md index 27a09890d44c..bdff31ceb8ac 100644 --- a/examples/rust/chess_robby_fischer/README.md +++ b/examples/rust/chess_robby_fischer/README.md @@ -30,7 +30,7 @@ let app_id = "RobbyFischer"; let rec_id = uuid::Uuid::new_v4().to_string(); let rec = rerun::RecordingStreamBuilder::new(app_id) .recording_id(&rec_id) - .connect() + .connect_tcp() .unwrap(); // … @@ -323,7 +323,7 @@ parser.add_argument("--application-id", type=str) args = parser.parse_args() rr.init(args.application_id, recording_id=args.recording_id) -rr.connect() +rr.connect_tcp() rr.send_blueprint(blueprint) ``` diff --git a/examples/rust/minimal_serve/src/main.rs b/examples/rust/minimal_serve/src/main.rs index 6cddaf9b3587..5a23c8b4b01c 100644 --- a/examples/rust/minimal_serve/src/main.rs +++ b/examples/rust/minimal_serve/src/main.rs @@ -4,7 +4,7 @@ use rerun::{demo_util::grid, external::glam}; fn main() -> Result<(), Box> { let open_browser = true; - let rec = rerun::RecordingStreamBuilder::new("rerun_example_minimal_serve").serve( + let rec = rerun::RecordingStreamBuilder::new("rerun_example_minimal_serve").serve_web( "0.0.0.0", Default::default(), Default::default(), diff --git a/rerun_cpp/docs/readme_snippets.cpp b/rerun_cpp/docs/readme_snippets.cpp index 63dedc1f19c8..4c55ef12418d 100644 --- a/rerun_cpp/docs/readme_snippets.cpp +++ b/rerun_cpp/docs/readme_snippets.cpp @@ -45,7 +45,7 @@ static std::vector create_image() { [[maybe_unused]] static void connecting() { /// [Connecting] rerun::RecordingStream rec("rerun_example_app"); - auto result = rec.connect(); // Connect to local host with default port. + auto result = rec.connect_tcp(); // Connect to local host with default port. if (result.is_err()) { // Handle error. } diff --git a/rerun_cpp/src/rerun/recording_stream.cpp b/rerun_cpp/src/rerun/recording_stream.cpp index 88de76f09872..6e4beb273572 100644 --- a/rerun_cpp/src/rerun/recording_stream.cpp +++ b/rerun_cpp/src/rerun/recording_stream.cpp @@ -101,6 +101,10 @@ namespace rerun { } Error RecordingStream::connect(std::string_view tcp_addr, float flush_timeout_sec) const { + return RecordingStream::connect_tcp(tcp_addr, flush_timeout_sec); + } + + Error RecordingStream::connect_tcp(std::string_view tcp_addr, float flush_timeout_sec) const { rr_error status = {}; rr_recording_stream_connect( _id, diff --git a/rerun_cpp/src/rerun/recording_stream.hpp b/rerun_cpp/src/rerun/recording_stream.hpp index 854b561d7487..f07549fde1e7 100644 --- a/rerun_cpp/src/rerun/recording_stream.hpp +++ b/rerun_cpp/src/rerun/recording_stream.hpp @@ -143,8 +143,23 @@ namespace rerun { /// timeout, and can cause a call to `flush` to block indefinitely. /// /// This function returns immediately. - Error connect(std::string_view tcp_addr = "127.0.0.1:9876", float flush_timeout_sec = 2.0) - const; + [[deprecated("Use `connect_tcp` instead")]] Error connect( + std::string_view tcp_addr = "127.0.0.1:9876", float flush_timeout_sec = 2.0 + ) const; + + /// Connect to a remote Rerun Viewer on the given ip:port. + /// + /// Requires that you first start a Rerun Viewer by typing 'rerun' in a terminal. + /// + /// flush_timeout_sec: + /// The minimum time the SDK will wait during a flush before potentially + /// dropping data if progress is not being made. Passing a negative value indicates no + /// timeout, and can cause a call to `flush` to block indefinitely. + /// + /// This function returns immediately. + Error connect_tcp( + std::string_view tcp_addr = "127.0.0.1:9876", float flush_timeout_sec = 2.0 + ) const; /// Spawns a new Rerun Viewer process from an executable available in PATH, then connects to it /// over TCP. diff --git a/rerun_cpp/tests/recording_stream.cpp b/rerun_cpp/tests/recording_stream.cpp index 691998ff7d0e..4208c69e179c 100644 --- a/rerun_cpp/tests/recording_stream.cpp +++ b/rerun_cpp/tests/recording_stream.cpp @@ -380,14 +380,14 @@ void test_logging_to_connection(const char* address, const rerun::RecordingStrea AND_GIVEN("an invalid address for the socket address") { THEN("then the save call fails") { CHECK( - stream.connect("definitely not valid!", 0.0f).code == + stream.connect_tcp("definitely not valid!", 0.0f).code == rerun::ErrorCode::InvalidSocketAddress ); } } AND_GIVEN("a valid socket address " << address) { THEN("save call with zero timeout returns no error") { - REQUIRE(stream.connect(address, 0.0f).is_ok()); + REQUIRE(stream.connect_tcp(address, 0.0f).is_ok()); WHEN("logging a component and then flushing") { check_logged_error([&] { diff --git a/rerun_py/docs/gen_common_index.py b/rerun_py/docs/gen_common_index.py index 8462277bb0d3..ec707a60be49 100755 --- a/rerun_py/docs/gen_common_index.py +++ b/rerun_py/docs/gen_common_index.py @@ -10,7 +10,7 @@ Function | Description -------- | ----------- [rerun.init()](initialization/#rerun.init) | Initialize the Rerun SDK … -[rerun.connect()](initialization/#rerun.connect) | Connect to a remote Rerun Viewer on the … +[rerun.connect_tcp()](initialization/#rerun.connect_tcp) | Connect to a remote Rerun Viewer on the … [rerun.spawn()](initialization/#rerun.spawn) | Spawn a Rerun Viewer … … @@ -85,10 +85,12 @@ class Section: func_list=[ "init", "connect", + "connect_tcp", "disconnect", "save", "send_blueprint", "serve", + "serve_web", "spawn", "memory_recording", "notebook_show", diff --git a/rerun_py/rerun_sdk/rerun/__init__.py b/rerun_py/rerun_sdk/rerun/__init__.py index ef36706e1059..c88a68168a0d 100644 --- a/rerun_py/rerun_sdk/rerun/__init__.py +++ b/rerun_py/rerun_sdk/rerun/__init__.py @@ -154,10 +154,12 @@ ) from .sinks import ( connect as connect, + connect_tcp as connect_tcp, disconnect as disconnect, save as save, send_blueprint as send_blueprint, serve as serve, + serve_web as serve_web, spawn as spawn, stdout as stdout, ) diff --git a/rerun_py/rerun_sdk/rerun/sinks.py b/rerun_py/rerun_sdk/rerun/sinks.py index c38cf6a3eddd..0d26b98dc98f 100644 --- a/rerun_py/rerun_sdk/rerun/sinks.py +++ b/rerun_py/rerun_sdk/rerun/sinks.py @@ -2,8 +2,10 @@ import logging import pathlib +import warnings import rerun_bindings as bindings # type: ignore[attr-defined] +from typing_extensions import deprecated # type: ignore[misc, unused-ignore] from rerun.blueprint.api import BlueprintLike, create_in_memory_blueprint from rerun.recording_stream import RecordingStream, get_application_id @@ -19,6 +21,10 @@ def is_recording_enabled(recording: RecordingStream | None) -> bool: return bindings.is_enabled() # type: ignore[no-any-return] +@deprecated( + """Please migrate to `rr.connect_tcp(…)`. + See: https://www.rerun.io/docs/reference/migration-0-20?speculative-link for more details.""" +) def connect( addr: str | None = None, *, @@ -29,6 +35,54 @@ def connect( """ Connect to a remote Rerun Viewer on the given ip:port. + !!! Warning "Deprecated" + Please migrate to [rerun.connect_tcp][]. + See [the migration guide](https://www.rerun.io/docs/reference/migration-0-20?speculative-link) for more details. + + Requires that you first start a Rerun Viewer by typing 'rerun' in a terminal. + + This function returns immediately. + + Parameters + ---------- + addr: + The ip:port to connect to + flush_timeout_sec: + The minimum time the SDK will wait during a flush before potentially + dropping data if progress is not being made. Passing `None` indicates no timeout, + and can cause a call to `flush` to block indefinitely. + default_blueprint + Optionally set a default blueprint to use for this application. If the application + already has an active blueprint, the new blueprint won't become active until the user + clicks the "reset blueprint" button. If you want to activate the new blueprint + immediately, instead use the [`rerun.send_blueprint`][] API. + recording: + Specifies the [`rerun.RecordingStream`][] to use. + If left unspecified, defaults to the current active data recording, if there is one. + See also: [`rerun.init`][], [`rerun.set_global_data_recording`][]. + + """ + + warnings.warn( + message=("`connect` is deprecated. Use `connect_tcp` instead."), + category=DeprecationWarning, + ) + + return connect_tcp( + addr, flush_timeout_sec=flush_timeout_sec, default_blueprint=default_blueprint, recording=recording + ) + + +def connect_tcp( + addr: str | None = None, + *, + flush_timeout_sec: float | None = 2.0, + default_blueprint: BlueprintLike | None = None, + recording: RecordingStream | None = None, +) -> None: + """ + Connect to a remote Rerun Viewer on the given ip:port. + Requires that you first start a Rerun Viewer by typing 'rerun' in a terminal. This function returns immediately. @@ -72,14 +126,11 @@ def connect( recording = RecordingStream.to_native(recording) - bindings.connect( + bindings.connect_tcp( addr=addr, flush_timeout_sec=flush_timeout_sec, default_blueprint=blueprint_storage, recording=recording ) -_connect = connect # we need this because Python scoping is horrible - - def save( path: str | pathlib.Path, default_blueprint: BlueprintLike | None = None, recording: RecordingStream | None = None ) -> None: @@ -196,6 +247,10 @@ def disconnect(recording: RecordingStream | None = None) -> None: bindings.disconnect(recording=recording) +@deprecated( + """Please migrate to `rr.serve_web(…)`. + See: https://www.rerun.io/docs/reference/migration-0-20?speculative-link for more details.""" +) def serve( *, open_browser: bool = True, @@ -208,6 +263,69 @@ def serve( """ Serve log-data over WebSockets and serve a Rerun web viewer over HTTP. + !!! Warning "Deprecated" + Please migrate to [rerun.serve_web][]. + See [the migration guide](https://www.rerun.io/docs/reference/migration-0-20?speculative-link) for more details. + + You can also connect to this server with the native viewer using `rerun localhost:9090`. + + The WebSocket server will buffer all log data in memory so that late connecting viewers will get all the data. + You can limit the amount of data buffered by the WebSocket server with the `server_memory_limit` argument. + Once reached, the earliest logged data will be dropped. + Note that this means that static data may be dropped if logged early (see ). + + This function returns immediately. + + Parameters + ---------- + open_browser: + Open the default browser to the viewer. + web_port: + The port to serve the web viewer on (defaults to 9090). + ws_port: + The port to serve the WebSocket server on (defaults to 9877) + default_blueprint: + Optionally set a default blueprint to use for this application. If the application + already has an active blueprint, the new blueprint won't become active until the user + clicks the "reset blueprint" button. If you want to activate the new blueprint + immediately, instead use the [`rerun.send_blueprint`][] API. + recording: + Specifies the [`rerun.RecordingStream`][] to use. + If left unspecified, defaults to the current active data recording, if there is one. + See also: [`rerun.init`][], [`rerun.set_global_data_recording`][]. + server_memory_limit: + Maximum amount of memory to use for buffering log data for clients that connect late. + This can be a percentage of the total ram (e.g. "50%") or an absolute value (e.g. "4GB"). + + """ + + warnings.warn( + message=("`serve` is deprecated. Use `serve_web` instead."), + category=DeprecationWarning, + ) + + return serve_web( + open_browser=open_browser, + web_port=web_port, + ws_port=ws_port, + default_blueprint=default_blueprint, + recording=recording, + server_memory_limit=server_memory_limit, + ) + + +def serve_web( + *, + open_browser: bool = True, + web_port: int | None = None, + ws_port: int | None = None, + default_blueprint: BlueprintLike | None = None, + recording: RecordingStream | None = None, + server_memory_limit: str = "25%", +) -> None: + """ + Serve log-data over WebSockets and serve a Rerun web viewer over HTTP. + You can also connect to this server with the native viewer using `rerun localhost:9090`. The WebSocket server will buffer all log data in memory so that late connecting viewers will get all the data. @@ -359,4 +477,4 @@ def spawn( _spawn_viewer(port=port, memory_limit=memory_limit, hide_welcome_screen=hide_welcome_screen) if connect: - _connect(f"127.0.0.1:{port}", recording=recording, default_blueprint=default_blueprint) + connect_tcp(f"127.0.0.1:{port}", recording=recording, default_blueprint=default_blueprint) diff --git a/rerun_py/src/python_bridge.rs b/rerun_py/src/python_bridge.rs index cc42dba4fea6..33d37b6e43c0 100644 --- a/rerun_py/src/python_bridge.rs +++ b/rerun_py/src/python_bridge.rs @@ -137,14 +137,14 @@ fn rerun_bindings(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> { // sinks m.add_function(wrap_pyfunction!(is_enabled, m)?)?; m.add_function(wrap_pyfunction!(binary_stream, m)?)?; - m.add_function(wrap_pyfunction!(connect, m)?)?; - m.add_function(wrap_pyfunction!(connect_blueprint, m)?)?; + m.add_function(wrap_pyfunction!(connect_tcp, m)?)?; + m.add_function(wrap_pyfunction!(connect_tcp_blueprint, m)?)?; m.add_function(wrap_pyfunction!(save, m)?)?; m.add_function(wrap_pyfunction!(save_blueprint, m)?)?; m.add_function(wrap_pyfunction!(stdout, m)?)?; m.add_function(wrap_pyfunction!(memory_recording, m)?)?; m.add_function(wrap_pyfunction!(set_callback_sink, m)?)?; - m.add_function(wrap_pyfunction!(serve, m)?)?; + m.add_function(wrap_pyfunction!(serve_web, m)?)?; m.add_function(wrap_pyfunction!(disconnect, m)?)?; m.add_function(wrap_pyfunction!(flush, m)?)?; @@ -573,7 +573,7 @@ fn spawn( #[pyfunction] #[pyo3(signature = (addr = None, flush_timeout_sec=re_sdk::default_flush_timeout().expect("always Some()").as_secs_f32(), default_blueprint = None, recording = None))] -fn connect( +fn connect_tcp( addr: Option, flush_timeout_sec: Option, default_blueprint: Option<&PyMemorySinkStorage>, @@ -619,7 +619,7 @@ fn connect( #[pyfunction] #[pyo3(signature = (addr, make_active, make_default, blueprint_stream))] /// Special binding for directly sending a blueprint stream to a connection. -fn connect_blueprint( +fn connect_tcp_blueprint( addr: Option, make_active: bool, make_default: bool, @@ -945,7 +945,7 @@ impl PyBinarySinkStorage { #[allow(clippy::unnecessary_wraps)] // False positive #[pyfunction] #[pyo3(signature = (open_browser, web_port, ws_port, server_memory_limit, default_blueprint = None, recording = None))] -fn serve( +fn serve_web( open_browser: bool, web_port: Option, ws_port: Option, diff --git a/tests/cpp/plot_dashboard_stress/main.cpp b/tests/cpp/plot_dashboard_stress/main.cpp index fab96506f774..e3181c01b895 100644 --- a/tests/cpp/plot_dashboard_stress/main.cpp +++ b/tests/cpp/plot_dashboard_stress/main.cpp @@ -59,7 +59,7 @@ int main(int argc, char** argv) { if (args["spawn"].as()) { rec.spawn().exit_on_failure(); } else if (args["connect"].as()) { - rec.connect().exit_on_failure(); + rec.connect_tcp().exit_on_failure(); } else if (args["stdout"].as()) { rec.to_stdout().exit_on_failure(); } else if (args.count("save")) { diff --git a/tests/python/gil_stress/main.py b/tests/python/gil_stress/main.py index 0b58410074e4..b3a2152b6d00 100644 --- a/tests/python/gil_stress/main.py +++ b/tests/python/gil_stress/main.py @@ -35,7 +35,7 @@ rr.log("test", rr.Points3D([1, 2, 3]), recording=rec.inner) rec = rr.new_recording(application_id="test") -rr.connect(recording=rec) +rr.connect_tcp(recording=rec) rr.log("test", rr.Points3D([1, 2, 3]), recording=rec.inner) rec = rr.new_recording(application_id="test")