Skip to content

Commit bfd3680

Browse files
committed
Allow dynamic querying of instance builders
Signed-off-by: Ryan Levick <ryan.levick@fermyon.com>
1 parent 4753301 commit bfd3680

File tree

15 files changed

+154
-339
lines changed

15 files changed

+154
-339
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/factors-derive/src/lib.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ fn expand_factors(input: &DeriveInput) -> syn::Result<TokenStream> {
211211
)*
212212
}
213213

214-
#[allow(dead_code)]
215214
impl #builders_name {
216215
#(
217216
pub fn #factor_names(&mut self) -> &mut <#factor_types as #Factor>::InstanceBuilder {
@@ -220,6 +219,23 @@ fn expand_factors(input: &DeriveInput) -> syn::Result<TokenStream> {
220219
)*
221220
}
222221

222+
impl #factors_path::HasInstanceBuilder for #builders_name {
223+
fn for_factor<F: #Factor>(
224+
&mut self
225+
) -> Option<&mut F::InstanceBuilder> {
226+
let type_id = #TypeId::of::<F::InstanceBuilder>();
227+
#(
228+
if type_id == #TypeId::of::<<#factor_types as #Factor>::InstanceBuilder>() {
229+
let builder = self.#factor_names.as_mut().unwrap();
230+
return Some(
231+
<dyn #Any>::downcast_mut(builder).unwrap()
232+
);
233+
}
234+
)*
235+
None
236+
}
237+
}
238+
223239
#vis struct #state_name {
224240
__table: #ResourceTable,
225241
#(

crates/factors/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ pub use crate::{
1414
factor::{ConfigureAppContext, ConfiguredApp, Factor, FactorInstanceState, InitContext},
1515
prepare::{FactorInstanceBuilder, InstanceBuilders, PrepareContext, SelfInstanceBuilder},
1616
runtime_config::{FactorRuntimeConfigSource, RuntimeConfigSourceFinalizer},
17-
runtime_factors::{AsInstanceState, RuntimeFactors, RuntimeFactorsInstanceState},
17+
runtime_factors::{
18+
AsInstanceState, HasInstanceBuilder, RuntimeFactors, RuntimeFactorsInstanceState,
19+
},
1820
};
1921

2022
/// Result wrapper type defaulting to use [`Error`].

crates/factors/src/runtime_factors.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub trait RuntimeFactors: Send + Sync + Sized + 'static {
3636
/// The per instance state of the factors.
3737
type InstanceState: RuntimeFactorsInstanceState;
3838
/// The collection of all the `InstanceBuilder`s of the factors.
39-
type InstanceBuilders: Send;
39+
type InstanceBuilders: Send + HasInstanceBuilder;
4040
/// The runtime configuration of all the factors.
4141
type RuntimeConfig: Default;
4242

@@ -81,6 +81,10 @@ pub trait RuntimeFactors: Send + Sync + Sized + 'static {
8181
) -> Option<Option<&mut F::InstanceBuilder>>;
8282
}
8383

84+
pub trait HasInstanceBuilder {
85+
fn for_factor<F: Factor>(&mut self) -> Option<&mut F::InstanceBuilder>;
86+
}
87+
8488
/// Get the state of a particular Factor from the overall InstanceState
8589
///
8690
/// Implemented by `#[derive(RuntimeFactors)]`

crates/trigger-http/src/server.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use hyper::{
1313
};
1414
use hyper_util::rt::TokioIo;
1515
use spin_app::{APP_DESCRIPTION_KEY, APP_NAME_KEY};
16-
use spin_factor_outbound_http::SelfRequestOrigin;
17-
use spin_factors::RuntimeFactors;
16+
use spin_factor_outbound_http::{OutboundHttpFactor, SelfRequestOrigin};
17+
use spin_factors::{HasInstanceBuilder, RuntimeFactors};
1818
use spin_http::{
1919
app_info::AppInfo,
2020
body,
@@ -236,11 +236,14 @@ impl<F: RuntimeFactors> HttpServer<F> {
236236
let mut instance_builder = self.trigger_app.prepare(component_id)?;
237237

238238
// Set up outbound HTTP request origin and service chaining
239-
// TODO: bring back once outbound networking is refactored
240-
// let outbound_http = instance_builder.factor_builders().outbound_http();
241-
// let origin = SelfRequestOrigin::create(server_scheme, &self.listen_addr)?;
242-
// outbound_http.set_self_request_origin(origin);
243-
// outbound_http.set_request_interceptor(OutboundHttpInterceptor::new(self.clone()))?;
239+
if let Some(outbound_http) = instance_builder
240+
.factor_builders()
241+
.for_factor::<OutboundHttpFactor>()
242+
{
243+
let origin = SelfRequestOrigin::create(server_scheme, &self.listen_addr)?;
244+
outbound_http.set_self_request_origin(origin);
245+
outbound_http.set_request_interceptor(OutboundHttpInterceptor::new(self.clone()))?;
246+
}
244247

245248
// Prepare HTTP executor
246249
let trigger_config = self.component_trigger_configs.get(component_id).unwrap();

crates/trigger-http/src/wagi.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use std::{io::Cursor, net::SocketAddr};
33
use anyhow::{ensure, Result};
44
use http_body_util::BodyExt;
55
use hyper::{Request, Response};
6-
use spin_factors::RuntimeFactors;
6+
use spin_factor_wasi::WasiFactor;
7+
use spin_factors::{HasInstanceBuilder, RuntimeFactors};
78
use spin_http::{config::WagiTriggerConfig, routes::RouteMatch, wagi};
89
use tracing::{instrument, Level};
910
use wasmtime_wasi::pipe::MemoryOutputPipe;
@@ -74,14 +75,16 @@ impl HttpExecutor for WagiHttpExecutor {
7475

7576
let stdout = MemoryOutputPipe::new(usize::MAX);
7677

77-
// TODO:
78-
// let wasi_builder = instance_builder.factor_builders().wasi();
79-
80-
// // Set up Wagi environment
81-
// wasi_builder.args(argv.split(' '));
82-
// wasi_builder.env(headers);
83-
// wasi_builder.stdin_pipe(Cursor::new(body));
84-
// wasi_builder.stdout(stdout.clone());
78+
if let Some(wasi_builder) = instance_builder
79+
.factor_builders()
80+
.for_factor::<WasiFactor>()
81+
{
82+
// // Set up Wagi environment
83+
wasi_builder.args(argv.split(' '));
84+
wasi_builder.env(headers);
85+
wasi_builder.stdin_pipe(Cursor::new(body));
86+
wasi_builder.stdout(stdout.clone());
87+
}
8588

8689
let (instance, mut store) = instance_builder.instantiate(()).await?;
8790

crates/trigger/src/cli.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,6 @@ pub struct FactorsTriggerCommand<T: Trigger<B::Factors>, B: RuntimeFactorsBuilde
9090
)]
9191
pub silence_component_logs: bool,
9292

93-
/// Set the static assets of the components in the temporary directory as writable.
94-
#[clap(long = "allow-transient-write")]
95-
pub allow_transient_write: bool,
96-
9793
/// Configuration file for config providers and wasmtime config.
9894
#[clap(
9995
name = RUNTIME_CONFIG_FILE,
@@ -125,7 +121,7 @@ pub struct FactorsTriggerCommand<T: Trigger<B::Factors>, B: RuntimeFactorsBuilde
125121
}
126122

