How to handle Generic Data #256
-
Hello I'm facing a compile issue with this code, may be you have a solution ? :) I'm trying to create a generic worker registration. fn register_worker<T: Model + 'static>() {
// Create my model
let model = T::Model::new();
// Create the worker
let worker =
WorkerBuilder::new("worker")
.data(Arc::new(model)) // Add the model in shared state
.with_storage(product_storage)
.build_fn(handle_product_task::<T>); // Generic handler over the model
....
} The issue only occures with the line Here is the compile error
I tried replacing model by a simple u16 it works. Thanks a lot |
Beta Was this translation helpful? Give feedback.
Replies: 10 comments
-
Tower offers a method to check if the service is actually clone. From first look, I am curious if it's because you are missing Try these two and get back if they don't help. |
Beta Was this translation helpful? Give feedback.
-
Thanks for your help I still did not try [check_service_clone] (https://docs.rs/tower/latest/tower/struct.ServiceBuilder.html#method.check_service_clone), I need to figure out how to use it. I tried with ?Sized but it doesn't work. May be my traits are too constrained: Here is the full code : pub trait ModelGenerator: Product + Sized {
type Model: Model<Self, Err = Self::Err>;
type Err: Error + Into<AppError>;
fn model() -> Result<Self::Model, Self::Err> {
Self::Model::new()
}
}
pub trait Model<T: Product>: Sized {
type Err: Error + Into<AppError>;
fn new() -> Result<Self, Self::Err>;
fn version(&self) -> Result<String, Self::Err>;
...
}
fn register_worker<T: ModelGenerator + 'static>() {
// Create my model
let model = T::model().unwrap();
// Create the worker
let worker =
WorkerBuilder::new("worker")
.data(Arc::new(model)) // Add the model in shared state
.with_storage(product_storage)
.build_fn(handle_product_task::<T>); // Generic handler over the model
....
} |
Beta Was this translation helpful? Give feedback.
-
I also tried with less constrained traits (without Sized) but still got the same error: pub trait ModelGenerator: Product {
type Model: Model;
type Err: Error + Into<AppError>;
fn model() -> Result<Self::Model, Self::Err>;
}
pub trait Model {
type Product: Product;
type Err: Error + Into<AppError>;
fn version(&self) -> Result<String, Self::Err>;
fn process(
&self,
input: (
<Self::Product as Product>::ModelInput,
<Self::Product as Product>::RenderInput,
),
callback: ComposeCallback,
) -> Result<(<Self::Product as Product>::ModelOutput, String), Self::Err>;
} In fact you can recreate this issue with a simple trait: pub trait BasicTrait {}
fn register_worker<T: BasicTrait>(data: T) {
let worker =
WorkerBuilder::new("worker")
.data(Arc::new(data)) // Add the data in shared state
.with_storage(product_storage)
.build_fn(handle_product_task::<T>); // Generic handler over the model
} It's like generic cannot be mixed with data and worker builder |
Beta Was this translation helpful? Give feedback.
-
Can you try wrapping the Arc in a wrapper struct? |
Beta Was this translation helpful? Give feedback.
-
To test check clone, use the .chain(|svc| svc.check_svc(...)) |
Beta Was this translation helpful? Give feedback.
-
Amazing it's working, using I do understand why Sync is needed because Arc is Sync only if T is Sync. #[derive(Clone)]
MyStruct<T: Model> {
model: Arc<T> // It should not be mandatory for T to impl Clone
} |
Beta Was this translation helpful? Give feedback.
-
nevermind I found out that using impl<T: ModelFactory> Clone for Ctx<T>
{
fn clone(&self) -> Self {
Self {
model: self.model.clone(),
}
}
} It's working perfectly :) Thank again for all your help !!!! |
Beta Was this translation helpful? Give feedback.
-
Always happy to help. 🙂 |
Beta Was this translation helpful? Give feedback.
-
Hey @AzHicham, I have a bit of the same problem. I'm creating a system allowing Workers to be registered from a plugin system. And I'm a little stuck around Generic Data. Do you have any ideas for me? :) Thanks |
Beta Was this translation helpful? Give feedback.
-
Hello, sorry for the late reply |
Beta Was this translation helpful? Give feedback.
Tower offers a method to check if the service is actually clone.
https://docs.rs/tower/latest/tower/struct.ServiceBuilder.html#method.check_service_clone
From first look, I am curious if it's because you are missing
T: ?Sized
which is required by Arc to be clone.Try these two and get back if they don't help.