Repository: tokio-rs/tokio
File: tokio/src/runtime/builder.rs (Rust)

Code before:
    /// # pub fn main() {
    /// let runtime = runtime::Builder::new_current_thread()
    ///     .on_task_spawn(|_| {
    ///         println!("spawning task");
    ///     })
    ///     .build()
    ///     .unwrap();
    ///
    /// runtime.block_on(async {
    ///     tokio::task::spawn(std::future::ready(()));
    ///
    ///     for _ in 0..64 {
    ///         tokio::task::yield_now().await;
    ///     }
    /// })
    /// # }
    /// ```
    #[cfg(all(not(loom), tokio_unstable))]
    #[cfg_attr(docsrs, doc(cfg(tokio_unstable)))]
    pub fn on_task_spawn<F>(&mut self, f: F) -> &mut Self
    where
        F: Fn(&TaskMeta<'_>) + Send + Sync + 'static,
    {
        self.before_spawn = Some(std::sync::Arc::new(f));
        self
    }

    /// Executes function `f` just after a task is terminated.
    ///
    /// `f` is called within the Tokio context, so functions like
    /// [`tokio::spawn`](crate::spawn) can be called.
    ///
    /// This can be used for bookkeeping or monitoring purposes.
    ///
    /// Note: There can only be one task termination callback for a runtime; calling this
    /// function more than once replaces the last callback defined, rather than adding to it.
    ///
    /// This *does not* support [`LocalSet`](crate::task::LocalSet) at this time.
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    /// # pub fn main() {
    /// let runtime = runtime::Builder::new_current_thread()
    ///     .on_task_terminate(|_| {
    ///         println!("killing task");
    ///     })
    ///     .build()
    ///     .unwrap();
    ///

Review comment (suggestion):
Please also add the docs blurb about this being unstable.
```rs
/// **Note**: This is an [unstable API][unstable]. The public API of this type
/// may break in 1.x releases. See [the documentation on unstable
/// features][unstable] for details.
///
/// [unstable]: crate#unstable-features
```
I would add it to `on_task_spawn`, `on_task_terminate`, and `TaskMeta`. Probably not to `MultiThreadAlt`.

Code after:
    /// [unstable]: crate#unstable-features  
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    /// # pub fn main() {
    /// let runtime = runtime::Builder::new_current_thread()
    ///     .on_task_spawn(|_| {
    ///         println!("spawning task");
    ///     })
    ///     .build()
    ///     .unwrap();
    ///
    /// runtime.block_on(async {
    ///     tokio::task::spawn(std::future::ready(()));
    ///
    ///     for _ in 0..64 {
    ///         tokio::task::yield_now().await;
    ///     }
    /// })
    /// # }
    /// ```
    #[cfg(all(not(loom), tokio_unstable))]
    #[cfg_attr(docsrs, doc(cfg(tokio_unstable)))]
    pub fn on_task_spawn<F>(&mut self, f: F) -> &mut Self
    where
        F: Fn(&TaskMeta<'_>) + Send + Sync + 'static,
    {
        self.before_spawn = Some(std::sync::Arc::new(f));
        self
    }

    /// Executes function `f` just after a task is terminated.
    ///
    /// `f` is called within the Tokio context, so functions like
    /// [`tokio::spawn`](crate::spawn) can be called.
    ///
    /// This can be used for bookkeeping or monitoring purposes.
    ///
    /// Note: There can only be one task termination callback for a runtime; calling this
    /// function more than once replaces the last callback defined, rather than adding to it.
    ///
    /// This *does not* support [`LocalSet`](crate::task::LocalSet) at this time.
    ///
    /// **Note**: This is an [unstable API][unstable]. The public API of this type  
    /// may break in 1.x releases. See [the documentation on unstable  
    /// features][unstable] for details.  
    ///  
    /// [unstable]: crate#unstable-features  
    ///