Skip to content

Commit 6a67cef

Browse files
committed
Get things compiling
Signed-off-by: Ryan Levick <[email protected]>
1 parent c578fdd commit 6a67cef

File tree

7 files changed

+199
-121
lines changed

7 files changed

+199
-121
lines changed

Cargo.lock

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/trigger-http2/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use spin_http::{config::HttpTriggerConfig, routes::Router};
2525
use spin_trigger2::Trigger;
2626
use wasmtime_wasi_http::bindings::wasi::http::types::ErrorCode;
2727

28-
use server::HttpServer;
28+
pub use server::HttpServer;
2929

3030
pub use tls::TlsConfig;
3131

crates/trigger2/src/cli.rs

Lines changed: 145 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod launch_metadata;
22

3-
use std::path::PathBuf;
3+
use std::future::Future;
4+
use std::path::{Path, PathBuf};
45

56
use anyhow::{Context, Result};
67
use clap::{Args, IntoApp, Parser};
@@ -13,7 +14,7 @@ use spin_runtime_config::ResolvedRuntimeConfig;
1314

1415
use crate::factors::{TriggerFactors, TriggerFactorsRuntimeConfig};
1516
use crate::stdio::{FollowComponents, StdioLoggingExecutorHooks};
16-
use crate::Trigger;
17+
use crate::{Trigger, TriggerApp};
1718
pub use launch_metadata::LaunchMetadata;
1819

1920
pub const APP_LOG_DIR: &str = "APP_LOG_DIR";
@@ -172,43 +173,154 @@ impl<T: Trigger> FactorsTriggerCommand<T> {
172173
anyhow::bail!("This application requires the following features that are not available in this version of the '{}' trigger: {unmet}", T::TYPE);
173174
}
174175

175-
let mut trigger = T::new(self.trigger_args, &app)?;
176+
let trigger = T::new(self.trigger_args, &app)?;
177+
let mut builder = TriggerAppBuilder::new(trigger, PathBuf::from(working_dir));
178+
let config = builder.engine_config();
176179

177-
let mut core_engine_builder = {
178-
let mut config = spin_core::Config::default();
180+
// Apply --cache / --disable-cache
181+
if !self.disable_cache {
182+
config.enable_cache(&self.cache)?;
183+
}
179184

180-
// Apply --cache / --disable-cache
181-
if !self.disable_cache {
182-
config.enable_cache(&self.cache)?;
183-
}
185+
if self.disable_pooling {
186+
config.disable_pooling();
187+
}
184188

185-
if self.disable_pooling {
186-
config.disable_pooling();
189+
let run_fut = builder
190+
.run(
191+
app,
192+
TriggerAppOptions {
193+
runtime_config_file: self.runtime_config_file.as_deref(),
194+
state_dir: self.state_dir.as_deref(),
195+
initial_key_values: self.key_values,
196+
allow_transient_write: self.allow_transient_write,
197+
follow_components,
198+
log_dir: self.log,
199+
},
200+
)
201+
.await?;
202+
203+
let (abortable, abort_handle) = futures::future::abortable(run_fut);
204+
ctrlc::set_handler(move || abort_handle.abort())?;
205+
match abortable.await {
206+
Ok(Ok(())) => {
207+
tracing::info!("Trigger executor shut down: exiting");
208+
Ok(())
209+
}
210+
Ok(Err(err)) => {
211+
tracing::error!("Trigger executor failed");
212+
Err(err)
213+
}
214+
Err(_aborted) => {
215+
tracing::info!("User requested shutdown: exiting");
216+
Ok(())
187217
}
218+
}
219+
}
220+
221+
fn follow_components(&self) -> FollowComponents {
222+
if self.silence_component_logs {
223+
FollowComponents::None
224+
} else if self.follow_components.is_empty() {
225+
FollowComponents::All
226+
} else {
227+
let followed = self.follow_components.clone().into_iter().collect();
228+
FollowComponents::Named(followed)
229+
}
230+
}
231+
}
232+
233+
const SLOTH_WARNING_DELAY_MILLIS: u64 = 1250;
234+
235+
fn warn_if_wasm_build_slothful() -> sloth::SlothGuard {
236+
#[cfg(debug_assertions)]
237+
let message = "\
238+
This is a debug build - preparing Wasm modules might take a few seconds\n\
239+
If you're experiencing long startup times please switch to the release build";
240+
241+
#[cfg(not(debug_assertions))]
242+
let message = "Preparing Wasm modules is taking a few seconds...";
243+
244+
sloth::warn_if_slothful(SLOTH_WARNING_DELAY_MILLIS, format!("{message}\n"))
245+
}
246+
247+
fn help_heading<T: Trigger>() -> Option<&'static str> {
248+
if T::TYPE == help::HelpArgsOnlyTrigger::TYPE {
249+
Some("TRIGGER OPTIONS")
250+
} else {
251+
let heading = format!("{} TRIGGER OPTIONS", T::TYPE.to_uppercase());
252+
let as_str = Box::new(heading).leak();
253+
Some(as_str)
254+
}
255+
}
256+
257+
/// A builder for a [`TriggerApp`].
258+
pub struct TriggerAppBuilder<T> {
259+
engine_config: spin_core::Config,
260+
working_dir: PathBuf,
261+
pub trigger: T,
262+
}
188263

