Unverified Commit 45885b11 authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Make RuntimePlugin & RuntimePlugins Send/Sync (#2771)

## Motivation and Context
We will eventually want to store additional runtime plugins on fluent
builders, clients, etc. To make this work, the RuntimePlugin trait needs
to assert Send/Sync

## Description
Small tweaks + test on the RuntimePlugin trait

## Testing
CI


----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 07bd832a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ open class OperationGenerator(
                    """
                    pub(crate) fn register_default_runtime_plugins(
                        runtime_plugins: #{RuntimePlugins},
                        operation: #{Box}<dyn #{RuntimePlugin} + #{Send} + #{Sync}>,
                        operation: impl #{RuntimePlugin} + 'static,
                        handle: #{Arc}<crate::client::Handle>,
                        config_override: #{Option}<crate::config::Builder>,
                    ) -> #{RuntimePlugins} {
@@ -180,7 +180,7 @@ open class OperationGenerator(
                    ) -> #{RuntimePlugins} {
                        #{register_default_runtime_plugins}(
                            runtime_plugins,
                            #{Box}::new(Self::new()) as _,
                            Self::new(),
                            handle,
                            config_override
                        )
+28 −18
Original line number Diff line number Diff line
@@ -6,16 +6,16 @@
use crate::client::interceptors::InterceptorRegistrar;
use aws_smithy_types::config_bag::{ConfigBag, FrozenLayer};
use std::fmt::Debug;
use std::sync::Arc;

pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
pub type BoxRuntimePlugin = Box<dyn RuntimePlugin + Send + Sync>;

/// RuntimePlugin Trait
///
/// A RuntimePlugin is the unit of configuration for augmenting the SDK with new behavior
///
/// Runtime plugins can set configuration and register interceptors.
pub trait RuntimePlugin: Debug {
pub trait RuntimePlugin: Debug + Send + Sync {
    fn config(&self) -> Option<FrozenLayer> {
        None
    }
@@ -25,20 +25,29 @@ pub trait RuntimePlugin: Debug {
    }
}

impl RuntimePlugin for BoxRuntimePlugin {
#[derive(Debug, Clone)]
struct SharedRuntimePlugin(Arc<dyn RuntimePlugin>);

impl SharedRuntimePlugin {
    fn new(plugin: impl RuntimePlugin + 'static) -> Self {
        Self(Arc::new(plugin))
    }
}

impl RuntimePlugin for SharedRuntimePlugin {
    fn config(&self) -> Option<FrozenLayer> {
        self.as_ref().config()
        self.0.config()
    }

    fn interceptors(&self, interceptors: &mut InterceptorRegistrar) {
        self.as_ref().interceptors(interceptors)
        self.0.interceptors(interceptors)
    }
}

#[derive(Default)]
#[derive(Default, Clone, Debug)]
pub struct RuntimePlugins {
    client_plugins: Vec<BoxRuntimePlugin>,
    operation_plugins: Vec<BoxRuntimePlugin>,
    client_plugins: Vec<SharedRuntimePlugin>,
    operation_plugins: Vec<SharedRuntimePlugin>,
}

impl RuntimePlugins {
@@ -46,19 +55,14 @@ impl RuntimePlugins {
        Default::default()
    }

    pub fn with_client_plugin(
        mut self,
        plugin: impl RuntimePlugin + Send + Sync + 'static,
    ) -> Self {
        self.client_plugins.push(Box::new(plugin));
    pub fn with_client_plugin(mut self, plugin: impl RuntimePlugin + 'static) -> Self {
        self.client_plugins.push(SharedRuntimePlugin::new(plugin));
        self
    }

    pub fn with_operation_plugin(
        mut self,
        plugin: impl RuntimePlugin + Send + Sync + 'static,
    ) -> Self {
        self.operation_plugins.push(Box::new(plugin));
    pub fn with_operation_plugin(mut self, plugin: impl RuntimePlugin + 'static) -> Self {
        self.operation_plugins
            .push(SharedRuntimePlugin::new(plugin));
        self
    }

@@ -106,4 +110,10 @@ mod tests {
    fn can_add_runtime_plugin_implementors_to_runtime_plugins() {
        RuntimePlugins::new().with_client_plugin(SomeStruct);
    }

    #[test]
    fn runtime_plugins_are_send_sync() {
        fn assert_send_sync<T: Send + Sync>() {}
        assert_send_sync::<RuntimePlugins>();
    }
}