Giter Club home page Giter Club logo

Comments (9)

czocher avatar czocher commented on June 1, 2024 1

@maxcountryman you're correct, it does not support async and is not multithread-safe. In reality sqlite is never async nor multithread-safe. AFAIK it needs to be kept behind a Mutex. Sqlx and other async database access libraries either do that or employ some kind of message passing approach.

I was thinking on using tokio-rusqlite to overcome this problem.

from axum-login.

czocher avatar czocher commented on June 1, 2024 1

This is an async_trait @rgwood. You should implement it as described in the example of: https://crates.io/crates/async-trait.

Additionally the error type you mentioned can be easily created from any existing type implementing the std::error::Error trait with the help of wrap_err.

from axum-login.

maxcountryman avatar maxcountryman commented on June 1, 2024

It looks neat but correct me if I'm wrong: it doesn't support async currently, right?

from axum-login.

rgwood avatar rgwood commented on June 1, 2024

I tried to use axum-login in a project that uses rusqlite today. Initially it seemed pretty straightforward, but implementingUserStore was harder than expected:

#[derive(Clone, Debug, PartialEq)]
pub struct UserRepository {
    conn: ConnectionPool,
}

impl UserStore<i64, Role> for UserRepository {
    // nearly everything in this impl was generated by the "Implement missing members" Quick Fix in rust-analyzer
    #[doc = " An associated user type which will be loaded from the store."]
    type User = User;

    #[doc = " Load and return a user."]
    #[doc = ""]
    #[doc = " This provides a generic interface for loading a user from some store."]
    #[doc = " For example, this might be a database or cache. It\'s assumed that a"]
    #[doc = " unique, stable identifier of the user is available. See [`AuthUser`]"]
    #[doc = " for expected minimal interface of the user type itself."]
    #[must_use]
    #[must_use]
    #[allow(clippy::type_complexity,clippy::type_repetition_in_bounds)]
    fn load_user<'life0,'life1,'async_trait>(&'life0 self,user_id: &'life1 i64) ->  ::core::pin::Pin<Box<dyn ::core::future::Future<Output = Result<Option<Self::User> > > + ::core::marker::Send+'async_trait> >where 'life0:'async_trait,'life1:'async_trait,Self:'async_trait {
        todo!()
    }
}

The lifetimes are impenetrable and it seems like load_user needs to return a Result<T, E> where E is an error type from a library I've never used before. I gave up after 5-10 minutes of digging into that.

(apologies, I know I should have kept trying to figure this out)

from axum-login.

czocher avatar czocher commented on June 1, 2024

@rgwood if you provide a work-in-progress PR I can have a look and maybe help you with the details.

from axum-login.

rgwood avatar rgwood commented on June 1, 2024

Thank you for the help and offer! I ended up implementing it like this:

#[derive(Clone)]
pub struct SqliteUserStore {}

// uggggggh async is the worst
#[async_trait]
impl UserStore<i64, Role> for SqliteUserStore {
    type User = User;

    async fn load_user(
        &self,
        user_id: &i64,
    ) -> std::result::Result<Option<Self::User>, eyre::Report> {
        let conn = get_conn_from_pool()
            .map_err(|e| eyre::eyre!("could not get db connection: {}", e))?;
        let user = get_user(&conn, *user_id)
            .map_err(|e| eyre::eyre!("could not get user: {}", e))?;
        Ok(user)
    } 
}

I figure that reading from my small local SQLite DB is fast enough that a blocking read is OK here. 🤞

from axum-login.

czocher avatar czocher commented on June 1, 2024

@maxcountryman @rgwood I'll try to provide a PR with an async version as soon as I overcome some dependency related issues.

The current problems I'm facing:

  • The UserId parameter is provided as a reference which needs to be shared between threads. Not sure how to do it yet.
  • rusqlite conflicts with sqlx, since they both link to the C sqlite library. Both features are not additive, which is a problem overall, but I don't think we can do anything about it.

Any help/ideas are welcomed.

WIP branch I'm working on: https://github.com/czocher/axum-login/blob/rusqlite/axum-login/src/rusqlite_store.rs

from axum-login.

czocher avatar czocher commented on June 1, 2024

@rgwood the implementation is finalized, you can probably copy the solution for an async version if you'd like.

from axum-login.

maxcountryman avatar maxcountryman commented on June 1, 2024

I believe we can close this now that we no longer bundle user stores.

from axum-login.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.