Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: Device manager #2

Merged
merged 5 commits into from
Jul 18, 2024

Conversation

RaulTrombin
Copy link
Member

@RaulTrombin RaulTrombin commented Jun 4, 2024

This PR adds DeviceManager and Device modules, each following the actor pattern.
Each structure has its own handler, allowing usage across multiple and different threads.

Device requests made to the Manager are forwarded directly to the respective Device. Each request provides a Result<Answer, ManagerError>.

Requires merge&bump on ping-rs:

some cool refs:
https://ryhl.io/blog/actors-with-tokio/
https://theari.dev/blog/tokio-actors/
https://www.oreilly.com/library/view/applied-akka-patterns/9781491934876/ch01.html
https://www.amazon.com/Rust-Web-Programming-hands-applications/dp/1803234695

@RaulTrombin RaulTrombin force-pushed the Add_device_mnge branch 7 times, most recently from bc66eda to 2e968e6 Compare July 16, 2024 18:22
@RaulTrombin RaulTrombin changed the title Add: Device manager [WIP] Add: Device manager Jul 16, 2024
@RaulTrombin RaulTrombin marked this pull request as ready for review July 16, 2024 18:35
Comment on lines 396 to 351
Ping1DRequest::DeviceID => match self.device_id().await {
Ok(result) => PingAnswer::PingMessage(bluerobotics_ping::Messages::Ping1D(
bluerobotics_ping::ping1d::Messages::DeviceId(result),
)),
Err(e) => PingAnswer::PingError(e),
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just use a macro for this ?

Copy link
Member Author

@RaulTrombin RaulTrombin Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it'll require some manipulation on strings, custom input for return type and different handling for methods.
But'll help to make to code more cleanner, can we add as an future upgrade?

DeviceNotExist(Uuid),
DeviceAlreadyExist(Uuid),
DeviceIsStopped(Uuid),
Other,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we give an string as content to have more information about the error ?

Copy link
Member Author

@RaulTrombin RaulTrombin Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed this error for now, was used on only one place with an unreachable case.

};
use tokio::sync::{mpsc, oneshot};
use tokio_serial::{SerialPort, SerialPortBuilderExt, SerialStream};
// use tracing::{error, info};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lost comment

