Replies: 1 comment 2 replies
-
Interior mutability problem is indeed hard to crack for large states and, at this point, I'm not sure what the best approach could be. It might involve transparent message dispatch, but maybe something different. Whatever the solution will be, I think it's best to create a specialized crate extending the base functionality. |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi @krojew,
first of all, mad respect for building this framework.
I really like the idea to bring concepts from enterprise java/kotlin development to Rust and I think it can work really well at a large scale.
In the past, I had to build a few quite complex and large rust microservices.
It works, but it is not really that fun.
So it would be a blessing to be able to use sophisticated dependency injection and proper DDD etc. in Rust.
I've started playing around with springtime in the last few days, and I ran into a few hiccups.
So I thought I'd just make some proposals on how to solve them.
1. State Management:
For stateless services, which most rust microservices probably are, this is not really an issue. But for more complex ones, the state you would want to store in any component would have to have quite a few locks, depending on how fine you would want to control the access to it.
So for example one could of course do:
This would work for a small state, but if we start to make our state larger and more complex it gets annoying pretty quickly.
Then we have the option to either lock the whole state
or use for every field own locks.
But both of those variants are not really nice to use.
A while ago, I was fiddling around with my own version of DI in rust.
Its done very differently and didn't turn out to work as good as springtime.
But my idea to allow a more Spring-like workflow with stateful components in Rust was to implement smart proc macros that are able to hide rusts single mutability. I know that's a very dangerous topic, but hear me out:
If you take a look at this example you will find mutable functions that can be executed on immutable objects.
This works by converting a normal struct to a Wrapper that handles the async actor messaging.
The example will more or less compile to:
So one is able to do safely do this.
This requires every function call to become async, even if the function body does not require it, but I t think that's a pretty reasonable trade-off in comparison to being forced to guard everything first.
Also one could clone the handle and move it to other threads.
This is essentially the same thing that for example actix does, but hidden behind a proc macro, so not every single function call requires a manually written struct of parameters, return types and handler implementation.
If not implemented properly, circular actor calls could easily deadlock. So one would have to either detect that or work with some sort of reentrant locking mechanism. But it is possible to do safely and get an almost spring-like development workflow where you don't have to carefully manage mutability and still take advantages of rusts safe mutability model in the background.
There are a few downsides and it requires some quite complex and carefully crafted macros to properly handle all possible cases on how a function might look like, generics, const generics, lifetimes etc.. But I think it could be worth the effort and be a perfect extension for springtime.
2. Beans
Since springtime already has this auto-discovery feature, it would probably be an interesting idea to replicate springs bean model and not be forced to create Provider Components for every dynamic singleton configuration.
So something like this might be worth a try?
3. Assisted Factories
Only a small one, and it does not exist like this in Spring, but it matches the ecosystem quite well in my opinion.
The Problem:
If you want to create anything that is not just a singleton, you would have to construct the instance yourself with all its dependencies. I know this is a bit of a niche use-case but it can come in handy with very complex stateful applications.
Example:
it works, but its annoying to do, especially when the fields change, and it could look like this, which would create the same output with less boilerplate.
So yea what do you think?
Beta Was this translation helpful? Give feedback.
All reactions