-
Notifications
You must be signed in to change notification settings - Fork 276
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
Define loggers in terms of container builders #615
Define loggers in terms of container builders #615
Conversation
The logging infrastructure had some old assumptions built in, such as the container type and the size of buffers. With this change, we defer to the container builder pattern to re-use the existing infrastructure. This also allows us to switch the container type to something else if we'd like to do so. Signed-off-by: Moritz Hoffmann <antiguru@gmail.com>
Signed-off-by: Moritz Hoffmann <antiguru@gmail.com>
TimelyDataflow/timely-dataflow#615 Signed-off-by: Moritz Hoffmann <antiguru@gmail.com>
where | ||
S: Stream, | ||
{ | ||
// Log the receive thread's start. | ||
logger.as_mut().map(|l| l.log(StateEvent { send: false, process, remote, start: true })); | ||
if let Some(logger) = logger.as_ref() { | ||
logger.log(CommunicationEvent::from(StateEvent { send: false, process, remote, start: true })); |
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've seen a bunch of these, and don't know yet but wonder if log
should take a T: From<Foo>
where Foo
is the type it otherwise expects as its argument.
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.
That's hard because we need a T that can be copied into the container (builder), and that supports From for some argument type. I don't think rust could figure out the in-between type because there might be more than one option. This means we have to specify it somewhere manually....
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.
Gotcha. One option would be to have a Logger<T, CB: PushInto<T>>
, which carries the opinions about what you should be pushing in to it. I can't really tell whether it is worse giving up the generality of PushInto
, as that would do, or giving up the Into
constraint and asking folks to build the logged types more explicitly.
logging/src/lib.rs
Outdated
pub fn log<S: Into<T>>(&self, event: S) { | ||
pub fn log<S>(&self, event: S) where CB: PushInto<(Duration, S)> { |
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.
Can you say why the Into<T>
went away? It feels like a bit of the noise in other files is making up for this. Is it that we shouldn't want to invoke .into()
before pushing, or .. some other reason? Or no particular reason?
logging/src/lib.rs
Outdated
if !self.buffer.is_empty() { | ||
self.flush(); | ||
} | ||
self.flush(); |
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.
The code doesn't really match the comment any more. I think it does avoid sending empty buffers because of flush()
's implementation, but also the implementation has a TODO to change that.
timely/src/dataflow/scopes/child.rs
Outdated
@@ -70,6 +70,7 @@ where | |||
fn peek_identifier(&self) -> usize { | |||
self.parent.peek_identifier() | |||
} | |||
#[inline(always)] |
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.
?
timely/src/logging.rs
Outdated
pub messages: Box<dyn ProgressEventTimestampVec>, | ||
pub messages: std::rc::Rc<dyn ProgressEventTimestampVec>, |
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.
You mentioned that this change was due to needing Clone
to work out. I think we should probably at least write a note about this explaining to ourselves what is going on here. Another option (h/t @ParkMyCar) is to have the traits provide a box_clone(&self)
method that produces a Box<dyn Trait>
, though .. we would need to write the Clone
implementation manually. I'm not 100% sure I grok the fall out with Rc
, if for example we ever needed to implement Send
.
timely/src/progress/reachability.rs
Outdated
@@ -74,7 +74,6 @@ | |||
|
|||
use std::collections::{BinaryHeap, HashMap, VecDeque}; | |||
use std::cmp::Reverse; | |||
|
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.
Hrm. Not sure about the formatting, but generally try to space out std
vs crate stuffs!
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.
Although I think we can merge this, it seems like there is some noise around how we log things, both in the switch from .map(|l| ...)
to if let
, but also in removing the Into
constraint requiring more awareness about the types that actually get logged. Happy to discuss!
Signed-off-by: Moritz Hoffmann <antiguru@gmail.com>
if buffer_capacity < Self::buffer_capacity() { | ||
self.buffer.reserve((buffer_capacity+1).next_power_of_two()); | ||
} |
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.
We had logic in place that tried to grow the buffers geometrically, but I'm not sure that was still working as originally intended. With the switch to container builders, that logic certainly doesn't exist here anymore.
I changed the PR to introduce a Also, I followed the I restored the flush behavior to send empty buffers when nothing had been logged, and drop to only flush if anything had been logged since the last flush. |
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.
Looks good! I think I understand most of it, but I haven't fully grokked the dirty
stuff yet. Sorry if me being confused resulted in PR churn. The other parts look good, and we should move ahead with this, and I can figure out what we need to be true about logging async, though it almost certainly derives from running it and seeing what is bad, which landing this unblocks more of.
* Incorporate breaking changes from Timely's logging update TimelyDataflow/timely-dataflow#615 Signed-off-by: Moritz Hoffmann <antiguru@gmail.com> * Back out of some changes Signed-off-by: Moritz Hoffmann <antiguru@gmail.com> * Upgrade timely Signed-off-by: Moritz Hoffmann <antiguru@gmail.com> * Fix compile errors Signed-off-by: Moritz Hoffmann <antiguru@gmail.com> --------- Signed-off-by: Moritz Hoffmann <antiguru@gmail.com>
The logging infrastructure had some old assumptions built in, such as the
container type and the size of buffers. With this change, we defer to the
container builder pattern to re-use the existing infrastructure. This also
allows us to switch the container type to something else if we'd like to do
so.
Signed-off-by: Moritz Hoffmann antiguru@gmail.com