-
Notifications
You must be signed in to change notification settings - Fork 3
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
Reanalyze events, history, log and decouple from implementation #18
Conversation
Codecov Report
@@ Coverage Diff @@
## main #18 +/- ##
=======================================
Coverage ? 67.63%
=======================================
Files ? 9
Lines ? 1029
Branches ? 0
=======================================
Hits ? 696
Misses ? 333
Partials ? 0 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
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 is probably a great improvement, but my head just isn't into grokking all of this at 3pm on my last day before summer vacation.
I wholly support the separation of concerns, and would appreciate maybe a face-to-face rundown of this compared to what we're doing in the new zino 2.0 codebase when we get back from vacay.
* "testing" was used six times from 2000 to 2001 | ||
* "admin0" was used ten times from 2000 to 2002 | ||
* "flapping" was used 22 times on 2016-07-13T09:55 UTC | ||
* "notPresent" was used 161 times during 2003 | ||
* "5" was used 389 times from 1998 to 2000 | ||
* "dormant" was used 813 times from 2000 to 2006 |
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 would assume these are mostly derived from IF-MIB::ifOperState
, as defined on page 31 of RFC 2863:
up(1), -- ready to pass packets down(2), testing(3), -- in some test mode unknown(4), -- status can not be determined -- for some reason. dormant(5), notPresent(6), -- some component is missing lowerLayerDown(7) -- down due to state of -- lower-layer interface(s)
Zino does feature a flapping status, but I think this might be in a different event attribute, as the actual operational status fetched from the port is either up/down (or any of the other values above). "Flapping" is just Zino's way of flagging an event for a port that keeps switching between up/down states very often.
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 suspect the "flapping" enum value is no longer used/supported since it was only ever used once, during one minute, since 1998. There is a separate enum (FlapState) for showing flapping which I assume was added after that happened.
Does the existing server push these values on blindly?
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'll have to ask HE about this.
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.
Go right ahead and ask HE. Since many of the "strange" values exist only in old data and for limited periods, I would mostly assume they are due to old bugs or at least old versions of the Zino codebase, and do not necessarily represent today's situation.
Most certainly, the 5
value you saw in the data is identical to dormant
: Zino likely got this state value from some ports, and some hiccup in Scotty prevented the raw value from being translated to the MIB's name for that value, dormant
.
58af551
to
ff06d0d
Compare
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 looks mostly fine to me - I've added a couple of nitpicks about missing type annotations that would be helpful, but this applies really to more locations than the few I've commented.
I'd still appreciate a F2F rundown of the architecture here, as I'm not all that familiar with the original ritz/zinolib code. At least that would put me in a better state to comment on your design suggestions. Maybe we can schedule one for next week.
def get_downtime(self): | ||
"""Calculate downtime on this PortState""" | ||
# If no transition is detected, use now. | ||
now = utcnow() | ||
lasttrans = self.lasttrans or now | ||
accumulated = self.ac_down or timedelta(seconds=0) | ||
|
||
if self.port_state in [PortState.DOWN, PortState.LOWER_LAYER_DOWN]: | ||
return accumulated + now - lasttrans | ||
else: | ||
return accumulated |
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 don't know the original ritz/zinolib code very well. Is this algorithm taken directly from there?
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.
Pretty much, yes. The original code calls datetime.now()
multiple times and access lasttrans/ac_down via a case-object, not a typed event-object. Grep for def get_downtime
in src/zinolib/ritz.py
.
4381cc8
to
8bd4422
Compare
a8a7305
to
efd8ba4
Compare
5105619
to
f0fa020
Compare
The EventEngine currently only supports the first load of events, not updates. This was originally written with pydantic v1, v2 was released during development of this rather long-lived branch. Since v2 made our subclass of BaseModel unnecessary, we attempted to upgrade via bump-pydantic. It didn't pick up on our sub-class and some other annoyances. Input to timedelta works different, on v1 you could build a timedelta from an int of seconds stored in a string, in v2 it must be an int. Interestingly the v1 docs does not mention that int-as-string is supported.
This is becoming a ridiculously long-lived branch. Tests are in, engines have been renamed to managers and collected in Bootstrapping and updates via the update-channel are in a different branch based on this, waiting for a merge. |
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.
It works against Howits ig you remove SessionAdapter
. See comments
Rename *engine to *manager and collect them all in the directory controllers. The classes were renamed because the exact same name was used in a different project. They were also moved since the base class was in the wrong file.
The file "src/zinolib/zino1.py" will be removed as soon as this PR is merged, it has only existed to make it easier to use the library while it was in flux. |
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 to me. The implementation was also thoroughly tested by using this code in Howitz and it works really well.
There are some small nitpicks, but nothing major (can be merged as is for my part):
- remove commented out code (see comments)
get_downtime
could return a formatted string without microseconds instead of timedelta, as its only purpose is to be displayed in the table. But this could either be handled in a separate PR, or be delegated to the frontend completely.
And when this is merged, #24 can also be closed 😌
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
This is a major rethink of what events, models, and history looks like. The data classes themselves contain only what is needed to have valid information, and the info is validated on creation by Pydantic. The data classes are filled with data and changed by Engine classes, which are adapted to whatever API/protocol is needed. Using the Zino1 wire protocol has been hidden in the Zino1EventEngine.
The goal is that the data classes can be used both by servers and clients.
MVC-speak: the data classes are models, the engines are the controllers.
Everything is written from the bottom up to be easy to unit test, without using
mock.patch()
.Feedback needed:
Missing:
get_events
after setting state or changing history.Please nitpick! Please ask why things are laid out as they are!