-
Notifications
You must be signed in to change notification settings - Fork 14
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
feat(evpn-bridge): netlink watcher Module #385
feat(evpn-bridge): netlink watcher Module #385
Conversation
824b41e
to
edaa268
Compare
pkg/netlink/eventbus/eventbus.go
Outdated
|
||
// Unsubscribe the subscriber, which delete the subscriber(all resources will be washed out) | ||
func (s *Subscriber) Unsubscribe() { | ||
close(s.Ch) |
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.
If you write to a closed channel, your program will panic, and it is possible since someone can still be writing on the line 56 to a chan.
Usually it is a responsibility of the send side to close the chan.
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.
chan will be closed only when we deinitialize from vendor module. there are some missing pieces in unsubscriber function . will be added in vendor module PR
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.
hmmm... it might work with mutexes, but can we do better? Could WaitGroup help here?
pkg/netlink/netlink_watcher.go
Outdated
} | ||
|
||
// oldgenmap old map | ||
var oldgenmap = make(map[interface{}]interface{}) |
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 have many global vars scattered here and there in this file. Could we group them within a struct, maybe even multiple structs, separated by their purpose? It is sometimes hard to follow what function can change. With usage of global vars and functions, they can change any of them. Functions could operate not on global vars, but on members of a specific struct instance
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.
done
0e3a2c1
to
bcb2125
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.
some more notes
6a88d12
to
b23eb4c
Compare
364a03a
to
47b297f
Compare
pkg/netlink/netlink_watcher.go
Outdated
if strings.Contains(event[1], "route") || strings.HasPrefix(event[1], "nexthop") { | ||
var rv *RouteStruct | ||
var nv *NexthopStruct | ||
if strings.Contains(event[1], "route") { |
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.
how do you know that you have 2 elements in event array?
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.
done
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 done. I see
if rv.Vrf.Status.VrfOperStatus == infradb.VrfOperStatusToBeDeleted {
notifyAddDel(rv, event.Operation[2])
What does index 2 mean here? Why was it 1? Would it make sense to create a dedicated struct where we ahve 3 members and their name clearly explain what those events mean?
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.
each event will have 3 operations add, update and delete, accordingly we are filling operations for each event type, so that's where we have length 3 and index 2 for delete, which already defined as constants
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.
For me, it is just a magic number. You might have context how indexing in this array correspond to operations, but I do not have such a context and people who come and try to understand this code, does not have this context either.
Why we cannot use?
notifyAddDel(rv, event.operations.to_delete)
Plus
The code chunk at the moment look like
if event.EventType == ROUTE || event.EventType == NEXTHOP {
var rv *RouteStruct
var nv *NexthopStruct
if event.EventType == ROUTE {
rv, ok = v1.(*RouteStruct)
if !ok {
log.Printf("Netlink: Type mismatch")
continue
}
if rv.Vrf.Status.VrfOperStatus == infradb.VrfOperStatusToBeDeleted {
notifyAddDel(rv, event.Operation[2])
delete(new_db, k1)
delete(old_db, k1)
continue
}
} else if event.EventType == NEXTHOP {
nv, ok = v1.(*NexthopStruct)
if !ok {
log.Printf("Netlink: Type mismatch")
continue
}
if nv.Vrf.Status.VrfOperStatus == infradb.VrfOperStatusToBeDeleted {
notifyAddDel(nv, event.Operation[2])
delete(new_db, k1)
delete(old_db, k1)
continue
}
}
Don't you have a feeling that the code in first if is very similar in the code in the second if?
Can we have an interface which would return the status, type assert to that interface once, get the status and do your actions without these duplications? Type Assert v1 to one type or another, get status and work with that? Any other means?
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.
Done
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
switch event.EventType {
case ROUTE:
status, ok = v1.(VrfStatusGetter)
case NEXTHOP:
status, ok = v1.(VrfStatusGetter)
default:
}
to
status, ok := v1.(VrfStatusGetter)
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.
Done
pkg/netlink/netlink_watcher.go
Outdated
case *NexthopStruct: | ||
return t.deepEqual(v2.(*NexthopStruct), true) | ||
} | ||
return 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.
so if we have v1 and v2 of different types,t hen we return true
looks suspicious
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.
fixed
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.
but what if v1 and v2 of the same type but not RouteStruct
or NexthopStruct
. It is still 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.
Done, we now check for 4 possible structs
pkg/netlink/netlink_watcher.go
Outdated
if strings.Contains(event[1], "route") || strings.HasPrefix(event[1], "nexthop") { | ||
var rv *RouteStruct | ||
var nv *NexthopStruct | ||
if strings.Contains(event[1], "route") { |
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.
For me, it is just a magic number. You might have context how indexing in this array correspond to operations, but I do not have such a context and people who come and try to understand this code, does not have this context either.
Why we cannot use?
notifyAddDel(rv, event.operations.to_delete)
Plus
The code chunk at the moment look like
if event.EventType == ROUTE || event.EventType == NEXTHOP {
var rv *RouteStruct
var nv *NexthopStruct
if event.EventType == ROUTE {
rv, ok = v1.(*RouteStruct)
if !ok {
log.Printf("Netlink: Type mismatch")
continue
}
if rv.Vrf.Status.VrfOperStatus == infradb.VrfOperStatusToBeDeleted {
notifyAddDel(rv, event.Operation[2])
delete(new_db, k1)
delete(old_db, k1)
continue
}
} else if event.EventType == NEXTHOP {
nv, ok = v1.(*NexthopStruct)
if !ok {
log.Printf("Netlink: Type mismatch")
continue
}
if nv.Vrf.Status.VrfOperStatus == infradb.VrfOperStatusToBeDeleted {
notifyAddDel(nv, event.Operation[2])
delete(new_db, k1)
delete(old_db, k1)
continue
}
}
Don't you have a feeling that the code in first if is very similar in the code in the second if?
Can we have an interface which would return the status, type assert to that interface once, get the status and do your actions without these duplications? Type Assert v1 to one type or another, get status and work with that? Any other means?
Hello @artek-koltun I have created a dedicated PR for the docker-compose fix: #390 |
Co-authored-by: Vemula Venkatesh <[email protected]> Co-authored-by: Saikumar Banoth <[email protected]> Co-authored-by: Jambekar Vishakha <[email protected]> Co-authored-by: Dimitrios Markou <[email protected]> Signed-off-by: atulpatel261194 <[email protected]>
Signed-off-by: Saikumar, Banoth <[email protected]>
Signed-off-by: Saikumar, Banoth <[email protected]>
Signed-off-by: Saikumar, Banoth <[email protected]>
Signed-off-by: Saikumar, Banoth <[email protected]>
Signed-off-by: Saikumar, Banoth <[email protected]>
Signed-off-by: Saikumar, Banoth <[email protected]>
6c99072
to
7ee6677
Compare
pkg/netlink/notify.go
Outdated
case *L2NexthopStruct: | ||
return t.deepEqual(v2.(*L2NexthopStruct), true) | ||
default: | ||
return 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.
Are you sure that you want to return true, if v1 is none of the listed types?
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.
yes, we deal with only the 4 structures defined.
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 if you add a new type, it will be always true if by mistake this code is not updated?
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.
when a new type is declared, one need to implement the difference check function for it, best thing is we can log in default
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.
when a new type is declared, one need to implement the difference check function for it, best thing is we can log in default
best we can do here is to log an error and report that they are not equal if an unknown types are coming
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.
Done
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.
true is still returned
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.
yes, we log and return true because don't want to handle such cases,
In case the values are equal we return true to deepcheck and we don't process it simply delete it,
same when we get unknown structs we log and return true and delete them
pkg/netlink/netlinkstate.go
Outdated
fdbentry.bp, _ = infradb.GetBP(bp) | ||
} | ||
} | ||
Dev := fdbIP.Ifname |
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.
why some vars are capitilized, some not? https://google.github.io/styleguide/go/decisions.html
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.
Done
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.
still see some like CPs
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.
Done
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 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.
Done
Signed-off-by: Saikumar, Banoth <[email protected]>
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.
Signed-off-by: Saikumar, Banoth <[email protected]>
Signed-off-by: Saikumar, Banoth <[email protected]>
Signed-off-by: Saikumar, Banoth <[email protected]>
Signed-off-by: atulpatel261194 <[email protected]>
fbac3d6
to
bb3e67f
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.
Despite the current quality disadvantages, we agreed to merge the code as is due to the time constraints. According to the agreement, the tech debt will be re-designed and addressed by the team with the highest priority.
No description provided.