mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
This tag of hcsshim brings in a couple welcome features/improvements. One being exposing a way to query for hns endpoint statistics (Packets received/sent etc.). This tag also contains some optimizations for querying whether a certain HCN feature is supported, which is a common workflow in kube-proxy on Windows. The first result from querying HCN is now cached so further calls can skip the hcn query as well as the version range parsing that was performed. This also gets rid of some redundant logs that used to hit everytime the version range parsing occurred. The Go-winio dep bump, and all of the ctrd deps are transitive only. Nothing new is needed/intended to be used. Signed-off-by: Daniel Canter <dcanter@microsoft.com>
69 lines
2.1 KiB
Go
69 lines
2.1 KiB
Go
package hcs
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/Microsoft/hcsshim/internal/log"
|
|
)
|
|
|
|
func processAsyncHcsResult(ctx context.Context, err error, resultJSON string, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) ([]ErrorEvent, error) {
|
|
events := processHcsResult(ctx, resultJSON)
|
|
if IsPending(err) {
|
|
return nil, waitForNotification(ctx, callbackNumber, expectedNotification, timeout)
|
|
}
|
|
|
|
return events, err
|
|
}
|
|
|
|
func waitForNotification(ctx context.Context, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
|
|
callbackMapLock.RLock()
|
|
if _, ok := callbackMap[callbackNumber]; !ok {
|
|
callbackMapLock.RUnlock()
|
|
log.G(ctx).WithField("callbackNumber", callbackNumber).Error("failed to waitForNotification: callbackNumber does not exist in callbackMap")
|
|
return ErrHandleClose
|
|
}
|
|
channels := callbackMap[callbackNumber].channels
|
|
callbackMapLock.RUnlock()
|
|
|
|
expectedChannel := channels[expectedNotification]
|
|
if expectedChannel == nil {
|
|
log.G(ctx).WithField("type", expectedNotification).Error("unknown notification type in waitForNotification")
|
|
return ErrInvalidNotificationType
|
|
}
|
|
|
|
var c <-chan time.Time
|
|
if timeout != nil {
|
|
timer := time.NewTimer(*timeout)
|
|
c = timer.C
|
|
defer timer.Stop()
|
|
}
|
|
|
|
select {
|
|
case err, ok := <-expectedChannel:
|
|
if !ok {
|
|
return ErrHandleClose
|
|
}
|
|
return err
|
|
case err, ok := <-channels[hcsNotificationSystemExited]:
|
|
if !ok {
|
|
return ErrHandleClose
|
|
}
|
|
// If the expected notification is hcsNotificationSystemExited which of the two selects
|
|
// chosen is random. Return the raw error if hcsNotificationSystemExited is expected
|
|
if channels[hcsNotificationSystemExited] == expectedChannel {
|
|
return err
|
|
}
|
|
return ErrUnexpectedContainerExit
|
|
case _, ok := <-channels[hcsNotificationServiceDisconnect]:
|
|
if !ok {
|
|
return ErrHandleClose
|
|
}
|
|
// hcsNotificationServiceDisconnect should never be an expected notification
|
|
// it does not need the same handling as hcsNotificationSystemExited
|
|
return ErrUnexpectedProcessAbort
|
|
case <-c:
|
|
return ErrTimeout
|
|
}
|
|
}
|