-
Notifications
You must be signed in to change notification settings - Fork 2
fileio cli improvments [DEVINFRA-602] [DEVINFRA-601] #395
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
Conversation
a56f544
to
687bb2c
Compare
I think reading might have a bug, appears to just hang sometimes |
7e296c6
to
fb39aa7
Compare
console_backend/src/bin/fileio.rs
Outdated
|
||
impl Remote { | ||
fn connect(&self, conn: ConnectionOpts) -> Result<Fileio> { | ||
let (reader, writer) = if self.host.parse::<SocketAddr>().is_ok() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how well this will work, if it looks like a tcp addr then we try and connect to tcp, otherwise we assume it's serial.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this need to be self.host.parse::<IpAddr>().is_ok()
? As the port is specified as a different argument? Not sure how this is working for you otherwise, unless I'm misunderstanding how to enter the CLI args?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yup good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually how about
let (reader, writer) = if File::open(&self.host).is_ok() {
SerialConnection::new(self.host.clone(), conn.baudrate, conn.flow_control)
.try_connect(None)?
} else {
TcpConnection::new(self.host.clone(), conn.port)?.try_connect(None)?
};
I think we should support using a hostname, and looking one up takes a bit of time so I think we should do it second. File::open(&self.host).is_ok()
seems to work on windows for checking if something is a serial port, haven't tried linux yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds reasonable to me, would Path::exists
be very slightly better to save an additional open?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried that and for whatever reason Path::exists
returns false for a com port on windows, but opening the file succeeds? I don't really understand windows that well, but might have something to do with it not having quite the same "everything is a file" approach that unix has
/// Piksi File IO operations. | ||
#[derive(Parser)] | ||
#[clap( | ||
name = "fileio", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the context of the "Swift Toolbox" I think this name makes sense, but it also feels a little generic. Maybe piksi-fileio
or something would be better
fb39aa7
to
0696b2f
Compare
0696b2f
to
6db4df1
Compare
.into_remote() | ||
.context("--delete flag requires <SRC> to be a remote target")?; | ||
let fileio = remote.connect(conn)?; | ||
fileio.remove(remote.path)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Over TCP, this doesn't work for me (the file doesn't get deleted) and, as far as I can tell, it's because the socket gets shut down too quickly. It does work when there's a short 1s sleep added (though I think much less than 1s would suffice as well). Comparing wireshark captures for the Python fileio and this version with a 1s delay, I can see:
To Piksi: PSH ACK
From Piksi: ACK
To Piksi: FIN ACK
From Piksi: FIN ACK
To Piksi: ACK
But without the delay I see:
To Piksi: PSH ACK
To Piksi: FIN ACK
From Piksi: ACK
From Piksi: ACK
From Piksi: RST, ACK
I think SO_LINGER
would help here but it looks like it's only enabled in nightly at the moment. The easy solution is probably just to add a delay here 🤷♂️ . I guess read/write should be fine as they wait for SBP layer acks before closing the connection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, added the sleep. https://doc.rust-lang.org/std/net/struct.TcpStream.html#method.set_nodelay might also work, maybe the message never gets set because its not enough data. Regardless I kind of like the sleep, make it feel like the tool is waiting for a ack even though its not 😆
- Show some example usages in help text Co-authored-by: Steven Meyer <[email protected]> Co-authored-by: notoriaga <[email protected]>
dcb00cc
to
9fedda3
Compare
None => continue, | ||
}; | ||
if elapsed < FILE_IO_TIMEOUT { | ||
std::thread::sleep(FILE_IO_TIMEOUT - elapsed); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was sometimes a bit of a delay sometimes after finishing a write, which was because we were waiting for the timeout thread to join and it was asleep. This lets up wake up the timeout thread when we finish so we can exit faster
) { | ||
let mut batch = Vec::with_capacity(config.batch_size); | ||
let send_batch = move |batch: &mut Vec<MsgFileioWriteReq>| -> bool { | ||
let mut guard = pending_map.lock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixes a weird race condition (which I only seem to ran into reliably on windows) where we'd check to see if we finished writing by checking if pending_map
was empty. The map would be empty because the request making thread didn't get a chance to insert the new requests. Holding the lock here seems to make it work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bug manifests as a write "hanging", I'm willing to bet this has affected things like updating firmware (again, mostly appears to have been a windows issue for whatever reason)
}; | ||
if elapsed < FILE_IO_TIMEOUT { | ||
std::thread::sleep(FILE_IO_TIMEOUT - elapsed); | ||
timeout_parker.park_timeout(FILE_IO_TIMEOUT - elapsed); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm seeing the upgrade process hang when connected to a device via serial but not using a tcp connection is there something we could do in this PR to address it? I do see this message as well if it is related: timeout thread finished
. Somewhat unrelated but also appears to be struggling with the speed of serial, the time to load the settings. See:
https://swift-nav.atlassian.net/browse/CPP-641
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that with this pr? That may have been related to the other change with the lock
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this issue is on main as well. I was just wondering if there was a timeout here you are touching that could possibly resolve the issue. I could understand addressing this in a separate PR too if it is more involved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Based on the feedback here - https://swift-nav.atlassian.net/wiki/spaces/~460004640/pages/2108063854/FileIO+feedback
^ I changed the styling to be a bit more plain, and also added a spinner for reads (because we don't know the file size before hand). I don't really have an opinion on how either should look. It's pretty easy to mess around with if anyone is interested