Created
January 17, 2022 17:05
-
-
Save jayunit100/8aaf0271dc64f3f023637bd417f331b7 to your computer and use it in GitHub Desktop.
some comments on the diff function, which will be increasingly the backbone for kpng
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func (sl *ServicesListener) diff(prevSvc, currSvc *localnetv1.Service) { | |
// 0) make PortsListener calls by leveraging the SlicesLen iterator | |
// name, protoc, port, nodeport, targetport, targetportname | |
var prevPorts, currPorts []*localnetv1.PortMapping | |
if prevSvc != nil { | |
prevPorts = prevSvc.Ports | |
} | |
if currSvc != nil { | |
currPorts = currSvc.Ports | |
} | |
if sl.PortsListener != nil { | |
Diff{ | |
SameKey: func(pi, ci int) bool { | |
return samePort(prevPorts[pi], currPorts[ci]) | |
}, | |
Added: func(ci int) { sl.PortsListener.AddPort(currSvc, currPorts[ci]) }, | |
Updated: func(_, _ int) {}, | |
Deleted: func(pi int) { sl.PortsListener.DeletePort(prevSvc, prevPorts[pi]) }, | |
}.SlicesLen(len(prevPorts), len(currPorts)) | |
} | |
// there are 3 kinds of IPs: ClusterIP, ExternalIP, and LoadBalancerIP. we build a array | |
// which we'll use below | |
ipsExtractors := []struct { | |
ipKind IPKind | |
getIPs func(svc *localnetv1.Service) *localnetv1.IPSet | |
}{ | |
{ClusterIP, func(svc *localnetv1.Service) *localnetv1.IPSet { | |
if svc.IPs == nil { | |
return nil | |
} | |
return svc.IPs.ClusterIPs | |
}}, | |
{ExternalIP, func(svc *localnetv1.Service) *localnetv1.IPSet { | |
if svc.IPs == nil { | |
return nil | |
} | |
return svc.IPs.ExternalIPs | |
}}, | |
{LoadBalancerIP, func(svc *localnetv1.Service) *localnetv1.IPSet { | |
if svc.IPs == nil { | |
return nil | |
} | |
return svc.IPs.LoadBalancerIPs | |
}}, | |
} | |
// We defer the "delete" calls, but decide which calls to make right now... | |
deferredCalls := make([]func(), 0) | |
// 1) make internal IPsListener calls based on the diffs | |
if sl.IPsListener != nil { | |
for _, ext := range ipsExtractors { | |
ext := ext | |
var prevIPs, currIPs []string | |
if prevSvc != nil { | |
prevIPs = ext.getIPs(prevSvc).All() | |
} | |
if currSvc != nil { | |
currIPs = ext.getIPs(currSvc).All() | |
} | |
// Create a new "Diff". Then iterate through the every "previous/current" tuple | |
// inside of the SlicesLen method. This method will ultimately call | |
// Added | |
// Updated | |
// Deleted | |
// these functions, respectively will | |
// call IP on the IPsListener | |
// call delete IP (deferred) on the IPListener | |
Diff{ | |
SameKey: func(pi, ci int) bool { | |
return prevIPs[pi] == currIPs[ci] | |
}, | |
Added: func(ci int) { | |
sl.IPsListener.AddIP(currSvc, currIPs[ci], ext.ipKind) | |
}, | |
Updated: func(_, _ int) {}, // <-- how come we dont do anything when Updated() ??? | |
Deleted: func(pi int) { | |
deferredCalls = append(deferredCalls, func() { sl.IPsListener.DeleteIP(prevSvc, prevIPs[pi], ext.ipKind) }) | |
}, | |
}.SlicesLen(len(prevIPs), len(currIPs)) | |
} | |
} | |
// 2) Now make IPPortsListener calls based on the diffs ............... | |
if sl.IPPortsListener != nil { | |
for _, ext := range ipsExtractors { | |
ext := ext | |
type ipPort struct { | |
ip string | |
port *localnetv1.PortMapping | |
} | |
// compbine makes an array of ipPorts from a service .... | |
combine := func(svc *localnetv1.Service) []ipPort { | |
if svc == nil { | |
return nil | |
} | |
ips := ext.getIPs(svc).All() | |
pairs := make([]ipPort, 0, len(ips)*len(svc.Ports)) | |
for _, ip := range ips { | |
for _, port := range svc.Ports { | |
pairs = append(pairs, ipPort{ip, port}) | |
} | |
} | |
return pairs | |
} | |
// make prev and current list of ip port tuples.... | |
prevs := combine(prevSvc) | |
currs := combine(currSvc) | |
Diff{ | |
SameKey: func(pi, ci int) bool { | |
return prevs[pi].ip == currs[ci].ip && samePort(prevs[pi].port, currs[ci].port) | |
}, | |
Added: func(ci int) { sl.IPPortsListener.AddIPPort(currSvc, currs[ci].ip, ext.ipKind, currs[ci].port) }, | |
Updated: func(_, _ int) {}, | |
Deleted: func(pi int) { sl.IPPortsListener.DeleteIPPort(currSvc, prevs[pi].ip, ext.ipKind, prevs[pi].port) }, | |
}.SlicesLen(len(prevs), len(currs)) | |
} | |
} | |
// now issue the deferred delete calls from (1) | |
for _, deferredCall := range deferredCalls { | |
deferredCall() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment