func (c *Checker) checkTCP(result chan bool) {
	if c.TaskInfo.GetContainer().GetDocker().GetNetwork() == mesos.ContainerInfo_DockerInfo_BRIDGE {
		defer namespace.ExitNetworkNamespace()
		err := namespace.EnterNetworkNamespace(c.Pid)
		if err != nil {
			logger.GetInstance().Debug("Error while getting container namespace",
				zap.Error(err),
			)
			result <- false
			return
		}
	}
	port := c.TaskInfo.GetHealthCheck().GetTCP().GetPort()
	conn, err := net.DialTimeout("tcp", fmt.Sprintf("localhost:%d", port), time.Duration(c.TaskInfo.GetHealthCheck().GetTimeoutSeconds())*time.Second)
	if err != nil {
		logger.GetInstance().Error("Error while connecting to health check socket",
			zap.Error(err),
		)
		result <- false
		return
	}
	defer conn.Close()
	result <- true
}
checkTCP enters the container network namespace and
check that given port is accessible
package healthcheck
import (
	"bufio"
	"context"
	"fmt"
	"net"
	"net/http"
	"sync/atomic"
	"time"
	"github.com/Devatoria/go-mesos-executor/container"
	"github.com/Devatoria/go-mesos-executor/logger"
	"github.com/Devatoria/go-mesos-executor/namespace"
	"github.com/mesos/mesos-go/api/v1/lib"
	"go.uber.org/zap"
)
type Checker struct {
	ConsecutiveFailures uint32                   
	ContainerID         string                   
	Containerizer       container.Containerizer  
	Done                chan struct{}            
	Exited              chan struct{}            
	Healthy             chan bool                
	Pid                 int                      
	TaskInfo            *mesos.TaskInfo          
	Quit                chan struct{}            
}
func NewChecker(pid int, c container.Containerizer, containerID string, taskInfo *mesos.TaskInfo) *Checker {
	return &Checker{
		ConsecutiveFailures: 0,
		ContainerID:         containerID,
		Containerizer:       c,
		Done:                make(chan struct{}),
		Exited:              make(chan struct{}),
		Healthy:             make(chan bool),
		Pid:                 pid,
		TaskInfo:            taskInfo,
		Quit:                make(chan struct{}),
	}
}
func (c *Checker) Run() {
	ticker := time.NewTicker(time.Duration(c.TaskInfo.GetHealthCheck().GetIntervalSeconds()) * time.Second)
	defer ticker.Stop()
	time.Sleep(time.Duration(c.TaskInfo.GetHealthCheck().GetDelaySeconds()) * time.Second)
	gracePeriodExpired := uint32(0)
	gracePeriodTimer := time.NewTimer(time.Duration(c.TaskInfo.GetHealthCheck().GetGracePeriodSeconds()) * time.Second)
	defer gracePeriodTimer.Stop()
	go func() {
		<-gracePeriodTimer.C
		atomic.StoreUint32(&gracePeriodExpired, 1)
		logger.GetInstance().Debug("Grace period expired")
	}()
	var checkFunc func(chan bool)
	switch c.TaskInfo.GetHealthCheck().GetType() {
	case mesos.HealthCheck_HTTP:
		checkFunc = c.checkHTTP
	case mesos.HealthCheck_TCP:
		checkFunc = c.checkTCP
	case mesos.HealthCheck_COMMAND:
		checkFunc = c.checkCommand
	default:  
		logger.GetInstance().Error("Unknown or unsupported health check type... Mark task as unhealthy",
			zap.String("type", c.TaskInfo.GetHealthCheck().GetType().String()),
		)
		c.Healthy <- false
		return
	}
	var healthy bool
	for {
		select {
		case <-ticker.C:
			result := make(chan bool)
			go checkFunc(result)
			healthy = <-result
			logger.GetInstance().Debug("Health check ticker has ticked",
				zap.Bool("healthy", healthy),
			)
			if healthy {
				c.ConsecutiveFailures = 0
				atomic.StoreUint32(&gracePeriodExpired, 1)
			} else {
				if atomic.LoadUint32(&gracePeriodExpired) == 1 {
					c.ConsecutiveFailures++
					if c.ConsecutiveFailures == c.TaskInfo.GetHealthCheck().GetConsecutiveFailures() {
						ticker.Stop()
						c.Done <- struct{}{}
						break
					}
				}
			}
			c.Healthy <- healthy
		case <-c.Quit:
			logger.GetInstance().Debug("Shutting down checker")
			c.Exited <- struct{}{}
			return
		}
	}
}
func (c *Checker) checkHTTP(result chan bool) {
	if c.TaskInfo.GetContainer().GetDocker().GetNetwork() == mesos.ContainerInfo_DockerInfo_BRIDGE {
		defer namespace.ExitNetworkNamespace()  
		err := namespace.EnterNetworkNamespace(c.Pid)
		if err != nil {
			logger.GetInstance().Debug("Error while getting container namespace",
				zap.Error(err),
			)
			result <- false
			return
		}
	}
	port := c.TaskInfo.GetHealthCheck().GetHTTP().GetPort()
	path := c.TaskInfo.GetHealthCheck().GetHTTP().GetPath()
	conn, err := net.DialTimeout("tcp", fmt.Sprintf("localhost:%d", port), time.Duration(c.TaskInfo.GetHealthCheck().GetTimeoutSeconds())*time.Second)
	if err != nil {
		logger.GetInstance().Error("Error while connecting to health check socket",
			zap.Error(err),
		)
		result <- false
		return
	}
	defer conn.Close()
	fmt.Fprintf(conn, fmt.Sprintf("GET %s HTTP/1.0\r\n\r\n", path))
	status := bufio.NewReader(conn)
	response, err := http.ReadResponse(status, nil)
	if err != nil {
		logger.GetInstance().Error("Error while reading HTTP response",
			zap.Error(err),
		)
		result <- false
		return
	}
	if response.StatusCode < 200 || response.StatusCode > 399 {
		logger.GetInstance().Error("Unexpected status code",
			zap.Int("code", response.StatusCode),
		)
		result <- false
		return
	}
	result <- true
}