Unverified Commit 47b3d23f authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Create client runtime plugins once at client construction (#2819)

This PR refactors the fluent client so that the client runtime plugins
are created exactly once at client creation time, and reused thereafter.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 6532a2be
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -320,9 +320,8 @@ class AwsPresignedFluentBuilderMethod(
            """
            #{alternate_presigning_serializer}

            let runtime_plugins = #{Operation}::register_runtime_plugins(
                #{RuntimePlugins}::new(),
                self.handle.clone(),
            let runtime_plugins = #{Operation}::operation_runtime_plugins(
                self.handle.runtime_plugins.clone(),
                self.config_override
            )
                .with_client_plugin(#{SigV4PresigningRuntimePlugin}::new(presigning_config, #{payload_override}))
@@ -344,8 +343,7 @@ class AwsPresignedFluentBuilderMethod(
            *codegenScope,
            "Operation" to codegenContext.symbolProvider.toSymbol(section.operationShape),
            "OperationError" to section.operationErrorType,
            "RuntimePlugins" to RuntimeType.smithyRuntimeApi(runtimeConfig)
                .resolve("client::runtime_plugin::RuntimePlugins"),
            "RuntimePlugins" to RuntimeType.runtimePlugins(runtimeConfig),
            "SharedInterceptor" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::interceptors")
                .resolve("SharedInterceptor"),
            "SigV4PresigningRuntimePlugin" to AwsRuntimeType.presigningInterceptor(runtimeConfig)
+1 −1
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ class CredentialsIdentityResolverRegistration(
    override fun section(section: ServiceRuntimePluginSection): Writable = writable {
        when (section) {
            is ServiceRuntimePluginSection.AdditionalConfig -> {
                rustBlockTemplate("if let Some(credentials_cache) = self.handle.conf.credentials_cache()") {
                rustBlockTemplate("if let Some(credentials_cache) = ${section.serviceConfigName}.credentials_cache()") {
                    section.registerIdentityResolver(this, runtimeConfig) {
                        rustTemplate(
                            """
+9 −47
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@ package software.amazon.smithy.rust.codegen.client.smithy.generators

import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.customize.AuthOption
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.generators.EndpointParamsInterceptorGenerator
@@ -23,7 +22,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
import software.amazon.smithy.rust.codegen.core.smithy.customize.writeCustomizations
@@ -45,39 +43,6 @@ open class OperationGenerator(
    // TODO(enableNewSmithyRuntimeCleanup): Remove the `traitGenerator`
    private val traitGenerator: HttpBoundProtocolTraitImplGenerator,
) {
    companion object {
        fun registerDefaultRuntimePluginsFn(runtimeConfig: RuntimeConfig): RuntimeType =
            RuntimeType.forInlineFun("register_default_runtime_plugins", ClientRustModule.Operation) {
                rustTemplate(
                    """
                    pub(crate) fn register_default_runtime_plugins(
                        runtime_plugins: #{RuntimePlugins},
                        operation: impl #{RuntimePlugin} + 'static,
                        handle: #{Arc}<crate::client::Handle>,
                        config_override: #{Option}<crate::config::Builder>,
                    ) -> #{RuntimePlugins} {
                        let mut runtime_plugins = runtime_plugins
                            .with_client_plugin(handle.conf.clone())
                            .with_client_plugin(crate::config::ServiceRuntimePlugin::new(handle))
                            .with_client_plugin(#{NoAuthRuntimePlugin}::new())
                            .with_operation_plugin(operation);
                        if let Some(config_override) = config_override {
                            runtime_plugins = runtime_plugins.with_operation_plugin(config_override);
                        }
                        runtime_plugins
                    }
                    """,
                    *preludeScope,
                    "Arc" to RuntimeType.Arc,
                    "RuntimePlugin" to RuntimeType.runtimePlugin(runtimeConfig),
                    "RuntimePlugins" to RuntimeType.smithyRuntimeApi(runtimeConfig)
                        .resolve("client::runtime_plugin::RuntimePlugins"),
                    "NoAuthRuntimePlugin" to RuntimeType.smithyRuntime(runtimeConfig)
                        .resolve("client::auth::no_auth::NoAuthRuntimePlugin"),
                )
            }
    }

    private val model = codegenContext.model
    private val runtimeConfig = codegenContext.runtimeConfig
    private val symbolProvider = codegenContext.symbolProvider
@@ -180,17 +145,15 @@ open class OperationGenerator(
                        #{invoke_with_stop_point}(input, runtime_plugins, stop_point).await
                    }

                    pub(crate) fn register_runtime_plugins(
                        runtime_plugins: #{RuntimePlugins},
                        handle: #{Arc}<crate::client::Handle>,
                    pub(crate) fn operation_runtime_plugins(
                        client_runtime_plugins: #{RuntimePlugins},
                        config_override: #{Option}<crate::config::Builder>,
                    ) -> #{RuntimePlugins} {
                        #{register_default_runtime_plugins}(
                            runtime_plugins,
                            Self::new(),
                            handle,
                            config_override
                        )
                        let mut runtime_plugins = client_runtime_plugins.with_operation_plugin(Self::new());
                        if let Some(config_override) = config_override {
                            runtime_plugins = runtime_plugins.with_operation_plugin(config_override);
                        }
                        runtime_plugins
                            #{additional_runtime_plugins}
                    }
                    """,
@@ -200,10 +163,9 @@ open class OperationGenerator(
                    "InterceptorContext" to RuntimeType.interceptorContext(runtimeConfig),
                    "OrchestratorError" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::orchestrator::error::OrchestratorError"),
                    "RuntimePlugin" to RuntimeType.runtimePlugin(runtimeConfig),
                    "RuntimePlugins" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::runtime_plugin::RuntimePlugins"),
                    "RuntimePlugins" to RuntimeType.runtimePlugins(runtimeConfig),
                    "StopPoint" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::orchestrator::StopPoint"),
                    "invoke_with_stop_point" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::orchestrator::invoke_with_stop_point"),
                    "register_default_runtime_plugins" to registerDefaultRuntimePluginsFn(runtimeConfig),
                    "additional_runtime_plugins" to writable {
                        writeCustomizations(
                            operationCustomizations,
+4 −6
Original line number Diff line number Diff line
@@ -240,15 +240,13 @@ class PaginatorGenerator private constructor(
                if (codegenContext.smithyRuntimeMode.defaultToOrchestrator) {
                    rustTemplate(
                        """
                        let runtime_plugins = #{operation}::register_runtime_plugins(
                            #{RuntimePlugins}::new(),
                            handle,
                            None
                        let runtime_plugins = #{operation}::operation_runtime_plugins(
                            handle.runtime_plugins.clone(),
                            None,
                        );
                        """,
                        *codegenScope,
                        "RuntimePlugins" to RuntimeType.smithyRuntimeApi(runtimeConfig)
                            .resolve("client::runtime_plugin::RuntimePlugins"),
                        "RuntimePlugins" to RuntimeType.runtimePlugins(runtimeConfig),
                    )
                }
            },
+10 −15
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ sealed class ServiceRuntimePluginSection(name: String) : Section(name) {
    /**
     * Hook for adding additional things to config inside service runtime plugins.
     */
    data class AdditionalConfig(val newLayerName: String) : ServiceRuntimePluginSection("AdditionalConfig") {
    data class AdditionalConfig(val newLayerName: String, val serviceConfigName: String) : ServiceRuntimePluginSection("AdditionalConfig") {
        /** Adds a value to the config bag */
        fun putConfigValue(writer: RustWriter, value: Writable) {
            writer.rust("$newLayerName.store_put(#T);", value)
@@ -107,27 +107,28 @@ class ServiceRuntimePluginGenerator(
        customizations: List<ServiceRuntimePluginCustomization>,
    ) {
        val additionalConfig = writable {
            writeCustomizations(customizations, ServiceRuntimePluginSection.AdditionalConfig("cfg"))
            writeCustomizations(customizations, ServiceRuntimePluginSection.AdditionalConfig("cfg", "_service_config"))
        }
        writer.rustTemplate(
            """
            // TODO(enableNewSmithyRuntimeLaunch) Remove `allow(dead_code)` as well as a field `handle` when
            //  the field is no longer used.
            ##[allow(dead_code)]
            ##[derive(Debug)]
            pub(crate) struct ServiceRuntimePlugin {
                handle: #{Arc}<crate::client::Handle>,
                config: #{Option}<#{FrozenLayer}>,
            }

            impl ServiceRuntimePlugin {
                pub fn new(handle: #{Arc}<crate::client::Handle>) -> Self {
                    Self { handle }
                pub fn new(_service_config: crate::config::Config) -> Self {
                    Self {
                        config: {
                            #{config}
                        },
                    }
                }
            }

            impl #{RuntimePlugin} for ServiceRuntimePlugin {
                fn config(&self) -> #{Option}<#{FrozenLayer}> {
                    #{config}
                    self.config.clone()
                }

                fn interceptors(&self, interceptors: &mut #{InterceptorRegistrar}) {
@@ -145,13 +146,7 @@ class ServiceRuntimePluginGenerator(
                    rustTemplate(
                        """
                        let mut cfg = #{Layer}::new(${codegenContext.serviceShape.id.name.dq()});

                        // TODO(enableNewSmithyRuntimeLaunch): Make it possible to set retry classifiers at the service level.
                        //     Retry classifiers can also be set at the operation level and those should be added to the
                        //     list of classifiers defined here, rather than replacing them.

                        #{additional_config}

                        Some(cfg.freeze())
                        """,
                        *codegenScope,
Loading