spin_runtime_factors/
build.rs

1use std::path::PathBuf;
2
3use super::{TriggerAppArgs, TriggerFactors, TriggerFactorsRuntimeConfig};
4
5use anyhow::Context as _;
6use spin_factors_executor::FactorsExecutor;
7use spin_runtime_config::ResolvedRuntimeConfig;
8use spin_trigger::cli::{
9    FactorsConfig, InitialKvSetterHook, KeyValueDefaultStoreSummaryHook, MaxInstanceMemoryHook,
10    RuntimeFactorsBuilder, SqlStatementExecutorHook, SqliteDefaultStoreSummaryHook,
11    StdioLoggingExecutorHooks,
12};
13use spin_variables_static::StaticVariablesProvider;
14
15/// A [`RuntimeFactorsBuilder`] for [`TriggerFactors`].
16pub struct FactorsBuilder;
17
18impl RuntimeFactorsBuilder for FactorsBuilder {
19    type CliArgs = TriggerAppArgs;
20    type Factors = TriggerFactors;
21    type RuntimeConfig = ResolvedRuntimeConfig<TriggerFactorsRuntimeConfig>;
22
23    fn build(
24        config: &FactorsConfig,
25        args: &Self::CliArgs,
26    ) -> anyhow::Result<(Self::Factors, Self::RuntimeConfig)> {
27        let mut runtime_config = ResolvedRuntimeConfig::<TriggerFactorsRuntimeConfig>::from_file(
28            config.runtime_config_file.clone().as_deref(),
29            config.local_app_dir.clone().map(PathBuf::from),
30            config.state_dir.clone(),
31            config.log_dir.clone(),
32        )?;
33
34        let cli_static_variables = args.get_variables()?.clone();
35        let cli_static_variables_provider = StaticVariablesProvider::new(cli_static_variables);
36
37        // Insert the parsed static variables provided via cli arguments
38        // into the set of variable providers with highest precedence.
39        runtime_config
40            .runtime_config
41            .variables
42            .as_mut()
43            .unwrap()
44            .providers
45            .insert(0, Box::new(cli_static_variables_provider));
46
47        runtime_config.summarize(config.runtime_config_file.as_deref());
48
49        let factors = TriggerFactors::new(
50            runtime_config.state_dir(),
51            config.working_dir.clone(),
52            args.allow_transient_write,
53        )
54        .context("failed to create factors")?;
55        Ok((factors, runtime_config))
56    }
57
58    fn configure_app<U: Send + 'static>(
59        executor: &mut FactorsExecutor<Self::Factors, U>,
60        runtime_config: &Self::RuntimeConfig,
61        config: &FactorsConfig,
62        args: &Self::CliArgs,
63    ) -> anyhow::Result<()> {
64        executor.add_hooks(StdioLoggingExecutorHooks::new(
65            config.follow_components.clone(),
66            runtime_config.log_dir(),
67            config.truncate_logs,
68        ));
69        executor.add_hooks(SqlStatementExecutorHook::new(
70            args.sqlite_statements.clone(),
71        ));
72        executor.add_hooks(InitialKvSetterHook::new(args.key_values.clone()));
73        executor.add_hooks(SqliteDefaultStoreSummaryHook);
74        executor.add_hooks(KeyValueDefaultStoreSummaryHook);
75
76        let max_instance_memory = args
77            .max_instance_memory
78            .or(runtime_config.max_instance_memory());
79
80        // Only add the hook if a max instance memory size is specified via flag or runtime config.
81        if let Some(max_instance_memory) = max_instance_memory {
82            executor.add_hooks(MaxInstanceMemoryHook::new(max_instance_memory));
83        }
84
85        Ok(())
86    }
87}