Comment on lines 92 to 70
PingRequest::Ping1D(device_request) => match &self.device_type {
DeviceType::Ping1D(device) => {
let answer = device.handle(device_request).await;
let _ = request.respond_to.send(DeviceActorAnswer { answer });
}
_ => {
let ping_request = request.request;
let _ = request.respond_to.send(DeviceActorAnswer {
answer: PingAnswer::NotSupported(ping_request),
});
}
},
PingRequest::Ping360(device_request) => match &self.device_type {
DeviceType::Ping360(device) => {
let answer = device.handle(device_request).await;
let _ = request.respond_to.send(DeviceActorAnswer { answer });
}
_ => {
let ping_request = request.request;
let _ = request.respond_to.send(DeviceActorAnswer {
answer: PingAnswer::NotSupported(ping_request),
});
}
},
PingRequest::Common(device_request) => match &self.device_type {
DeviceType::Common(device) => {
let answer = device.handle(device_request).await;
let _ = request.respond_to.send(DeviceActorAnswer { answer });
}
_ => {
let ping_request = request.request;
let _ = request.respond_to.send(DeviceActorAnswer {
answer: PingAnswer::NotSupported(ping_request),
});
}
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PingRequest::Ping1D(device_request) => match &self.device_type {
DeviceType::Ping1D(device) => {
let answer = device.handle(device_request).await;
let _ = request.respond_to.send(DeviceActorAnswer { answer });
}
_ => {
let ping_request = request.request;
let _ = request.respond_to.send(DeviceActorAnswer {
answer: PingAnswer::NotSupported(ping_request),
});
}
},
PingRequest::Ping360(device_request) => match &self.device_type {
DeviceType::Ping360(device) => {
let answer = device.handle(device_request).await;
let _ = request.respond_to.send(DeviceActorAnswer { answer });
}
_ => {
let ping_request = request.request;
let _ = request.respond_to.send(DeviceActorAnswer {
answer: PingAnswer::NotSupported(ping_request),
});
}
},
PingRequest::Common(device_request) => match &self.device_type {
DeviceType::Common(device) => {
let answer = device.handle(device_request).await;
let _ = request.respond_to.send(DeviceActorAnswer { answer });
}
_ => {
let ping_request = request.request;
let _ = request.respond_to.send(DeviceActorAnswer {
answer: PingAnswer::NotSupported(ping_request),
});
}
},
PingRequest::Ping1D(device_request) | PingRequest::Ping360(device_request) | PingRequest::Common(device_request) => match &self.device_type {
DeviceType::Ping1D(device) | DeviceType::Ping360(device) | DeviceType::Common(device) => {
let answer = device.handle(device_request).await;
let _ = request.respond_to.send(DeviceActorAnswer { answer });
}
_ => {
let ping_request = request.request;
let _ = request.respond_to.send(DeviceActorAnswer {
answer: PingAnswer::NotSupported(ping_request),
});
}
},

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

@RaulTrombin RaulTrombin Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different devices and requests types :-/
Please check below:

error[E0308]: mismatched types
  --> src/device/devices.rs:20:72
   |
19 |         match request.request.clone() {
   |               ----------------------- this expression has type `PingRequest`
20 |             PingRequest::Ping1D(device_request) | PingRequest::Ping360(device_request) | PingRequest::Common(device_request) => match &self.device_type {
   |                                 --------------                         ^^^^^^^^^^^^^^ expected `Ping1DRequest`, found `Ping360Request`
   |                                 |
   |                                 first introduced with type `Ping1DRequest` here
   |
   = note: in the same arm, a binding must have the same type in all alternatives

error[E0308]: mismatched types
  --> src/device/devices.rs:20:110
   |
19 |         match request.request.clone() {
   |               ----------------------- this expression has type `PingRequest`
20 |             PingRequest::Ping1D(device_request) | PingRequest::Ping360(device_request) | PingRequest::Common(device_request) => match &self.device_type {
   |                                 -------------- first introduced with type `Ping1DRequest` here               ^^^^^^^^^^^^^^ expected `Ping1DRequest`, found `PingCommonRequest`
   |
   = note: in the same arm, a binding must have the same type in all alternatives

error[E0308]: mismatched types
  --> src/device/devices.rs:21:66
   |
20 |             PingRequest::Ping1D(device_request) | PingRequest::Ping360(device_request) | PingRequest::Common(device_request) => match &self.device_type {
   |                                                                                                                                       ----------------- this expression has type `&DeviceType`
21 |                 DeviceType::Ping1D(device) | DeviceType::Ping360(device) | DeviceType::Common(device) => {
   |                                    ------                        ^^^^^^ expected `&Ping1D`, found `&Ping360`
   |                                    |
   |                                    first introduced with type `&bluerobotics_ping::device::Ping1D` here
   |
   = note: expected reference `&bluerobotics_ping::device::Ping1D`
              found reference `&bluerobotics_ping::device::Ping360`
   = note: in the same arm, a binding must have the same type in all alternatives

error[E0308]: mismatched types
  --> src/device/devices.rs:21:95
   |
20 |             PingRequest::Ping1D(device_request) | PingRequest::Ping360(device_request) | PingRequest::Common(device_request) => match &self.device_type {
   |                                                                                                                                       ----------------- this expression has type `&DeviceType`
21 |                 DeviceType::Ping1D(device) | DeviceType::Ping360(device) | DeviceType::Common(device) => {
   |                                    ------                                                     ^^^^^^ expected `&Ping1D`, found `&Device`
   |                                    |
   |                                    first introduced with type `&bluerobotics_ping::device::Ping1D` here
   |
   = note: expected reference `&bluerobotics_ping::device::Ping1D`
              found reference `&bluerobotics_ping::common::Device`
   = note: in the same arm, a binding must have the same type in all alternatives

For more information about this error, try `rustc --explain E0308`.
warning: `ping-viewer-next` (bin "ping-viewer-next") generated 1 warning
error: could not compile `ping-viewer-next` (bin "ping-viewer-next") due to 4 previous errors; 1 warning emitted

ping @RaulTrombin

};
device_type
}
DeviceType::Ping1D(device) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should only deal with common case, the others are already upgraded.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the function was designed to:
If they already belong to the upgrading available class, they'll return quickly;
if not, they'll be repaired in the next step.

If it is not dealt with, we will remove this functionality.

Comment on lines 256 to 283
let device = match device_selection {
DeviceSelection::Common | DeviceSelection::Auto => match port {
SourceType::Udp(udp_port) => crate::device::devices::DeviceType::Common(
bluerobotics_ping::common::Device::new(udp_port),
),
SourceType::Serial(serial_port) => crate::device::devices::DeviceType::Common(
bluerobotics_ping::common::Device::new(serial_port),
),
},
DeviceSelection::Ping1D => match port {
SourceType::Udp(udp_port) => {
crate::device::devices::DeviceType::Ping1D(Ping1D::new(udp_port))
}
SourceType::Serial(serial_port) => {
crate::device::devices::DeviceType::Ping1D(Ping1D::new(serial_port))
}
},
DeviceSelection::Ping360 => match port {
SourceType::Udp(udp_port) => {
crate::device::devices::DeviceType::Ping360(Ping360::new(udp_port))
}
SourceType::Serial(serial_port) => {
crate::device::devices::DeviceType::Ping360(Ping360::new(serial_port))
}
},
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should match port first and than the device.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did it.

@patrickelectric patrickelectric merged commit 1a6c538 into bluerobotics:master Jul 18, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants