Introduce new class of `send_` APIs starting with `send_columns`
Overview
This is a fairly small change with far-reaching implications.
The change establishes a new implicit precedent and divides our data APIs into two categories.
log_APIs which use a logging context manager and send data through a batchersend_APIs which bypass the context manager, and possibly bypass the batcher
Explanation
Generally speaking the log_ APIs are considered higher-level, with a focus on convenience, and don't necessarily support all use-cases or logging patterns. If users find themselves struggling with problems like
My data already has a timestamp. I find it error prone that I need to update the timestamp through a separate call on a context manager and then make a log call while ensuring nothing else has touched that context
Then the answer is "you should be using the send_ APIs."
The send_ APIs are considered lower-level, with a focus on more explicit control and expected behavior. Advanced users, especially those doing more generic mapping of their internal framework pieces to Rerun will very likely gravitate toward these APIs. For example, ROS messages already come with a timestamp in the message header, so the ROS bridge should end up using the send_ APIs to convert a message directly to the row that it represents.
Controversial Proposals
send_ APIs should avoid all global context
Although both APIs surfaces still work on top of the Rerun concept of a RecordingStream, given the explicit nature of send, this is an opportunity to further restrict implicit behaviors such as the thread_local/global streams.
To that end, we should NOT expose rr.send(...) with a default recording stream, and rather require the stream be referenced explicitly as stream.send(...).
send_ APIs should be strict
The fact that our log APIs swallow failures to convert types to Rerun makes sense in the context of a high-level APIs. This is rarely what an advanced user would expect when working with a lower-level API surface.
Failures in the send_ APIs should raise appropriate exceptions that can be caught by a user and handled explicitly.
Design
The log_ APIs:
log(... )log_components(...)disable_timeline(...)reset_time()set_time_nanos(...)set_time_seconds(...)set_time_sequence(...)
Maybe (controversial):
init(... )set_global_data_recording(...)set_thread_local_data_recording(...)set_strict_mode(...)
The send_ APIs
send_temporal_batchallows you to send a batch of time data along with one or more batches of component data.- Other possible names:
send_rows,send_dataframe,send_chunk
- Other possible names:
send_blueprint-- this API already exists, but the usage ofsend_here is well inline with the newly defined intent. It sends a concrete blueprint object directly to the stream without using the context manager or batcher.
In the future, we should also introduce a mono version of send_, which likely needs to work in conjunction with an optional mechanism of providing a batcher.
Problematic APIs
log_file_from_contents(...)log_file_from_path(...)
Both of these are conceptually closer to send_ than they are to log_. I believe they ignore the current log context and choose their own values of time based on the contents of the file. They should probably be deprecated and renamed.
Consequences
send_temporal_batchwill not populatelog_timeorlog_tick
Note: I don't believe this entire issue need to be resolved to decide on the name / direction for the temporal batch APIs for 0.18.
However, if we introduce send_ as the mechanism in the new temporal batch logging, I would expect us to formalized and shift things in this direction for 0.19.