spin_factor_outbound_redis/
lib.rs1mod allowed_hosts;
2mod host;
3pub mod runtime_config;
4
5use host::InstanceState;
6use runtime_config::RuntimeConfig;
7use spin_factor_otel::OtelFactorState;
8use spin_factor_outbound_networking::{
9 ConnectionSemaphore, OutboundNetworkingFactor, build_connection_semaphore,
10};
11use spin_factors::{
12 ConfigureAppContext, Factor, FactorData, PrepareContext, RuntimeFactors, SelfInstanceBuilder,
13 anyhow,
14};
15use spin_world::spin::redis::redis as v3;
16
17use crate::allowed_hosts::AllowedHostChecker;
18
19#[derive(Default)]
21pub struct OutboundRedisFactor {
22 _priv: (),
23}
24
25impl OutboundRedisFactor {
26 pub fn new() -> Self {
27 Self::default()
28 }
29}
30
31pub struct AppState {
32 pub semaphore: ConnectionSemaphore,
34}
35
36impl Factor for OutboundRedisFactor {
37 type RuntimeConfig = RuntimeConfig;
38 type AppState = AppState;
39 type InstanceBuilder = InstanceState;
40
41 fn init(&mut self, ctx: &mut impl spin_factors::InitContext<Self>) -> anyhow::Result<()> {
42 ctx.link_bindings(spin_world::v1::redis::add_to_linker::<_, FactorData<Self>>)?;
43 ctx.link_bindings(spin_world::v2::redis::add_to_linker::<_, FactorData<Self>>)?;
44 ctx.link_bindings(v3::add_to_linker::<_, RedisFactorData>)?;
45 Ok(())
46 }
47
48 fn configure_app<T: RuntimeFactors>(
49 &self,
50 mut ctx: ConfigureAppContext<T, Self>,
51 ) -> anyhow::Result<Self::AppState> {
52 let config = ctx.take_runtime_config().unwrap_or_default();
53
54 Ok(AppState {
55 semaphore: build_connection_semaphore(
56 ctx.app_state::<OutboundNetworkingFactor>().ok(),
57 "redis",
58 config.max_connections,
59 config.wait_timeout,
60 ),
61 })
62 }
63
64 fn prepare<T: RuntimeFactors>(
65 &self,
66 mut ctx: PrepareContext<T, Self>,
67 ) -> anyhow::Result<Self::InstanceBuilder> {
68 let otel = OtelFactorState::from_prepare_context(&mut ctx)?;
69 let outbound_networking = ctx.instance_builder::<OutboundNetworkingFactor>()?;
70
71 Ok(InstanceState {
72 allowed_host_checker: AllowedHostChecker::new(outbound_networking.allowed_hosts()),
73 blocked_networks: outbound_networking.blocked_networks(),
74 connections: spin_resource_table::Table::new(1024),
75 semaphore: ctx.app_state().semaphore.clone(),
76 otel,
77 })
78 }
79}
80
81impl SelfInstanceBuilder for InstanceState {}
82
83pub struct RedisFactorData(OutboundRedisFactor);
84
85impl spin_core::wasmtime::component::HasData for RedisFactorData {
86 type Data<'a> = &'a mut InstanceState;
87}