You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am trying to use session object with Redis as the storage in a distributed system with async-graphql to set and delete session for userid but having issues with that because actix-session does not implement Send and cannot be moved across threads. It has type: Rc<RefCell<actix_session::SessionInner>>. async-graphql requires that it has a Send trait.
Full compiler error message:
`Rc<RefCell<actix_session::session::SessionInner>>` cannot be sent between threads safely
within `actix_session::Session`, the trait `std::marker::Send` is not implemented for `Rc<RefCell<actix_session::session::SessionInner>>`rustc[E0277](https://doc.rust-lang.org/error-index.html#E0277)
graphql.rs(74,23): required by a bound introduced by this call
lib.rs(1,1): required because it appears within the type `actix_session::Session`
request.rs(91,26): required by a bound in `Request::data`
`Rc<RefCell<actix_session::session::SessionInner>>` cannot be shared between threads safely
within `actix_session::Session`, the trait `Sync` is not implemented for `Rc<RefCell<actix_session::session::SessionInner>>`rustc[E0277](https://doc.rust-lang.org/error-index.html#E0277)
graphql.rs(74,23): required by a bound introduced by this call
lib.rs(1,1): required because it appears within the type `actix_session::Session`
Question
Is there a possibility to make Session sendable?
#[post("/graphql")]pubasyncfnindex(schema: web::Data<MyGraphQLSchema>,req:HttpRequest,gql_request:GraphQLRequest,) -> GraphQLResponse{letmut request = gql_request.into_inner();let session = req.get_session();// ---> This is required to have `Send` marker
request = request.data(session);
schema.execute(request).await.into()}
Present work around:
use std::ops::Deref;use actix_session::Session;use send_wrapper::SendWrapper;use uuid::Uuid;use wither::bson::oid::ObjectId;#[derive(Clone,Debug)]structShared<T>(pubOption<SendWrapper<T>>);impl<T>Shared<T>{pubfnnew(v:T) -> Self{Self(Some(SendWrapper::new(v)))}}impl<T>DerefforShared<T>{typeTarget = T;fnderef(&self) -> &Self::Target{&*self.0.as_deref().unwrap()}}typeSessionShared = Shared<actix_session::Session>;#[derive(Debug, thiserror::Error)]pubenumTypedSessionError{#[error("Failed to parse data")]ParsingFailure(#[from] serde_json::Error),#[error(transparent)]Unknown(#[from] anyhow::Error),// source and Display delegate to anyhow::Error}typeTypedSessionResult<T> = Result<T,TypedSessionError>;/*This is somewhat like a hack: https://github.com/async-graphql/async-graphql/issues/426Session is Session(Rc<RefCell<SessionInner>>) and probably okay to useSendWrapper for now but having it implement Send would allowusing Arc/Mutex*/pubstructTypedSession(SessionShared);implTypedSession{constUSER_ID_KEY:&'static str = "user_id";pubfnnew(session:Session) -> Self{Self(Shared::new(session))}pubfnrenew(&self){self.0.renew();}pubfninsert_user_uuid(&self,user_id:Uuid) -> TypedSessionResult<()>{self.0.insert(Self::USER_ID_KEY, user_id)?;Ok(())}pubfnget_user_uuid(&self) -> TypedSessionResult<Option<Uuid>>{Ok(self.0.get::<Uuid>(Self::USER_ID_KEY)?)}pubfnclear(&self){self.0.clear()}}
Pitfall to the workaround
The workaround uses a hack by Wrapping it in a SendWrapper. However, this is intended for when one is sure one is operating in a single-threaded context. However, this isn't the case for actix. So, I am considering this as a short-term solution
Also, curious why this isn't a common issue and why RefCell was used in the first place as Session type🤔
The text was updated successfully, but these errors were encountered:
robjtede
changed the title
std::marker::Send is not implemented for Rc<RefCell<actix_session::session::SessionInner>>std::marker::Send is not implemented for `Rc<RefCell<actix_session::session::SessionInner>>
May 30, 2022
robjtede
changed the title
std::marker::Send is not implemented for `Rc<RefCell<actix_session::session::SessionInner>>std::marker::Send is not implemented for Rc<RefCell<actix_session::session::SessionInner>>May 30, 2022
Thanks for this wonderful library!
Issue
I am trying to use session object with
Redis
as the storage in a distributed system withasync-graphql
to set and delete session foruserid
but having issues with that becauseactix-session
does not implementSend
and cannot be moved across threads. It has type:Rc<RefCell<actix_session::SessionInner>>
.async-graphql
requires that it has aSend
trait.Full compiler error message:
Question
Session
sendable?Present work around:
Pitfall to the workaround
The workaround uses a hack by Wrapping it in a
SendWrapper
. However, this is intended for when one is sure one is operating in a single-threaded context. However, this isn't the case foractix
. So, I am considering this as a short-term solutionAlso, curious why this isn't a common issue and why
RefCell
was used in the first place asSession
type🤔The text was updated successfully, but these errors were encountered: