-
Notifications
You must be signed in to change notification settings - Fork 8
Allow - as an output argument to pipe to std out
#89
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
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.
Thanks for the PR :)
I like the idea in theory. In practice, I'm not a fan of the Box<dyn Write>. Rather, I think the write logic should just all get moved into a separate function with a generic O: Write, then a call would be made in each arm of the match.
Would love to apply this to the other files - maybe at least bigbedtobed, bigwigtobedgraph, and bigwigvaluesoverbed. Though, I'm okay if you want to just keep scope limited for this PR, and can open an issue to apply this to the other bins.
|
@jackh726 Thanks for the response! I agree pulling out the logic and applying it to other files would be great. I see what you mean about using static dispatch with a generic function instead of fn run_computation<W: Write, R: Reopen + BBIFileRead>(...) -> Result<...> {
// ... core logic ...
}And in the main function: match bedoutpath.as_str() {
"-" => {
// ... setup stdout writer
run_computation(writer, ...)
},
_ => {
// ... setup file writer
run_computation(writer, ...)
}
} |
|
Yes, that's exactly what I had in mind :) |
|
Awesome that makes sense. yeah this isnt too bad at all! I can try that out, re-push and you can let me know what you think |
|
@jackh726 I've got functionality going for runtime.block_on(async move {
loop {
let next = buf_rcv.next().await;
let Some(mut buf) = next else {
data_handle.await.unwrap()?;
return Ok::<_, BBIReadError>(());
};
buf.switch(out_file);
while !buf.is_real_file_ready() {
tokio::task::yield_now().await;
}
out_file = buf.await_real_file();
}
})?;This makes static dispatch difficult since these functions are sort of inherently assuming that we will be giving them a file so its hard to make it abstract via traits and just pass in a |
|
In summary:
|
|
Hmm, not sure I follow. Maybe you want to push a commit where things break and I can help give some concrete feedback. |
|
@jackh726 just pushed. I worked more this morning on it, but still stuck. I can try to be more specific. I think that core issue (from what I can see) is this: the original Essentially, the crux of the issue is when we try to run the future in runtime.block_on(async move {
loop {
let next = buf_rcv.next().await;
let Some(mut buf) = next else {
data_handle.await.unwrap()?;
return Ok::<_, BBIReadError>(());
};
buf.switch(out_file);
while !buf.is_real_file_ready() {
tokio::task::yield_now().await;
}
out_file = buf.await_real_file();
}
})?;It seems to be waiting for the buffer to become available, then it attempts to switch the buffer from that runtime.block_on(async move {
loop {
let next = buf_rcv.next().await;
let Some(buf) = next else {
data_handle.await.unwrap()?;
return Ok::<_, BBIReadError>(());
};
// get a readable handle to the temp buffer.
let mut reader = buf.into_reader()?;
// copy the entire contents of the temp buffer to our generic writer.
io::copy(&mut reader, &mut writer)?;
}
})?;Which I think is close, but I think we'd need to implement Does that make sense? I might be way over complicating things. But regardless, I pushed what I have and what I think is close... its erroring and maybe you can take a glance |
|
I just pushed a commit that fixes this. I was just hard-coding Haven't otherwise reviewed all your changes, but two things that seem like should be done:
|
|
Oh that was a simple fix I see now. Ok thank you I should have caught that.
|
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.
Changes overall look good - though, I think we should be keeping the BufWriter around the inner O: Writes, since we don't want to be syscalling for every byte write (though, tbh, I haven't benchmarked one vs the other, it may be that removing the BufWriter is actually faster)
Also, can you squash you commits?
|
|
||
| let bedin = File::open(bedinpath).unwrap(); | ||
| let mut bedstream = StreamingLineReader::new(BufReader::new(bedin)); | ||
| let mut outwriter = BufWriter::new(out); |
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.
And here
Gotcha. Essentially this? match bedpath.as_str() {
"-" => {
let stdout = io::stdout();
write_bed_from_bed(bigbed, writer, overlap_bed)?;
}
_ => {
let file = File::create(bedpath)?;
write_bed_from_bed(bigbed, writer, overlap_bed)?;
}
}then, inside fn write_bed_from_bed<O: Write>(writer: O) {
let bufwriter = BufWriter::new(writer);
// use it
}And yes, I'll squash those commits |
|
@jackh726 still working on this got pulled away last night/afternoon. Just to follow up and clarify: You essentially want the Once I'm done with the changes, I'll squash the commits as well |
|
Ah, maybe I missed that they were created before passing in - but yes, please keep them (and keep them in the same place with the same args on creation). |
|
Ok, @jackh726 moved back to |
|
Hmm, don't see your changes. Maybe you didn't force push (and thought the push was successful?) |
|
Not sure... I think they are there if I look at "files changed." This is what I can see on my end: The changes were easy enough, I could just close this, start a new branch/fork, and retry. That side-steps the commit squashing altogether as well. |
|
No worries - I'll just get this in later today :) (I can do the last bits needed.) Thanks for your PR! |
66b18a6 to
2811cf8
Compare
2811cf8 to
b44de4b
Compare
|
Okay, made all the changes. Again, thanks for the pull request. This is great work, and I appreciate you putting up with the review process :) |
|
Thanks for reviewing and letting me contribute! |
I had a use case to pipe things around in my terminal.... particularly with
bigWigAverageOverBed. Super small tweak to allow a user to specify-as the output path argument and it will pipe it out instead of writing to a file.I suppose this logic could be duplicated to other tools. Btw thanks for this tool its much cleaner and faster than kentUtils 😄