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