189-
trigger.update_core_config(&mut config)?;
264+
/// Options for building a [`TriggerApp`].
265+
#[derive(Default)]
266+
pub struct TriggerAppOptions<'a> {
267+
/// Path to the runtime config file.
268+
runtime_config_file: Option<&'a Path>,
269+
/// Path to the state directory.
270+
state_dir: Option<&'a str>,
271+
/// Initial key/value pairs to set in the app's default store.
272+
initial_key_values: Vec<(String, String)>,
273+
/// Whether to allow transient writes to mounted files
274+
allow_transient_write: bool,
275+
/// Which components should have their logs followed.
276+
follow_components: FollowComponents,
277+
/// Log directory for component stdout/stderr.
278+
log_dir: Option<PathBuf>,
279+
}
280+
281+
impl<T: Trigger> TriggerAppBuilder<T> {
282+
pub fn new(trigger: T, working_dir: PathBuf) -> Self {
283+
Self {
284+
engine_config: spin_core::Config::default(),
285+
working_dir,
286+
trigger,
287+
}
288+
}
289+
290+
pub fn engine_config(&mut self) -> &mut spin_core::Config {
291+
&mut self.engine_config
292+
}
190293

191-
spin_core::Engine::builder(&config)?
294+
/// Build a [`TriggerApp`] from the given [`App`] and options.
295+
pub async fn build(
296+
&mut self,
297+
app: App,
298+
options: TriggerAppOptions<'_>,
299+
) -> anyhow::Result<TriggerApp<T>> {
300+
let mut core_engine_builder = {
301+
self.trigger.update_core_config(&mut self.engine_config)?;
302+
303+
spin_core::Engine::builder(&self.engine_config)?
192304
};
193-
trigger.add_to_linker(core_engine_builder.linker())?;
305+
self.trigger.add_to_linker(core_engine_builder.linker())?;
194306

195-
let runtime_config = match &self.runtime_config_file {
307+
let runtime_config = match options.runtime_config_file {
196308
Some(runtime_config_path) => {
197309
ResolvedRuntimeConfig::<TriggerFactorsRuntimeConfig>::from_file(
198310
runtime_config_path,
199-
self.state_dir.as_deref(),
311+
options.state_dir,
200312
)?
201313
}
202-
None => ResolvedRuntimeConfig::default(self.state_dir.as_deref()),
314+
None => ResolvedRuntimeConfig::default(options.state_dir),
203315
};
204316

205317
runtime_config
206-
.set_initial_key_values(&self.key_values)
318+
.set_initial_key_values(&options.initial_key_values)
207319
.await?;
208320

209321
let factors = TriggerFactors::new(
210-
working_dir,
211-
self.allow_transient_write,
322+
self.working_dir.clone(),
323+
options.allow_transient_write,
212324
runtime_config.key_value_resolver,
213325
runtime_config.sqlite_resolver,
214326
);
@@ -249,8 +361,10 @@ impl<T: Trigger> FactorsTriggerCommand<T> {
249361

250362
let mut executor = FactorsExecutor::new(core_engine_builder, factors)?;
251363

252-
let log_dir = self.log.clone();
253-
executor.add_hooks(StdioLoggingExecutorHooks::new(follow_components, log_dir));
364+
executor.add_hooks(StdioLoggingExecutorHooks::new(
365+
options.follow_components,
366+
options.log_dir,
367+
));
254368
// TODO:
255369
// builder.hooks(SummariseRuntimeConfigHook::new(&self.runtime_config_file));
256370
// builder.hooks(KeyValuePersistenceMessageHook);
@@ -261,59 +375,17 @@ impl<T: Trigger> FactorsTriggerCommand<T> {
261375
executor.load_app(app, runtime_config.runtime_config, SimpleComponentLoader)?
262376
};
263377

264-
let run_fut = trigger.run(configured_app);
265-
266-
let (abortable, abort_handle) = futures::future::abortable(run_fut);
267-
ctrlc::set_handler(move || abort_handle.abort())?;
268-
match abortable.await {
269-
Ok(Ok(())) => {
270-
tracing::info!("Trigger executor shut down: exiting");
271-
Ok(())
272-
}
273-
Ok(Err(err)) => {
274-
tracing::error!("Trigger executor failed");
275-
Err(err)
276-
}
277-
Err(_aborted) => {
278-
tracing::info!("User requested shutdown: exiting");
279-
Ok(())
280-
}
281-
}
282-
}
283-
284-
fn follow_components(&self) -> FollowComponents {
285-
if self.silence_component_logs {
286-
FollowComponents::None
287-
} else if self.follow_components.is_empty() {
288-
FollowComponents::All
289-
} else {
290-
let followed = self.follow_components.clone().into_iter().collect();
291-
FollowComponents::Named(followed)
292-
}
378+
Ok(configured_app)
293379
}
294-
}
295-
296-
const SLOTH_WARNING_DELAY_MILLIS: u64 = 1250;
297-
298-
fn warn_if_wasm_build_slothful() -> sloth::SlothGuard {
299-
#[cfg(debug_assertions)]
300-
let message = "\
301-
This is a debug build - preparing Wasm modules might take a few seconds\n\
302-
If you're experiencing long startup times please switch to the release build";
303-
304-
#[cfg(not(debug_assertions))]
305-
let message = "Preparing Wasm modules is taking a few seconds...";
306-
307-
sloth::warn_if_slothful(SLOTH_WARNING_DELAY_MILLIS, format!("{message}\n"))
308-
}
309380

310-
fn help_heading<T: Trigger>() -> Option<&'static str> {
311-
if T::TYPE == help::HelpArgsOnlyTrigger::TYPE {
312-
Some("TRIGGER OPTIONS")
313-
} else {
314-
let heading = format!("{} TRIGGER OPTIONS", T::TYPE.to_uppercase());
315-
let as_str = Box::new(heading).leak();
316-
Some(as_str)
381+
/// Run the [`TriggerApp`] with the given [`App`] and options.
382+
pub async fn run(
383+
mut self,
384+
app: App,
385+
options: TriggerAppOptions<'_>,
386+
) -> anyhow::Result<impl Future<Output = anyhow::Result<()>>> {
387+
let configured_app = self.build(app, options).await?;
388+
Ok(self.trigger.run(configured_app))
317389
}
318390
}
319391

crates/trigger2/src/stdio.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ use tokio::io::AsyncWrite;
1212
use crate::factors::TriggerFactors;
1313

1414
/// Which components should have their logs followed on stdout/stderr.
15-
#[derive(Clone, Debug)]
15+
#[derive(Clone, Debug, Default)]
1616
pub enum FollowComponents {
17+
#[default]
1718
/// No components should have their logs followed.
1819
None,
1920
/// Only the specified components should have their logs followed.
@@ -33,12 +34,6 @@ impl FollowComponents {
3334
}
3435
}
3536

36-
impl Default for FollowComponents {
37-
fn default() -> Self {
38-
Self::None
39-
}
40-
}
41-
4237
/// Implements TriggerHooks, writing logs to a log file and (optionally) stderr
4338
pub struct StdioLoggingExecutorHooks {
4439
follow_components: FollowComponents,

tests/conformance-tests/src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use anyhow::Context as _;
2+
use test_environment::http::Request;
23
use testing_framework::runtimes::spin_cli::{SpinCli, SpinConfig};
34

45
/// Run a single conformance test against the supplied spin binary.
@@ -56,9 +57,11 @@ pub fn run_test(
5657
let conformance_tests::config::Invocation::Http(mut invocation) = invocation;
5758
invocation.request.substitute_from_env(&mut env)?;
5859
let spin = env.runtime_mut();
59-
let actual = invocation
60-
.request
61-
.send(|request| spin.make_http_request(request))?;
60+
let actual = invocation.request.send(|request| {
61+
let request =
62+
Request::full(request.method, request.path, request.headers, request.body);
63+
spin.make_http_request(request)
64+
})?;
6265

6366
conformance_tests::assertions::assert_response(&invocation.response, &actual)
6467
.with_context(|| {

tests/testing-framework/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ regex = "1.10.2"
1414
reqwest = { workspace = true }
1515
temp-dir = "0.1.11"
1616
test-environment = { workspace = true }
17-
spin-trigger-http = { path = "../../crates/trigger-http" }
17+
spin-factors-executor = { path = "../../crates/factors-executor" }
18+
spin-app = { path = "../../crates/app" }
19+
spin-trigger-http2 = { path = "../../crates/trigger-http2" }
1820
spin-http = { path = "../../crates/http" }
19-
spin-trigger = { path = "../../crates/trigger" }
21+
spin-trigger2 = { path = "../../crates/trigger2" }
2022
spin-loader = { path = "../../crates/loader" }
2123
toml = "0.8.6"
2224
tokio = "1.23"

0 commit comments

Comments
 (0)