Skip to content
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

feat(resources): add support for turso client w/o provisioning #996

Merged
merged 14 commits into from
Jun 28, 2023

Conversation

Kazy
Copy link
Contributor

@Kazy Kazy commented Jun 12, 2023

Description of change

This adds support for Turso but without provisioning.

Close #986.

How has this been tested? (if applicable)

Locally yes, both with a local and a remote database.

TODO

  • Clarify the few XXX in the code.

@Kazy Kazy force-pushed the turso-integration branch from 0132f6b to ce916a5 Compare June 12, 2023 16:22
@Kazy Kazy marked this pull request as ready for review June 13, 2023 14:57
Copy link
Contributor

@iulianbarbu iulianbarbu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Kazy ! This looks on the right path. I would need to take a closer look at the tests and do a manual one also. Consider this part 1. :D

We'll be a bit low on bandwidth reviewing this during the next two weeks because we're planning for a bigger release and an off-site soon after. We'll try our best to provide meaningful feedback though in the meantime, so please shoot if you have other qs.


```rust
#[shuttle_runtime::main]
async fn app(#[shuttle_turso::Turso(addr="advanced-lightspeed.turso.io", auth_token=Some("token")] client: Client) -> __ { }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the token provided in plain?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was, and I've updated the code to read from the secrets instead.

resources/turso/src/lib.rs Outdated Show resolved Hide resolved
@Kazy Kazy requested a review from iulianbarbu June 20, 2023 16:07
Copy link
Contributor

@oddgrd oddgrd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @Kazy, this is really great! Apologies for the delayed review, but I'd say this is very nearly finished, I just have some suggestions for some small changes we could make. Thanks for adding tests and docs too ❤️

Comment on lines 3 to 13
version = "0.18.0"
edition = "2021"
license = "Apache-2.0"
description = "Plugin to obtain a client connected to a Turso database"
keywords = ["shuttle-service", "turso"]

[dependencies]
async-trait = "0.1.56"
libsql-client = { version = "0.27" }
serde = { version = "1.0.148", features = ["derive"] }
shuttle-service = { path = "../../service", version = "0.18.0", default-features = false }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some delayed-review version bumps 😄

Suggested change
version = "0.18.0"
edition = "2021"
license = "Apache-2.0"
description = "Plugin to obtain a client connected to a Turso database"
keywords = ["shuttle-service", "turso"]
[dependencies]
async-trait = "0.1.56"
libsql-client = { version = "0.27" }
serde = { version = "1.0.148", features = ["derive"] }
shuttle-service = { path = "../../service", version = "0.18.0", default-features = false }
version = "0.19.0"
edition = "2021"
license = "Apache-2.0"
description = "Plugin to obtain a client connected to a Turso database"
keywords = ["shuttle-service", "turso"]
[dependencies]
async-trait = "0.1.56"
libsql-client = { version = "0.27" }
serde = { version = "1.0.148", features = ["derive"] }
shuttle-service = { path = "../../service", version = "0.19.0", default-features = false }

use libsql_client::client::Client;

#[shuttle_runtime::main]
async fn app(#[shuttle_turso::Turso(addr="libsql://advanced-lightspeed.turso.io")] client: Client) -> __ { }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use secrets string interpolation here, see this section in the rds docs for an example. I think we should also add the token param to the example and interpolate it from secrets, and maybe also make that one required.

I'm also thinking we should use one of the frameworks for the example so it's clear that using turso resource doesn't change the return type, what do you think?

Suggested change
async fn app(#[shuttle_turso::Turso(addr="libsql://advanced-lightspeed.turso.io")] client: Client) -> __ { }
async fn app(#[shuttle_turso::Turso(addr="libsql://advanced-lightspeed.turso.io")] client: Client) -> ShuttleAxum { ... }

Copy link
Contributor

@oddgrd oddgrd Jun 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we don't need to use secrets interpolation for the address, since unlike an sql connection string it doesn't contain a password. But for the token I think it would be good

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I wasn't aware that we could interpolate it like that ! This is better than my solution that requires the user to use a Secret.toml file; one can just use a hardcoded token when playing with it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Pieter implemented it a while ago but we haven't really documented it very clearly. 😄 It's pretty cool!

Comment on lines 54 to 68
impl Turso {
async fn output_from_addr(
&self,
factory: &mut dyn Factory,
addr: &str,
) -> Result<<Turso as ResourceBuilder<Client>>::Output, shuttle_service::Error> {
match factory
.get_secrets()
.await
.expect("secrets should be available")
.get(&self.token_secret)
{
Some(token) => Ok(TursoOutput {
conn_url: Url::parse(addr).map_err(Error::UrlParseError)?,
token: Some(token.to_string()),
}),
None => Err(ShuttleError::Custom(CustomError::msg(format!(
"could't find secret {}",
self.token_secret
)))),
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking maybe we can replace this with the secrets string interpolation?

Comment on lines 7 to 10
**IMPORTANT**: Currently Shuttle isn't able to provision a database for you (yet). This means you will have to create an account on their [website](https://turso.tech/) and follow the few steps required to create a database and create a token to access it.

Add `shuttle-turso` to the dependencies for your service.
This resource will be provided by adding the `shuttle_turso::Turso` attribute to your Shuttle `main` decorated function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent docs, thank you! Perhaps we can suggest to cargo add shuttle-turso?

@Kazy Kazy force-pushed the turso-integration branch from 7b57599 to df0da6c Compare June 23, 2023 13:51
@Kazy
Copy link
Contributor Author

Kazy commented Jun 23, 2023

Sorry for the forced push. I missed that you updated the fork and ended up with some unwanted commits, and I preferred to have a clean state :)

@Kazy Kazy requested a review from oddgrd June 23, 2023 13:55
Copy link
Contributor

@oddgrd oddgrd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, thank you @Kazy! I left a couple of comments but they are just nits 😄

Comment on lines 78 to 82
Self {
addr: "".to_string(),
token: "".to_string(),
local_addr: None,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we derive Default for the Turso struct, we can do this:

Suggested change
Self {
addr: "".to_string(),
token: "".to_string(),
local_addr: None,
}
Self::default()

Comment on lines 21 to 22
use libsql_client::client::Client;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
use libsql_client::client::Client;
use libsql_client::client::Client;
use shuttle_axum::ShuttleAxum;

resources/turso/Cargo.toml Outdated Show resolved Hide resolved
resources/turso/Cargo.toml Outdated Show resolved Hide resolved
@oddgrd oddgrd merged commit 4ea9883 into shuttle-hq:main Jun 28, 2023
AlphaKeks pushed a commit to AlphaKeks/shuttle that referenced this pull request Jul 21, 2023
…le-hq#996)

* feat(resources): add support for turso client w/o provisioning

* chore(resources/turso): remove todo about checking for local db file

* test(resources/turso): add test

* build: add missing shuttle-turso override of cargo path

* ci: add shuttle-turso to the test matrix

* ref: unnecessary borrow in ResourceBuilder config

* ref(resources/turso): read secrets from Secrets.toml, support token in local

* fix(resources/turso): please clippy

* build(resources/turso): bump versions

* ref(resources/turso): rely on secret interpolation for token, update README

* ref(resources/turso): use default for Turso, add missing import in README

* chore: upgrade and lock libsql version

* chore: v0.20.0

* chore: v0.20.0

---------

Co-authored-by: oddgrd <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature]: Add support for Turso
4 participants