I've to contain single-threaded (!Send + !Sync
) fields in my Backend
structure for tower-lsp. LanguageServer
forces my Backend
to implement these, so I am wondering whether there is anyway to make my single-threaded code to work. Perhaps I can use a thread_local!
or a lazy_static!
?
Or maybe there is some alternative crate?
are you implmeneting interior mutability somewhere, i.e. UnsafeCell
internally? any reason you don't use the thread safe wrapper type Arc<Mutex<...>>
?
1 Like
It happens that I have compiler_results: RefCell<Vec<(DepSeq, Rc<Database>)>>,
inside Backend
, and Rc<Database>
is used widely many times in my codebase. DepSeq
itself contains some Rc
as well, so it can't implement Send + Sync
.
Interior mutability definitely exists in my semantic model (using the smodel crate).
the tower_lsp::LanguageServer
trait uses Send + Sync
as super trait, so your backend must be thread safe. replace Rc<RefCell<T>>
with its thread safe counter part Arc<Mutex<T>>
(or Arc<RwLock<T>>
, if you need to distinguish shared borrow and exclusive borrow).
But I think it just won't work, as I'd have to change my entire codebase to use Arc
/RwLock
/Mutex
instead of Rc
/RefCell
/Cell
. I guess I'll explore to see if there are single-threaded crates instead of tower-lsp

I have found async-lsp: LanguageServer in async_lsp - Rust
Only the error has to implement Send
, apparently.
1 Like
looking at the documentation of async_lsp::LanguageServer
, it doesn't require Send
. I can only guess the Send
is required because you use tokio::spawn()
. try use spawn_local()
. this will force the task to be run on a single thread.
1 Like