-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement wasi-config #2869
base: main
Are you sure you want to change the base?
Implement wasi-config #2869
Conversation
@@ -31,6 +31,7 @@ impl Factor for VariablesFactor { | |||
fn init<T: Send + 'static>(&mut self, mut ctx: InitContext<T, Self>) -> anyhow::Result<()> { | |||
ctx.link_bindings(spin_world::v1::config::add_to_linker)?; | |||
ctx.link_bindings(spin_world::v2::variables::add_to_linker)?; | |||
ctx.link_bindings(spin_world::wasi::config::store::add_to_linker)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'll want to consider whether we want to make this configurable for users of the factor - i.e., do we want to force all runtimes that use the VariablesFactor
to link all three interfaces? We could instead make this linking conditional based on some configuration provided when the factor is constructed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Crate feature flag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the feature is light-weight enough that we could just do a dynamic check instead of a compile time feature flag, but I don't feel strongly either way.
]; | ||
ensure_matches!(get_all(), Ok(val) if val == expected_all); | ||
|
||
ensure_matches!(get("invalid-name"), Err(Error::Io(_))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does wasi-config
actually say anything about how keys are supposed to be formed? Is it possible that some code that targets wasi-config
and runs properly on other runtimes would error on Spin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it doesn't: https://github.com/WebAssembly/wasi-runtime-config/blob/f4d699bc6dd77adad99fa1a2246d482225ec6485/wit/store.wit#L17
This is a good call out of how it should probably be opinionated about string fmt or support invalid-name
error
@@ -0,0 +1,8 @@ | |||
# Variables |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should consider adding a conformance test for this. The runtime tests here are meant to be Spin CLI specific but this test seems like it should be applied to all Spin compliant runtimes.
@@ -52,6 +52,21 @@ impl ProviderResolver { | |||
self.resolve_template(template).await | |||
} | |||
|
|||
pub async fn resolve_all(&self, component_id: &str) -> Result<Vec<(String, String)>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: doc comment.
.map(|r| r.map(|value| (key.to_string(), value))) | ||
}); | ||
|
||
futures::future::try_join_all(resolve_futs).await |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am slightly worried about performance - at some point we might want to see if adding some sort of caching mechanism to providers is worth it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably push this down into the provider as e.g. (untested):
trait Provider {
async fn get(&self, key: &Key) -> anyhow::Result<Option<String>>;
async fn get_many(&self, keys: impl IntoIterator<Item = &Key>) -> anyhow::Result<impl IntoIterator<Option<String>>> {
try_join_all(keys.into_iter().map(|key| self.get(key)).await
}
}
match <Self as variables::Host>::get(self, key).await { | ||
Ok(value) => Ok(Some(value)), | ||
// Err(e) if matches!(e, variables::Error::Undefined(_)) => Ok(Ok(None)), | ||
Err(e) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW you could:
Err(variables::Error::Undefined(_)) => Ok(None)
crates/factor-variables/src/host.rs
Outdated
variables::Error::Undefined(msg) => spin_world::wasi::config::store::Error::Io(msg), // TODO: this should presumably not occur here | ||
variables::Error::InvalidName(msg) => { | ||
spin_world::wasi::config::store::Error::Io(msg) | ||
} // TODO: this doesn't feel ideal, but wasi-config only allows two error cases |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding 2, it felt like we have some errors that don't map nicely to the proposal. I ended up using the io error variant for anything that wasn't a provider error, which feels potentially misleading.
@itowlson referencing your PR comment and this comment inline, I talked to @thomastaylor312 and InvalidName
seems like a good example of an error message we'd want to update WASI config to use as it is a fairly universal case
crates/factor-variables/src/host.rs
Outdated
variables::Error::Provider(msg) => { | ||
spin_world::wasi::config::store::Error::Upstream(msg) | ||
} | ||
variables::Error::Other(msg) => spin_world::wasi::config::store::Error::Io(msg), // TODO: again, hard to know how to map this (and the original expressions::Error is not more helpful) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WASI config does seem to define IO errors as everything else. Is the concern you are raising is that we are labeling this "other" error as related to IO when it might not be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kate-goldenring Yes, that's exactly my worry. I appreciate that ""other" is a kind of unhelpful bucket though...!
]; | ||
ensure_matches!(get_all(), Ok(val) if val == expected_all); | ||
|
||
ensure_matches!(get("invalid-name"), Err(Error::Io(_))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it doesn't: https://github.com/WebAssembly/wasi-runtime-config/blob/f4d699bc6dd77adad99fa1a2246d482225ec6485/wit/store.wit#L17
This is a good call out of how it should probably be opinionated about string fmt or support invalid-name
error
@kate-goldenring re #2869 (comment) can you clarify "no it doesn't" please? I didn't follow how the linked WIT comment applied - are you thinking of this as "we can't possibly find a key for an invalid name so should return |
@itowlson I was aiming to point out that this is a weak spot of the WASI config interface and that we should propose updating it to either (A) be opinionated about string formatting or (B) support and invalid key error. My preference is that latter; however, the former would help achieve @rylev's point of enabling more portability across host implementatations. |
Signed-off-by: itowlson <ivan.towlson@fermyon.com>
Fixes #2868.
This has the same considerations as our wasi-observe and wasi-keyvalue implementations in terms of versioning the Spin worlds - I mashed it into the existing Spin 2 worlds for development and testing but know that is not sustainable. (At this point, I'm assuming all this lot will be punted into a new Spin 3 world.)
I'm publishing this mostly to:
(Regarding 2, it felt like we have some errors that don't map nicely to the proposal. I ended up using the
io
error variant for anything that wasn't a provider error, which feels potentially misleading. @kate-goldenring I'd value your thoughts on this!)