github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/containerd/supervisor/worker.go (about)

     1  package supervisor
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	"github.com/Sirupsen/logrus"
     8  	"github.com/docker/containerd/runtime"
     9  	"golang.org/x/net/context"
    10  )
    11  
    12  // Worker interface
    13  type Worker interface {
    14  	Start()
    15  }
    16  
    17  type startTask struct {
    18  	Container      runtime.Container
    19  	CheckpointPath string
    20  	Stdin          string
    21  	Stdout         string
    22  	Stderr         string
    23  	Err            chan error
    24  	StartResponse  chan StartResponse
    25  	Ctx            context.Context
    26  }
    27  
    28  // NewWorker return a new initialized worker
    29  func NewWorker(s *Supervisor, wg *sync.WaitGroup) Worker {
    30  	return &worker{
    31  		s:  s,
    32  		wg: wg,
    33  	}
    34  }
    35  
    36  type worker struct {
    37  	wg *sync.WaitGroup
    38  	s  *Supervisor
    39  }
    40  
    41  // Start runs a loop in charge of starting new containers
    42  func (w *worker) Start() {
    43  	defer w.wg.Done()
    44  	for t := range w.s.startTasks {
    45  		started := time.Now()
    46  		process, err := t.Container.Start(t.Ctx, t.CheckpointPath, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr))
    47  		if err != nil {
    48  			logrus.WithFields(logrus.Fields{
    49  				"error": err,
    50  				"id":    t.Container.ID(),
    51  			}).Error("containerd: start container")
    52  			t.Err <- err
    53  			evt := &DeleteTask{
    54  				ID:      t.Container.ID(),
    55  				NoEvent: true,
    56  				Process: process,
    57  			}
    58  			w.s.SendTask(evt)
    59  			continue
    60  		}
    61  		if err := w.s.monitor.MonitorOOM(t.Container); err != nil && err != runtime.ErrContainerExited {
    62  			if process.State() != runtime.Stopped {
    63  				logrus.WithField("error", err).Error("containerd: notify OOM events")
    64  			}
    65  		}
    66  		if err := w.s.monitorProcess(process); err != nil {
    67  			logrus.WithField("error", err).Error("containerd: add process to monitor")
    68  			t.Err <- err
    69  			evt := &DeleteTask{
    70  				ID:      t.Container.ID(),
    71  				NoEvent: true,
    72  				Process: process,
    73  			}
    74  			w.s.SendTask(evt)
    75  			continue
    76  		}
    77  		// only call process start if we aren't restoring from a checkpoint
    78  		// if we have restored from a checkpoint then the process is already started
    79  		if t.CheckpointPath == "" {
    80  			if err := process.Start(); err != nil {
    81  				logrus.WithField("error", err).Error("containerd: start init process")
    82  				t.Err <- err
    83  				evt := &DeleteTask{
    84  					ID:      t.Container.ID(),
    85  					NoEvent: true,
    86  					Process: process,
    87  				}
    88  				w.s.SendTask(evt)
    89  				continue
    90  			}
    91  		}
    92  		ContainerStartTimer.UpdateSince(started)
    93  		w.s.newExecSyncMap(t.Container.ID())
    94  		t.Err <- nil
    95  		t.StartResponse <- StartResponse{
    96  			Container: t.Container,
    97  		}
    98  		w.s.notifySubscribers(Event{
    99  			Timestamp: time.Now(),
   100  			ID:        t.Container.ID(),
   101  			Type:      StateStart,
   102  		})
   103  	}
   104  }