127123
/// Configuration options that are common to all triggers.
128-
#[derive(Debug)]
124+
#[derive(Debug, Default)]
129125
pub struct CommonTriggerOptions {
130126
/// The Spin working directory.
131127
pub working_dir: PathBuf,
@@ -135,8 +131,6 @@ pub struct CommonTriggerOptions {
135131
pub state_dir: UserProvidedPath,
136132
/// Path to the local app directory.
137133
pub local_app_dir: Option<String>,
138-
/// Whether to allow transient writes to mounted files
139-
pub allow_transient_write: bool,
140134
/// Which components should have their logs followed.
141135
pub follow_components: FollowComponents,
142136
/// Log directory for component stdout/stderr.
@@ -220,7 +214,6 @@ impl<T: Trigger<B::Factors>, B: RuntimeFactorsBuilder> FactorsTriggerCommand<T,
220214
runtime_config_file: self.runtime_config_file.clone(),
221215
state_dir,
222216
local_app_dir: local_app_dir.clone(),
223-
allow_transient_write: self.allow_transient_write,
224217
follow_components,
225218
log_dir,
226219
};
@@ -281,18 +274,18 @@ fn help_heading<T: Trigger<F>, F: RuntimeFactors>() -> Option<&'static str> {
281274
}
282275

283276
/// A builder for a [`TriggerApp`].
284-
pub struct TriggerAppBuilder<T, F> {
277+
pub struct TriggerAppBuilder<T, B> {
285278
engine_config: spin_core::Config,
286279
pub trigger: T,
287-
_factors: std::marker::PhantomData<F>,
280+
_factors_builder: std::marker::PhantomData<B>,
288281
}
289282

290283
impl<T: Trigger<B::Factors>, B: RuntimeFactorsBuilder> TriggerAppBuilder<T, B> {
291284
pub fn new(trigger: T) -> Self {
292285
Self {
293286
engine_config: spin_core::Config::default(),
294287
trigger,
295-
_factors: Default::default(),
288+
_factors_builder: Default::default(),
296289
}
297290
}
298291

@@ -400,16 +393,19 @@ impl<T: Trigger<B::Factors>, B: RuntimeFactorsBuilder> TriggerAppBuilder<T, B> {
400393
}
401394
}
402395

396+
/// A builder for runtime factors.
403397
pub trait RuntimeFactorsBuilder {
404398
type Options: clap::Args;
405399
type Factors: RuntimeFactors;
406400
type RuntimeConfig: Into<<Self::Factors as RuntimeFactors>::RuntimeConfig>;
407401

402+
/// Build the factors and runtime config from the given options.
408403
fn build(
409404
common_options: &CommonTriggerOptions,
410405
options: &Self::Options,
411406
) -> anyhow::Result<(Self::Factors, Self::RuntimeConfig)>;
412407

408+
/// Configure the factors in the executor.
413409
fn configure_app<U: Send + 'static>(
414410
executor: &mut FactorsExecutor<Self::Factors, U>,
415411
runtime_config: &Self::RuntimeConfig,
@@ -444,11 +440,12 @@ pub mod help {
444440
}
445441

446442
/// A user provided option which be either be provided, default, or explicitly none.
447-
#[derive(Clone, Debug)]
443+
#[derive(Clone, Debug, Default)]
448444
pub enum UserProvidedPath {
449445
/// Use the explicitly provided directory.
450446
Provided(PathBuf),
451447
/// Use the default.
448+
#[default]
452449
Default,
453450
/// Explicitly unset.
454451
Unset,

0 commit comments

Comments
 (0)