Rename Events to task in supervisor

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-02-11 17:26:24 -08:00
parent d2bf71043f
commit 3dc59d565a
18 changed files with 274 additions and 281 deletions

View file

@ -32,7 +32,7 @@ func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContaine
if c.BundlePath == "" { if c.BundlePath == "" {
return nil, errors.New("empty bundle path") return nil, errors.New("empty bundle path")
} }
e := supervisor.NewEvent(supervisor.StartContainerEventType) e := supervisor.NewTask(supervisor.StartContainerTaskType)
e.ID = c.Id e.ID = c.Id
e.BundlePath = c.BundlePath e.BundlePath = c.BundlePath
e.Stdin = c.Stdin e.Stdin = c.Stdin
@ -45,7 +45,7 @@ func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContaine
Name: c.Checkpoint, Name: c.Checkpoint,
} }
} }
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }
@ -60,11 +60,11 @@ func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContaine
} }
func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse, error) { func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse, error) {
e := supervisor.NewEvent(supervisor.SignalEventType) e := supervisor.NewTask(supervisor.SignalTaskType)
e.ID = r.Id e.ID = r.Id
e.Pid = r.Pid e.Pid = r.Pid
e.Signal = syscall.Signal(int(r.Signal)) e.Signal = syscall.Signal(int(r.Signal))
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }
@ -89,7 +89,7 @@ func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest)
if r.Pid == "" { if r.Pid == "" {
return nil, fmt.Errorf("process id cannot be empty") return nil, fmt.Errorf("process id cannot be empty")
} }
e := supervisor.NewEvent(supervisor.AddProcessEventType) e := supervisor.NewTask(supervisor.AddProcessTaskType)
e.ID = r.Id e.ID = r.Id
e.Pid = r.Pid e.Pid = r.Pid
e.ProcessSpec = process e.ProcessSpec = process
@ -97,7 +97,7 @@ func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest)
e.Stdout = r.Stdout e.Stdout = r.Stdout
e.Stderr = r.Stderr e.Stderr = r.Stderr
e.StartResponse = make(chan supervisor.StartResponse, 1) e.StartResponse = make(chan supervisor.StartResponse, 1)
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }
@ -106,7 +106,7 @@ func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest)
} }
func (s *apiServer) CreateCheckpoint(ctx context.Context, r *types.CreateCheckpointRequest) (*types.CreateCheckpointResponse, error) { func (s *apiServer) CreateCheckpoint(ctx context.Context, r *types.CreateCheckpointRequest) (*types.CreateCheckpointResponse, error) {
e := supervisor.NewEvent(supervisor.CreateCheckpointEventType) e := supervisor.NewTask(supervisor.CreateCheckpointTaskType)
e.ID = r.Id e.ID = r.Id
e.Checkpoint = &runtime.Checkpoint{ e.Checkpoint = &runtime.Checkpoint{
Name: r.Checkpoint.Name, Name: r.Checkpoint.Name,
@ -115,7 +115,7 @@ func (s *apiServer) CreateCheckpoint(ctx context.Context, r *types.CreateCheckpo
UnixSockets: r.Checkpoint.UnixSockets, UnixSockets: r.Checkpoint.UnixSockets,
Shell: r.Checkpoint.Shell, Shell: r.Checkpoint.Shell,
} }
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }
@ -126,12 +126,12 @@ func (s *apiServer) DeleteCheckpoint(ctx context.Context, r *types.DeleteCheckpo
if r.Name == "" { if r.Name == "" {
return nil, errors.New("checkpoint name cannot be empty") return nil, errors.New("checkpoint name cannot be empty")
} }
e := supervisor.NewEvent(supervisor.DeleteCheckpointEventType) e := supervisor.NewTask(supervisor.DeleteCheckpointTaskType)
e.ID = r.Id e.ID = r.Id
e.Checkpoint = &runtime.Checkpoint{ e.Checkpoint = &runtime.Checkpoint{
Name: r.Name, Name: r.Name,
} }
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }
@ -139,8 +139,8 @@ func (s *apiServer) DeleteCheckpoint(ctx context.Context, r *types.DeleteCheckpo
} }
func (s *apiServer) ListCheckpoint(ctx context.Context, r *types.ListCheckpointRequest) (*types.ListCheckpointResponse, error) { func (s *apiServer) ListCheckpoint(ctx context.Context, r *types.ListCheckpointRequest) (*types.ListCheckpointResponse, error) {
e := supervisor.NewEvent(supervisor.GetContainerEventType) e := supervisor.NewTask(supervisor.GetContainerTaskType)
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }
@ -173,9 +173,9 @@ func (s *apiServer) ListCheckpoint(ctx context.Context, r *types.ListCheckpointR
} }
func (s *apiServer) State(ctx context.Context, r *types.StateRequest) (*types.StateResponse, error) { func (s *apiServer) State(ctx context.Context, r *types.StateRequest) (*types.StateResponse, error) {
e := supervisor.NewEvent(supervisor.GetContainerEventType) e := supervisor.NewTask(supervisor.GetContainerTaskType)
e.ID = r.Id e.ID = r.Id
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }
@ -245,10 +245,10 @@ func toUint32(its []int) []uint32 {
} }
func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContainerRequest) (*types.UpdateContainerResponse, error) { func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContainerRequest) (*types.UpdateContainerResponse, error) {
e := supervisor.NewEvent(supervisor.UpdateContainerEventType) e := supervisor.NewTask(supervisor.UpdateContainerTaskType)
e.ID = r.Id e.ID = r.Id
e.State = runtime.State(r.Status) e.State = runtime.State(r.Status)
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }
@ -256,13 +256,13 @@ func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContaine
} }
func (s *apiServer) UpdateProcess(ctx context.Context, r *types.UpdateProcessRequest) (*types.UpdateProcessResponse, error) { func (s *apiServer) UpdateProcess(ctx context.Context, r *types.UpdateProcessRequest) (*types.UpdateProcessResponse, error) {
e := supervisor.NewEvent(supervisor.UpdateProcessEventType) e := supervisor.NewTask(supervisor.UpdateProcessTaskType)
e.ID = r.Id e.ID = r.Id
e.Pid = r.Pid e.Pid = r.Pid
e.Height = int(r.Height) e.Height = int(r.Height)
e.Width = int(r.Width) e.Width = int(r.Width)
e.CloseStdin = r.CloseStdin e.CloseStdin = r.CloseStdin
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }
@ -272,37 +272,25 @@ func (s *apiServer) UpdateProcess(ctx context.Context, r *types.UpdateProcessReq
func (s *apiServer) Events(r *types.EventsRequest, stream types.API_EventsServer) error { func (s *apiServer) Events(r *types.EventsRequest, stream types.API_EventsServer) error {
events := s.sv.Events() events := s.sv.Events()
defer s.sv.Unsubscribe(events) defer s.sv.Unsubscribe(events)
for evt := range events { for e := range events {
var ev *types.Event if err := stream.Send(&types.Event{
switch evt.Type { Id: e.ID,
case supervisor.ExitEventType, supervisor.ExecExitEventType: Type: e.Type,
ev = &types.Event{ Timestamp: uint64(e.Timestamp.Unix()),
Type: "exit", Pid: e.Pid,
Id: evt.ID, Status: uint32(e.Status),
Pid: evt.Pid, }); err != nil {
Status: uint32(evt.Status), return err
}
case supervisor.OOMEventType:
ev = &types.Event{
Type: "oom",
Id: evt.ID,
}
} }
if ev != nil {
if err := stream.Send(ev); err != nil {
return err
}
}
} }
return nil return nil
} }
func (s *apiServer) Stats(ctx context.Context, r *types.StatsRequest) (*types.StatsResponse, error) { func (s *apiServer) Stats(ctx context.Context, r *types.StatsRequest) (*types.StatsResponse, error) {
e := supervisor.NewEvent(supervisor.StatsEventType) e := supervisor.NewTask(supervisor.StatsTaskType)
e.ID = r.Id e.ID = r.Id
e.Stat = make(chan *runtime.Stat, 1) e.Stat = make(chan *runtime.Stat, 1)
s.sv.SendEvent(e) s.sv.SendTask(e)
if err := <-e.Err; err != nil { if err := <-e.Err; err != nil {
return nil, err return nil, err
} }

View file

@ -389,15 +389,11 @@ func (*EventsRequest) ProtoMessage() {}
func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
type Event struct { type Event struct {
Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"`
Status uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"` Status uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"`
BundlePath string `protobuf:"bytes,4,opt,name=bundlePath" json:"bundlePath,omitempty"` Pid string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"`
Pid string `protobuf:"bytes,5,opt,name=pid" json:"pid,omitempty"` Timestamp uint64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"`
Signal uint32 `protobuf:"varint,7,opt,name=signal" json:"signal,omitempty"`
Process *Process `protobuf:"bytes,8,opt,name=process" json:"process,omitempty"`
Containers []*Container `protobuf:"bytes,9,rep,name=containers" json:"containers,omitempty"`
Checkpoint *Checkpoint `protobuf:"bytes,10,opt,name=checkpoint" json:"checkpoint,omitempty"`
} }
func (m *Event) Reset() { *m = Event{} } func (m *Event) Reset() { *m = Event{} }
@ -405,27 +401,6 @@ func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {} func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} }
func (m *Event) GetProcess() *Process {
if m != nil {
return m.Process
}
return nil
}
func (m *Event) GetContainers() []*Container {
if m != nil {
return m.Containers
}
return nil
}
func (m *Event) GetCheckpoint() *Checkpoint {
if m != nil {
return m.Checkpoint
}
return nil
}
type NetworkStats struct { type NetworkStats struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
RxBytes uint64 `protobuf:"varint,2,opt,name=rx_bytes" json:"rx_bytes,omitempty"` RxBytes uint64 `protobuf:"varint,2,opt,name=rx_bytes" json:"rx_bytes,omitempty"`
@ -1118,102 +1093,100 @@ var _API_serviceDesc = grpc.ServiceDesc{
} }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 1542 bytes of a gzipped FileDescriptorProto // 1517 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x58, 0xd9, 0x6e, 0x1c, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x58, 0xd9, 0x6e, 0x1c, 0x45,
0x17, 0xf6, 0xec, 0x33, 0x67, 0x16, 0xdb, 0xed, 0x6d, 0x3c, 0xf9, 0xf3, 0xc7, 0x74, 0x02, 0x89, 0x17, 0xf6, 0xec, 0x33, 0x67, 0x16, 0xdb, 0xed, 0x6d, 0x3c, 0xf9, 0xf3, 0xc7, 0x74, 0x02, 0x89,
0x50, 0x64, 0x05, 0x87, 0x25, 0x04, 0x09, 0x08, 0x4e, 0x44, 0x40, 0x09, 0x58, 0xb1, 0x8d, 0xc4, 0x50, 0x64, 0x05, 0x87, 0x25, 0x04, 0x09, 0x08, 0x4e, 0x44, 0x40, 0x09, 0x98, 0xd8, 0x46, 0xe2,
0x0d, 0xa3, 0x9e, 0xee, 0x62, 0xa6, 0x71, 0x6f, 0x74, 0x55, 0x7b, 0x79, 0x85, 0x70, 0xcf, 0x5b, 0x86, 0x51, 0x4f, 0x77, 0x31, 0xd3, 0xb8, 0x37, 0xba, 0xaa, 0xbd, 0xbc, 0x42, 0xb8, 0xe7, 0x2d,
0x20, 0x71, 0xc5, 0x03, 0xf0, 0x04, 0x3c, 0x07, 0x4f, 0xc1, 0xa9, 0xa5, 0x6b, 0xba, 0x7b, 0x16, 0x90, 0xb8, 0xe2, 0x01, 0x78, 0x1c, 0x9e, 0x82, 0xd3, 0xb5, 0x4d, 0x77, 0xcf, 0x62, 0x72, 0xc1,
0x93, 0x0b, 0x6e, 0x46, 0xaa, 0xaa, 0xb3, 0x7c, 0xe7, 0x3b, 0x4b, 0x57, 0x0d, 0xb4, 0xac, 0xc8, 0xcd, 0x48, 0x55, 0x75, 0xce, 0x77, 0xbe, 0xb3, 0x55, 0xf5, 0x19, 0x68, 0x59, 0x91, 0xbb, 0x1f,
0xdd, 0x8f, 0xe2, 0x90, 0x85, 0x46, 0x8d, 0x5d, 0x45, 0x84, 0x9a, 0x23, 0xd8, 0x3c, 0x8d, 0x1c, 0xc5, 0x21, 0x0b, 0x8d, 0x1a, 0xbb, 0x8a, 0x08, 0x35, 0x47, 0xb0, 0x79, 0x1a, 0x39, 0x16, 0x23,
0x8b, 0x91, 0xa3, 0x38, 0xb4, 0x09, 0xa5, 0xaf, 0xc8, 0xcf, 0x09, 0xa1, 0xcc, 0x00, 0x28, 0xbb, 0x47, 0x71, 0x68, 0x13, 0x4a, 0x5f, 0x91, 0x5f, 0x12, 0x42, 0x99, 0x01, 0x50, 0x76, 0x9d, 0x7e,
0x4e, 0xbf, 0xb4, 0x57, 0xba, 0xd7, 0x32, 0xda, 0x50, 0x89, 0x70, 0x51, 0x16, 0x0b, 0x3c, 0xb1, 0x69, 0xaf, 0x74, 0xaf, 0x65, 0xb4, 0xa1, 0x12, 0xe1, 0xa2, 0xcc, 0x17, 0x78, 0x62, 0x7b, 0x21,
0xbd, 0x90, 0x92, 0x63, 0xe6, 0xb8, 0x41, 0xbf, 0x82, 0x7b, 0x4d, 0xa3, 0x0b, 0xb5, 0x0b, 0xd7, 0x25, 0xc7, 0xcc, 0x71, 0x83, 0x7e, 0x05, 0xf7, 0x9a, 0x46, 0x17, 0x6a, 0x17, 0xae, 0xc3, 0x26,
0x61, 0x93, 0x7e, 0x15, 0x97, 0x5d, 0xa3, 0x07, 0xf5, 0x09, 0x71, 0xc7, 0x13, 0xd6, 0xaf, 0xf1, 0xfd, 0x2a, 0x2e, 0xbb, 0x46, 0x0f, 0xea, 0x13, 0xe2, 0x8e, 0x27, 0xac, 0x5f, 0x4b, 0xd7, 0xe6,
0xb5, 0xb9, 0x03, 0x5b, 0x05, 0x1f, 0x34, 0x0a, 0x03, 0x4a, 0xcc, 0x5f, 0x4a, 0xb0, 0x7d, 0x18, 0x0e, 0x6c, 0x15, 0x6c, 0xd0, 0x28, 0x0c, 0x28, 0x31, 0x7f, 0x2d, 0xc1, 0xf6, 0x61, 0x4c, 0xf0,
0x13, 0x3c, 0x39, 0x0c, 0x03, 0x66, 0xb9, 0x01, 0x89, 0xe7, 0xf9, 0xc7, 0xc5, 0x28, 0x09, 0x1c, 0xe4, 0x30, 0x0c, 0x98, 0xe5, 0x06, 0x24, 0x9e, 0x67, 0x1f, 0x17, 0xa3, 0x24, 0x70, 0x3c, 0x72,
0x8f, 0x1c, 0x59, 0xe8, 0x63, 0x0a, 0x63, 0x42, 0xec, 0xb3, 0x28, 0x74, 0x03, 0x26, 0x60, 0xb4, 0x64, 0xa1, 0x8d, 0x29, 0x8d, 0x09, 0xb1, 0xcf, 0xa2, 0xd0, 0x0d, 0x18, 0xa7, 0xd1, 0x4a, 0x69,
0x38, 0x0c, 0x2a, 0x50, 0x55, 0xc5, 0x12, 0x61, 0xe0, 0x32, 0x4c, 0x24, 0x8c, 0x74, 0x4d, 0xe2, 0x50, 0xce, 0xaa, 0xca, 0x97, 0x48, 0x03, 0x97, 0x61, 0x22, 0x68, 0xa8, 0x35, 0x89, 0xe3, 0x7e,
0xb8, 0x5f, 0x4f, 0xd7, 0x9e, 0x35, 0x22, 0x1e, 0xed, 0x37, 0xf6, 0x2a, 0xf7, 0x5a, 0xe6, 0xa7, 0x5d, 0xad, 0x3d, 0x6b, 0x44, 0x3c, 0xda, 0x6f, 0xec, 0x55, 0xee, 0xb5, 0xcc, 0x4f, 0x61, 0x67,
0xb0, 0x33, 0x03, 0x46, 0x02, 0x35, 0x6e, 0x43, 0xcb, 0x4e, 0x37, 0x05, 0xa8, 0xf6, 0xc1, 0xda, 0x86, 0x8c, 0x20, 0x6a, 0xdc, 0x86, 0x96, 0xad, 0x36, 0x39, 0xa9, 0xf6, 0xc1, 0xda, 0x3e, 0x0f,
0xbe, 0x20, 0x70, 0x5f, 0x0b, 0x9b, 0x8f, 0xa0, 0x7b, 0xec, 0x8e, 0x03, 0xcb, 0xbb, 0x96, 0x43, 0xe0, 0xbe, 0x16, 0x36, 0x1f, 0x41, 0xf7, 0xd8, 0x1d, 0x07, 0x96, 0x77, 0x6d, 0x0c, 0x53, 0x26,
0x8e, 0x44, 0x48, 0x0a, 0xe0, 0x5d, 0x73, 0x0d, 0x7a, 0xa9, 0xa6, 0x62, 0xe6, 0xf7, 0x12, 0xac, 0x5c, 0x92, 0x13, 0xef, 0x9a, 0x6b, 0xd0, 0x53, 0x9a, 0x32, 0x32, 0x7f, 0x94, 0x60, 0xfd, 0x89,
0x3f, 0x71, 0x9c, 0x25, 0x49, 0x59, 0x83, 0x26, 0x23, 0xb1, 0xef, 0x72, 0x2b, 0x65, 0x91, 0x85, 0xe3, 0x2c, 0x49, 0xca, 0x1a, 0x34, 0x19, 0x89, 0x7d, 0x37, 0x45, 0x29, 0xf3, 0x2c, 0xec, 0x42,
0x5d, 0xa8, 0x26, 0x14, 0xf1, 0x55, 0x04, 0xbe, 0xb6, 0xc2, 0x77, 0x8a, 0x5b, 0x46, 0x07, 0xaa, 0x35, 0xa1, 0xc8, 0xaf, 0xc2, 0xf9, 0xb5, 0x25, 0xbf, 0x53, 0xdc, 0x32, 0x3a, 0x50, 0xb5, 0xe2,
0x56, 0x3c, 0xa6, 0x48, 0x4c, 0x45, 0x62, 0x21, 0xc1, 0x39, 0xb2, 0xa2, 0x16, 0xf6, 0x85, 0xa3, 0x31, 0xc5, 0xc0, 0x54, 0x04, 0x17, 0x12, 0x9c, 0x63, 0x54, 0xe4, 0xc2, 0xbe, 0x70, 0x64, 0x48,
0x28, 0x51, 0x28, 0x1b, 0x79, 0x3a, 0x9b, 0x05, 0x3a, 0x5b, 0x05, 0x3a, 0x81, 0xaf, 0x31, 0xfc, 0x24, 0xcb, 0x46, 0x3e, 0x9c, 0xcd, 0x42, 0x38, 0x5b, 0x85, 0x70, 0x42, 0xba, 0x46, 0xf7, 0xab,
0xaa, 0xf0, 0x85, 0x36, 0x12, 0x85, 0xb2, 0xcb, 0x17, 0x63, 0x15, 0x76, 0xd7, 0xd8, 0x86, 0x9e, 0xdc, 0x16, 0x62, 0x24, 0x92, 0x65, 0x37, 0x5d, 0x8c, 0xa5, 0xdb, 0x5d, 0x63, 0x1b, 0x7a, 0x96,
0xe5, 0x38, 0x2e, 0x73, 0x43, 0x04, 0xfd, 0xa5, 0xeb, 0x50, 0x84, 0x5a, 0xc1, 0xf0, 0x37, 0xc1, 0xe3, 0xb8, 0xcc, 0x0d, 0x91, 0xf4, 0x97, 0xae, 0x43, 0x91, 0x6a, 0x05, 0xdd, 0xdf, 0x04, 0x23,
0xc8, 0xc6, 0xaa, 0x28, 0x78, 0xa1, 0xd3, 0xa1, 0xf3, 0x3c, 0x8f, 0x87, 0xb7, 0x73, 0x85, 0x50, 0xeb, 0xab, 0x0c, 0xc1, 0x0b, 0x9d, 0x0e, 0x9d, 0xe7, 0x79, 0x71, 0x78, 0x3b, 0x57, 0x08, 0x65,
0x16, 0xb1, 0xaf, 0xa7, 0xb9, 0xd1, 0x07, 0xe6, 0x00, 0xfa, 0xb3, 0xd6, 0x94, 0xa7, 0x87, 0xb0, 0xee, 0xfb, 0xba, 0xca, 0x8d, 0x3e, 0x30, 0x07, 0xd0, 0x9f, 0x45, 0x93, 0x96, 0x1e, 0xc2, 0xce,
0xf3, 0x94, 0x78, 0xe4, 0x3a, 0x4f, 0x48, 0x62, 0x60, 0xf9, 0x44, 0xe6, 0x90, 0x1b, 0x9c, 0x55, 0x53, 0xe2, 0x91, 0xeb, 0x2c, 0x61, 0x10, 0x03, 0xcb, 0x27, 0x22, 0x87, 0x29, 0xe0, 0xac, 0x92,
0x52, 0x06, 0x6f, 0xc3, 0xd6, 0x0b, 0x97, 0xb2, 0xa5, 0xe6, 0xcc, 0xef, 0x01, 0xa6, 0x02, 0xda, 0x04, 0xbc, 0x0d, 0x5b, 0x2f, 0x5c, 0xca, 0x96, 0xc2, 0x99, 0x3f, 0x00, 0x4c, 0x05, 0x34, 0xb8,
0xb8, 0x76, 0x45, 0x2e, 0x5d, 0xa6, 0x12, 0x8b, 0x24, 0x32, 0x3b, 0x52, 0xbd, 0xb6, 0x01, 0xed, 0x36, 0x45, 0x2e, 0x5d, 0x26, 0x13, 0x8b, 0x41, 0x64, 0x76, 0x24, 0x7b, 0x6d, 0x03, 0xda, 0x49,
0x24, 0x70, 0x2f, 0x8f, 0x43, 0xfb, 0x8c, 0x30, 0x2a, 0x4a, 0x5d, 0x34, 0x20, 0x9d, 0x10, 0xcf, 0xe0, 0x5e, 0x1e, 0x87, 0xf6, 0x19, 0x61, 0x94, 0x97, 0x3a, 0x6f, 0x40, 0x3a, 0x21, 0x9e, 0xc7,
0x13, 0x95, 0xde, 0x34, 0x3f, 0x87, 0xed, 0xa2, 0x7f, 0x55, 0xc8, 0xef, 0x40, 0x7b, 0xca, 0x16, 0x2b, 0xbd, 0x69, 0x7e, 0x0e, 0xdb, 0x45, 0xfb, 0xb2, 0x90, 0xdf, 0x81, 0xf6, 0x34, 0x5a, 0x14,
0x45, 0x6f, 0x95, 0x45, 0x74, 0x75, 0x8e, 0x19, 0xb2, 0x35, 0x0f, 0xf8, 0x1e, 0xf4, 0x74, 0xd1, 0xad, 0x55, 0x16, 0x85, 0xab, 0x73, 0xcc, 0x30, 0x5a, 0xf3, 0x88, 0xef, 0x41, 0x4f, 0x17, 0x3d,
0x0b, 0x21, 0x59, 0x0a, 0x16, 0x4b, 0xa8, 0x92, 0xf8, 0xad, 0x04, 0x0d, 0x95, 0xce, 0xb4, 0xa4, 0x17, 0x12, 0xa5, 0x60, 0xb1, 0x84, 0x4a, 0x89, 0xdf, 0x4b, 0xd0, 0x90, 0xe9, 0x54, 0x25, 0xf5,
0xfe, 0xc3, 0xa2, 0x5d, 0x87, 0x16, 0xbd, 0xa2, 0x8c, 0xf8, 0x47, 0xaa, 0x74, 0xbb, 0x6f, 0x5a, 0x1f, 0x16, 0xed, 0x3a, 0xb4, 0xe8, 0x15, 0x65, 0xc4, 0x3f, 0x92, 0xa5, 0xdb, 0x7d, 0xd3, 0xd2,
0xba, 0xaf, 0x4b, 0xd0, 0xd2, 0x21, 0x2d, 0xce, 0x79, 0x61, 0x10, 0xc9, 0xa1, 0xf3, 0x16, 0xb4, 0x7d, 0x5d, 0x82, 0x96, 0x76, 0x69, 0x71, 0xce, 0x0b, 0x17, 0x91, 0xb8, 0x74, 0xde, 0x82, 0x56,
0x22, 0x19, 0x2a, 0x91, 0x50, 0xdb, 0x07, 0x3d, 0x15, 0x45, 0x4a, 0xc1, 0x94, 0x9e, 0x5a, 0x61, 0x24, 0x5c, 0x25, 0x82, 0x6a, 0xfb, 0xa0, 0x27, 0xbd, 0x50, 0x21, 0x98, 0x86, 0xa7, 0x56, 0xb8,
0xf0, 0xd4, 0x45, 0x34, 0xe8, 0x24, 0xe2, 0xdd, 0xd0, 0x10, 0xdd, 0x70, 0x17, 0x1a, 0x2f, 0x2d, 0x78, 0xea, 0xdc, 0x1b, 0x34, 0x12, 0xa5, 0xdd, 0xd0, 0xe0, 0xdd, 0x70, 0x17, 0x1a, 0x2f, 0x2d,
0x7b, 0x82, 0x50, 0xf8, 0x81, 0x1d, 0x29, 0x56, 0xc5, 0x58, 0xf5, 0x89, 0x1f, 0xc6, 0x57, 0x02, 0x7b, 0x82, 0x54, 0xd2, 0x03, 0x3b, 0x92, 0x51, 0xe5, 0xd7, 0xaa, 0x4f, 0xfc, 0x30, 0xbe, 0xe2,
0x4d, 0xd5, 0xfc, 0x0e, 0xe7, 0x8d, 0xcc, 0x91, 0x4a, 0xee, 0x1d, 0x6c, 0x85, 0x34, 0x8a, 0x34, 0x6c, 0xaa, 0xe6, 0xf7, 0x78, 0xdf, 0x88, 0x1c, 0xc9, 0xe4, 0xde, 0xc1, 0x56, 0x50, 0x5e, 0xa8,
0xb7, 0x33, 0x63, 0xca, 0xb8, 0x05, 0x0d, 0x5f, 0xda, 0x57, 0xdd, 0x92, 0xc2, 0x55, 0x5e, 0xcd, 0xdc, 0xce, 0x5c, 0x53, 0xc6, 0x2d, 0x68, 0xf8, 0x02, 0x5f, 0x76, 0x8b, 0xa2, 0x2b, 0xad, 0x9a,
0x27, 0xb0, 0x2d, 0xc7, 0xf5, 0xd2, 0xa1, 0x3c, 0x33, 0xd0, 0x64, 0x84, 0x82, 0x14, 0x73, 0x17, 0x4f, 0x60, 0x5b, 0x5c, 0xd7, 0x4b, 0x2f, 0xe5, 0x99, 0x0b, 0x4d, 0x78, 0xc8, 0x83, 0x62, 0xee,
0x76, 0x66, 0x4c, 0xa8, 0xde, 0x58, 0x85, 0xee, 0xb3, 0x73, 0x82, 0xc5, 0xa7, 0x8c, 0x9a, 0x7f, 0xc2, 0xce, 0x0c, 0x84, 0xec, 0x8d, 0x55, 0xe8, 0x3e, 0x3b, 0x27, 0x58, 0x7c, 0x12, 0xd4, 0xfc,
0x95, 0xa0, 0x26, 0x76, 0x78, 0xb8, 0x1c, 0x89, 0x72, 0x20, 0x9d, 0xcd, 0xb3, 0xdf, 0x2d, 0x24, 0x0e, 0x6a, 0x7c, 0x23, 0xf5, 0x36, 0x25, 0x22, 0xf1, 0x85, 0xad, 0x79, 0xf0, 0x5d, 0x65, 0xbb,
0xa2, 0x9a, 0x05, 0x54, 0x2b, 0x4c, 0x58, 0x59, 0x10, 0x18, 0xb4, 0xca, 0x92, 0x28, 0x89, 0xd9, 0xaa, 0xd2, 0xcf, 0x5c, 0x1f, 0x91, 0x2c, 0x3f, 0xe2, 0x01, 0xae, 0x9a, 0x7f, 0x96, 0xa0, 0xf3,
0x1c, 0xe5, 0xb9, 0x6b, 0x2d, 0xe0, 0x2e, 0x3f, 0x6c, 0x60, 0xd1, 0xb0, 0xf9, 0xa3, 0x04, 0x9d, 0x0d, 0x61, 0x17, 0x61, 0x7c, 0x96, 0x46, 0x88, 0x16, 0xba, 0x0b, 0xab, 0x30, 0xbe, 0x1c, 0x8e,
0x6f, 0x08, 0xbb, 0x08, 0xe3, 0x33, 0x9e, 0x21, 0x5a, 0xe8, 0x6e, 0xec, 0x82, 0xf8, 0x72, 0x38, 0xae, 0x18, 0x66, 0x8c, 0x87, 0x32, 0x4d, 0x2c, 0xee, 0x1c, 0x59, 0xa2, 0xa7, 0x2a, 0x7c, 0x0f,
0xba, 0x62, 0x58, 0x31, 0x22, 0x95, 0x3c, 0x1e, 0xdc, 0x39, 0xb2, 0x64, 0x4f, 0x57, 0xc4, 0x1e, 0x71, 0x5f, 0x5d, 0x0e, 0xb1, 0x48, 0xc2, 0x58, 0xb4, 0x19, 0x17, 0xc3, 0x2d, 0x27, 0x0e, 0xa3,
0x96, 0xf5, 0xab, 0xcb, 0x21, 0x16, 0x69, 0x18, 0xcb, 0x36, 0x17, 0x62, 0xb8, 0xe5, 0xc4, 0x61, 0x88, 0x38, 0xc2, 0x56, 0x0a, 0x76, 0xa2, 0xc0, 0xea, 0x4a, 0x0a, 0x77, 0x22, 0x09, 0xd6, 0x50,
0x14, 0x11, 0x19, 0x69, 0x95, 0x1b, 0x3b, 0x49, 0x8d, 0xd5, 0x53, 0x29, 0xdc, 0x89, 0x94, 0xb1, 0x60, 0x27, 0x1a, 0xac, 0x99, 0x11, 0x53, 0x60, 0x2d, 0x4e, 0xdc, 0x87, 0xe6, 0x61, 0x94, 0x9c,
0x46, 0x6a, 0xec, 0x44, 0x1b, 0x6b, 0x66, 0xc4, 0x52, 0x63, 0x2d, 0x51, 0x52, 0x3e, 0x34, 0x0f, 0x52, 0x6b, 0x4c, 0xd2, 0x46, 0x67, 0x21, 0xb3, 0xbc, 0x61, 0x92, 0x2e, 0x39, 0xf5, 0xaa, 0xb1,
0xa3, 0xe4, 0x94, 0x5a, 0x63, 0xc2, 0x07, 0x0d, 0x0b, 0x99, 0xe5, 0x0d, 0x13, 0xbe, 0x14, 0xd0, 0x09, 0x9d, 0x88, 0xc4, 0x58, 0x14, 0x72, 0xb7, 0x8c, 0x49, 0xae, 0x1a, 0x37, 0x60, 0x83, 0x2f,
0xab, 0xc6, 0x26, 0x74, 0x22, 0x12, 0x63, 0x51, 0xaa, 0xdd, 0x32, 0x12, 0x55, 0x35, 0x6e, 0xc0, 0x87, 0x6e, 0x30, 0x3c, 0x23, 0x71, 0x40, 0x3c, 0x3f, 0x74, 0x88, 0xf4, 0x63, 0x17, 0xd6, 0xf5,
0x86, 0x58, 0x0e, 0xdd, 0x60, 0x78, 0x46, 0xe2, 0x80, 0x78, 0x7e, 0xe8, 0x10, 0x15, 0xc7, 0x2e, 0x61, 0xda, 0x6a, 0xfc, 0x88, 0xfb, 0x63, 0x9e, 0x40, 0xef, 0x64, 0x82, 0x5f, 0x03, 0xcc, 0x73,
0xac, 0xeb, 0x43, 0xde, 0xea, 0xe2, 0x48, 0xc4, 0x63, 0x9e, 0x40, 0xef, 0x64, 0x82, 0xb7, 0x11, 0x83, 0xf1, 0x53, 0x8b, 0x59, 0xc6, 0x2a, 0x34, 0x10, 0xdf, 0x0d, 0x1d, 0x2a, 0x0d, 0xa2, 0x36,
0xe6, 0xb9, 0xc1, 0xf8, 0xa9, 0xc5, 0x2c, 0x63, 0x15, 0xf3, 0x44, 0x62, 0x37, 0x74, 0xa8, 0x72, 0x13, 0x22, 0xc4, 0x19, 0xaa, 0x23, 0x11, 0x34, 0xbc, 0xce, 0xa7, 0x47, 0x69, 0x0a, 0x84, 0x41,
0x88, 0xda, 0x4c, 0x8a, 0x10, 0x67, 0x98, 0x1e, 0x49, 0xd2, 0xf0, 0x73, 0x32, 0x3d, 0x62, 0xae, 0xf3, 0x47, 0xee, 0x84, 0x08, 0xbc, 0x89, 0x0f, 0xa7, 0x26, 0x2b, 0x1e, 0xce, 0x55, 0x55, 0x91,
0xaf, 0x1c, 0x9a, 0x3f, 0x88, 0x20, 0x24, 0xf1, 0x26, 0x7e, 0xb8, 0x35, 0x58, 0xf9, 0xe1, 0x5e, 0xca, 0xd1, 0x7d, 0x58, 0x65, 0x9a, 0xc5, 0x10, 0xab, 0xc6, 0x92, 0x85, 0xb9, 0x25, 0x25, 0xf3,
0x4d, 0xf3, 0x95, 0x06, 0xba, 0x0f, 0xab, 0x4c, 0xa3, 0x18, 0x62, 0xd5, 0x5a, 0xaa, 0x31, 0xb6, 0x1c, 0xcd, 0xcf, 0x00, 0x5e, 0xf2, 0x3e, 0xe0, 0x8c, 0xb1, 0xd5, 0xb3, 0x01, 0xc2, 0x40, 0xfb,
0x94, 0x64, 0x1e, 0xa3, 0xf9, 0x19, 0xc0, 0x4b, 0xd1, 0x87, 0x02, 0x31, 0x8e, 0x9a, 0x2c, 0x41, 0xd6, 0xa5, 0x8e, 0x4e, 0xba, 0x85, 0x3e, 0xfd, 0x64, 0xb9, 0x9e, 0x2d, 0xbf, 0x13, 0xaa, 0xe6,
0x48, 0xb4, 0x6f, 0x5d, 0x6a, 0x76, 0xf8, 0x16, 0xc6, 0xf4, 0xa3, 0xe5, 0x7a, 0xb6, 0xba, 0xa7, 0xdf, 0x25, 0x68, 0x0b, 0x04, 0x41, 0x12, 0x21, 0x6c, 0xac, 0x7d, 0x05, 0xb1, 0xa7, 0x10, 0xf3,
0x54, 0xcd, 0xbf, 0x4b, 0xd0, 0x96, 0x16, 0x24, 0x48, 0x34, 0x61, 0x63, 0xef, 0xa5, 0x26, 0xf6, 0x8f, 0x49, 0xc6, 0x26, 0xbe, 0x39, 0xf4, 0xc2, 0x8a, 0xa4, 0x95, 0xca, 0x22, 0xb1, 0xbb, 0xd0,
0x52, 0x8b, 0xf9, 0x8f, 0x59, 0xc6, 0x27, 0x96, 0x21, 0xbd, 0xb0, 0x22, 0xe5, 0xa5, 0xb2, 0x48, 0x11, 0xd9, 0x90, 0x82, 0xd5, 0x45, 0x82, 0xf7, 0xd3, 0xeb, 0x0a, 0x99, 0xf0, 0xdb, 0xad, 0x7d,
0xec, 0x2e, 0x74, 0x64, 0x36, 0x94, 0x60, 0x75, 0x91, 0xe0, 0x7d, 0x3e, 0x2e, 0x11, 0x89, 0x98, 0x70, 0x33, 0x27, 0xc1, 0x39, 0xee, 0xf3, 0xdf, 0x67, 0x01, 0x8b, 0xaf, 0x06, 0xf7, 0x01, 0xa6,
0xae, 0xed, 0x83, 0x9b, 0x39, 0x09, 0x81, 0x71, 0x5f, 0xfc, 0x3e, 0x0b, 0x58, 0x7c, 0x35, 0xb8, 0xab, 0xb4, 0x17, 0xce, 0xc8, 0x95, 0xac, 0x6c, 0xf4, 0xe4, 0xdc, 0xf2, 0x12, 0xe9, 0xf9, 0xe3,
0x0f, 0x30, 0x5d, 0xf1, 0xb6, 0x3b, 0x23, 0x57, 0xaa, 0xb2, 0x31, 0x92, 0x73, 0xcb, 0x4b, 0x54, 0xf2, 0xa3, 0x92, 0xf9, 0x35, 0xac, 0x7e, 0xe1, 0x9d, 0xb9, 0x61, 0x46, 0x05, 0xa5, 0x7c, 0xeb,
0xe4, 0x8f, 0xcb, 0x8f, 0x4a, 0xe6, 0xd7, 0xb0, 0xfa, 0x85, 0x77, 0xe6, 0x86, 0x19, 0x15, 0x94, 0xe7, 0x30, 0x96, 0xfe, 0xa6, 0x4b, 0x37, 0xc0, 0xa5, 0x08, 0x17, 0x36, 0x5e, 0x18, 0x4d, 0xbf,
0xf2, 0xad, 0x9f, 0xc2, 0x58, 0xc5, 0xcb, 0x97, 0x6e, 0x80, 0x4b, 0x49, 0x17, 0xf6, 0x7d, 0x18, 0xa8, 0x04, 0x9e, 0xa8, 0x97, 0xbf, 0x2a, 0x00, 0x53, 0x30, 0xe3, 0x31, 0x0c, 0xdc, 0x70, 0x88,
0x4d, 0x6f, 0x74, 0xd2, 0x9e, 0xac, 0x97, 0x3f, 0x2b, 0x00, 0x53, 0x63, 0xc6, 0x63, 0x18, 0xb8, 0x25, 0x75, 0xee, 0xda, 0x44, 0xb4, 0xc0, 0x30, 0x26, 0x76, 0x12, 0x53, 0xf7, 0x9c, 0xc8, 0xfb,
0xe1, 0x10, 0x4b, 0xea, 0xdc, 0xb5, 0x89, 0x6c, 0x81, 0x61, 0x4c, 0xec, 0x24, 0xa6, 0xee, 0x39, 0x67, 0x5b, 0xfa, 0x52, 0xe4, 0xf0, 0x01, 0x6c, 0x4d, 0x75, 0x9d, 0x8c, 0x5a, 0x79, 0xa9, 0xda,
0x51, 0xf3, 0x6f, 0x5b, 0xc5, 0x52, 0xc4, 0xf0, 0x01, 0x6c, 0x4d, 0x75, 0x9d, 0x8c, 0x5a, 0x79, 0x43, 0xd8, 0x40, 0x35, 0xbc, 0x38, 0x92, 0x9c, 0x52, 0x65, 0xa9, 0xd2, 0xc7, 0xb0, 0x9b, 0xe1,
0xa9, 0xda, 0x43, 0xd8, 0x40, 0x35, 0x1c, 0x5c, 0x49, 0x4e, 0xa9, 0xb2, 0x54, 0xe9, 0x63, 0xd8, 0x99, 0x56, 0x6a, 0x46, 0xb5, 0xba, 0x54, 0xf5, 0x43, 0xd8, 0x46, 0xd5, 0x0b, 0xcb, 0x65, 0x45,
0xcd, 0xe0, 0xe4, 0x95, 0x9a, 0x51, 0xad, 0x2e, 0x55, 0xfd, 0x10, 0xb6, 0x51, 0xf5, 0xc2, 0x72, 0xbd, 0xda, 0xbf, 0xe0, 0xe9, 0x93, 0x78, 0x9c, 0xe3, 0x59, 0x5f, 0xaa, 0xf4, 0x1e, 0xac, 0xa3,
0x59, 0x51, 0xaf, 0xf6, 0x2f, 0x70, 0xfa, 0x24, 0x1e, 0xe7, 0x70, 0xd6, 0x97, 0x2a, 0xbd, 0x07, 0x52, 0xc1, 0x4e, 0xe3, 0x3a, 0x15, 0x4a, 0x6c, 0x86, 0xb7, 0x4a, 0x46, 0xa5, 0xb9, 0x4c, 0x05,
0xeb, 0xa8, 0x54, 0xf0, 0xd3, 0xb8, 0x4e, 0x85, 0x12, 0x9b, 0xe1, 0x54, 0xc9, 0xa8, 0x34, 0x97, 0xaf, 0xf7, 0xce, 0xf3, 0x64, 0x4c, 0x98, 0x37, 0xd2, 0xd5, 0xff, 0xa6, 0x0d, 0xf4, 0xba, 0x0c,
0xa9, 0xe0, 0xe7, 0xa5, 0xf3, 0x3c, 0x19, 0x13, 0xe6, 0x8d, 0x74, 0xf5, 0xbf, 0x69, 0x03, 0xbd, 0xed, 0xc3, 0x71, 0x1c, 0x26, 0x51, 0xae, 0xcb, 0x45, 0x0d, 0xcf, 0x74, 0xb9, 0x90, 0xb9, 0x07,
0x2e, 0x43, 0xfb, 0x70, 0x1c, 0x87, 0x49, 0x94, 0xeb, 0x72, 0x59, 0xc3, 0x33, 0x5d, 0x2e, 0x65, 0x1d, 0xf1, 0x7a, 0x49, 0x31, 0xd1, 0x5c, 0xc6, 0x6c, 0xa9, 0xa7, 0xdf, 0x28, 0xa3, 0x94, 0xb3,
0xee, 0x41, 0x47, 0x7e, 0x3d, 0x95, 0x98, 0x6c, 0x2e, 0x63, 0xb6, 0xd4, 0xf9, 0x1d, 0x69, 0xc4, 0x14, 0xcc, 0xb7, 0x57, 0xa6, 0xfc, 0x3e, 0x81, 0xee, 0x44, 0x38, 0x22, 0x25, 0x45, 0x2a, 0xef,
0x31, 0x2b, 0xc1, 0x7c, 0x7b, 0x65, 0xca, 0xef, 0x13, 0xe8, 0x4e, 0x64, 0x20, 0x4a, 0x52, 0xa6, 0x28, 0xcb, 0x53, 0x82, 0xfb, 0x59, 0x87, 0x45, 0x13, 0x3d, 0x87, 0xf5, 0x99, 0xcd, 0x7c, 0x2f,
0xf2, 0x4e, 0xea, 0x79, 0x0a, 0x70, 0x3f, 0x1b, 0xb0, 0x6c, 0xa2, 0xe7, 0xb0, 0x3e, 0xb3, 0x99, 0x99, 0xd9, 0x5e, 0x6a, 0x1f, 0x6c, 0x48, 0xd8, 0xac, 0x16, 0x6f, 0xb0, 0x4b, 0xf1, 0x0c, 0xeb,
0xef, 0x25, 0x33, 0xdb, 0x4b, 0xed, 0x83, 0x0d, 0x65, 0x36, 0xab, 0x25, 0x1a, 0xec, 0x52, 0x5e, 0x0f, 0x57, 0xe3, 0x5d, 0xe8, 0x06, 0xe2, 0xf1, 0xd1, 0x11, 0xa9, 0x64, 0x00, 0x72, 0x0f, 0x13,
0x03, 0xf4, 0xc5, 0xd9, 0x78, 0x17, 0xba, 0x81, 0xfc, 0xf8, 0x68, 0x46, 0x2a, 0x19, 0x03, 0xb9, 0x46, 0xc5, 0xe6, 0x3c, 0xe7, 0x46, 0x25, 0x1b, 0xe3, 0xdc, 0x33, 0x27, 0xd2, 0x20, 0x3f, 0xd2,
0x0f, 0x13, 0xb2, 0x62, 0x0b, 0x9c, 0x73, 0x59, 0xc9, 0x72, 0x8c, 0x79, 0xe1, 0x95, 0x81, 0x62, 0xe6, 0x8d, 0x07, 0x07, 0xbf, 0xd5, 0xa1, 0xf2, 0xe4, 0xe8, 0x2b, 0xe3, 0x15, 0xac, 0x16, 0x86,
0x7e, 0xa4, 0xd2, 0xa0, 0x2e, 0x89, 0xf3, 0x9e, 0x27, 0x07, 0xbf, 0xd6, 0xa1, 0xf2, 0xe4, 0xe8, 0x1a, 0x43, 0x5d, 0x2f, 0xf3, 0x27, 0xaf, 0xc1, 0xff, 0x17, 0x1d, 0xcb, 0x07, 0x7c, 0x25, 0xc5,
0x2b, 0xe3, 0x15, 0xac, 0x16, 0x1e, 0x55, 0x46, 0x3a, 0x5e, 0xe6, 0xbf, 0xfc, 0x06, 0xff, 0x5f, 0x2c, 0xbc, 0xee, 0x1a, 0x73, 0xfe, 0x87, 0x83, 0xc6, 0x5c, 0xf4, 0x51, 0xb0, 0x62, 0x7c, 0x04,
0x74, 0xac, 0x2e, 0x10, 0x2b, 0xdc, 0x66, 0xe1, 0x76, 0xa1, 0x6d, 0xce, 0xbf, 0xb8, 0x68, 0x9b, 0x75, 0x31, 0x02, 0x19, 0x9b, 0x52, 0x36, 0x37, 0x4b, 0x0d, 0xb6, 0x0a, 0xbb, 0x5a, 0xf1, 0x05,
0x8b, 0x2e, 0x25, 0x2b, 0xc6, 0x47, 0x50, 0x97, 0x4f, 0x30, 0x63, 0x53, 0xc9, 0xe6, 0xde, 0x72, 0x74, 0x73, 0xc3, 0xa5, 0x71, 0x23, 0x67, 0x2b, 0x3f, 0x41, 0x0d, 0xfe, 0x37, 0xff, 0x50, 0xa3,
0x83, 0xad, 0xc2, 0xae, 0x56, 0x7c, 0x01, 0xdd, 0xdc, 0xe3, 0xd6, 0xb8, 0x91, 0xf3, 0x95, 0x7f, 0x1d, 0x02, 0x4c, 0x47, 0x11, 0xa3, 0x2f, 0xa5, 0x67, 0x26, 0xb1, 0xc1, 0xee, 0x9c, 0x13, 0x0d,
0xc1, 0x0d, 0xfe, 0x37, 0xff, 0x50, 0x5b, 0x3b, 0x04, 0x98, 0x3e, 0x85, 0x8c, 0xbe, 0x92, 0x9e, 0x72, 0x0a, 0x6b, 0xc5, 0x59, 0xc3, 0x28, 0x44, 0xb5, 0x38, 0x19, 0x0c, 0x6e, 0x2d, 0x3c, 0xcf,
0x79, 0x09, 0x0e, 0x76, 0xe7, 0x9c, 0x68, 0x23, 0xa7, 0xb0, 0x56, 0x7c, 0xeb, 0x18, 0x05, 0x56, 0xc2, 0x16, 0x27, 0x0e, 0x0d, 0xbb, 0x60, 0x7e, 0xd1, 0xb0, 0x0b, 0x47, 0x95, 0x15, 0xe3, 0x5b,
0x8b, 0x2f, 0x93, 0xc1, 0xad, 0x85, 0xe7, 0x59, 0xb3, 0xc5, 0x17, 0x8f, 0x36, 0xbb, 0xe0, 0xfd, 0xe8, 0xe5, 0x87, 0x05, 0x43, 0x05, 0x69, 0xee, 0x0c, 0x33, 0xb8, 0xb9, 0xe0, 0x54, 0x03, 0xbe,
0xa4, 0xcd, 0x2e, 0x7c, 0x2a, 0xad, 0x18, 0xdf, 0x42, 0x2f, 0xff, 0x58, 0x31, 0x52, 0x92, 0xe6, 0x0f, 0x35, 0x31, 0x16, 0xa8, 0x8a, 0xcf, 0x4e, 0x12, 0x83, 0xcd, 0xfc, 0xa6, 0xd6, 0x7a, 0x00,
0xbe, 0xa1, 0x06, 0x37, 0x17, 0x9c, 0x6a, 0x83, 0xef, 0x43, 0x4d, 0x3e, 0x4b, 0xd2, 0x8a, 0xcf, 0x75, 0xf1, 0x5d, 0xa8, 0x0b, 0x20, 0xf7, 0x99, 0x38, 0xe8, 0x64, 0x77, 0xcd, 0x95, 0x07, 0x25,
0xbe, 0x64, 0x06, 0x9b, 0xf9, 0x4d, 0xad, 0xf5, 0x00, 0xea, 0xf2, 0x5e, 0xaa, 0x0b, 0x20, 0x77, 0x65, 0x87, 0xe6, 0xec, 0xd0, 0x79, 0x76, 0x32, 0xc9, 0x19, 0xd5, 0xf9, 0xdf, 0x1f, 0x0f, 0xff,
0x4d, 0x1d, 0x74, 0xb2, 0xbb, 0xe6, 0xca, 0x83, 0x52, 0xea, 0x87, 0xe6, 0xfc, 0xd0, 0x79, 0x7e, 0x09, 0x00, 0x00, 0xff, 0xff, 0x25, 0xa3, 0x4c, 0x3f, 0x0b, 0x11, 0x00, 0x00,
0x32, 0xc9, 0x19, 0xd5, 0xc5, 0xdf, 0x2f, 0x0f, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x37,
0x3f, 0x0d, 0x8b, 0x11, 0x00, 0x00,
} }

View file

@ -163,12 +163,8 @@ message Event {
string type = 1; string type = 1;
string id = 2; string id = 2;
uint32 status = 3; uint32 status = 3;
string bundlePath = 4; string pid = 4;
string pid = 5; uint64 timestamp = 5;
uint32 signal = 7;
Process process = 8;
repeated Container containers = 9;
Checkpoint checkpoint = 10;
} }
message NetworkStats { message NetworkStats {

View file

@ -39,11 +39,6 @@ var daemonFlags = []cli.Flag{
Value: "/run/containerd", Value: "/run/containerd",
Usage: "runtime state directory", Usage: "runtime state directory",
}, },
cli.IntFlag{
Name: "c,concurrency",
Value: 10,
Usage: "set the concurrency level for tasks",
},
cli.DurationFlag{ cli.DurationFlag{
Name: "metrics-interval", Name: "metrics-interval",
Value: 120 * time.Second, Value: 120 * time.Second,
@ -86,7 +81,7 @@ func main() {
if err := daemon( if err := daemon(
context.String("listen"), context.String("listen"),
context.String("state-dir"), context.String("state-dir"),
context.Int("concurrency"), 10,
context.Bool("oom-notify"), context.Bool("oom-notify"),
); err != nil { ); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
@ -171,8 +166,7 @@ func daemon(address, stateDir string, concurrency int, oom bool) error {
// setup a standard reaper so that we don't leave any zombies if we are still alive // setup a standard reaper so that we don't leave any zombies if we are still alive
// this is just good practice because we are spawning new processes // this is just good practice because we are spawning new processes
go reapProcesses() go reapProcesses()
tasks := make(chan *supervisor.StartTask, concurrency*100) sv, err := supervisor.New(stateDir, oom)
sv, err := supervisor.New(stateDir, tasks, oom)
if err != nil { if err != nil {
return err return err
} }

View file

@ -6,13 +6,13 @@ import (
"github.com/docker/containerd/runtime" "github.com/docker/containerd/runtime"
) )
type AddProcessEvent struct { type AddProcessTask struct {
s *Supervisor s *Supervisor
} }
// TODO: add this to worker for concurrent starts??? maybe not because of races where the container // TODO: add this to worker for concurrent starts??? maybe not because of races where the container
// could be stopped and removed... // could be stopped and removed...
func (h *AddProcessEvent) Handle(e *Event) error { func (h *AddProcessTask) Handle(e *Task) error {
start := time.Now() start := time.Now()
ci, ok := h.s.containers[e.ID] ci, ok := h.s.containers[e.ID]
if !ok { if !ok {
@ -27,5 +27,11 @@ func (h *AddProcessEvent) Handle(e *Event) error {
} }
ExecProcessTimer.UpdateSince(start) ExecProcessTimer.UpdateSince(start)
e.StartResponse <- StartResponse{} e.StartResponse <- StartResponse{}
h.s.notifySubscribers(Event{
Timestamp: time.Now(),
Type: "start-process",
Pid: e.Pid,
ID: e.ID,
})
return nil return nil
} }

View file

@ -1,10 +1,10 @@
package supervisor package supervisor
type CreateCheckpointEvent struct { type CreateCheckpointTask struct {
s *Supervisor s *Supervisor
} }
func (h *CreateCheckpointEvent) Handle(e *Event) error { func (h *CreateCheckpointTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID] i, ok := h.s.containers[e.ID]
if !ok { if !ok {
return ErrContainerNotFound return ErrContainerNotFound
@ -12,11 +12,11 @@ func (h *CreateCheckpointEvent) Handle(e *Event) error {
return i.container.Checkpoint(*e.Checkpoint) return i.container.Checkpoint(*e.Checkpoint)
} }
type DeleteCheckpointEvent struct { type DeleteCheckpointTask struct {
s *Supervisor s *Supervisor
} }
func (h *DeleteCheckpointEvent) Handle(e *Event) error { func (h *DeleteCheckpointTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID] i, ok := h.s.containers[e.ID]
if !ok { if !ok {
return ErrContainerNotFound return ErrContainerNotFound

View file

@ -6,11 +6,11 @@ import (
"github.com/docker/containerd/runtime" "github.com/docker/containerd/runtime"
) )
type StartEvent struct { type StartTask struct {
s *Supervisor s *Supervisor
} }
func (h *StartEvent) Handle(e *Event) error { func (h *StartTask) Handle(e *Task) error {
start := time.Now() start := time.Now()
container, err := runtime.New(h.s.stateDir, e.ID, e.BundlePath, e.Labels) container, err := runtime.New(h.s.stateDir, e.ID, e.BundlePath, e.Labels)
if err != nil { if err != nil {
@ -20,7 +20,7 @@ func (h *StartEvent) Handle(e *Event) error {
container: container, container: container,
} }
ContainersCounter.Inc(1) ContainersCounter.Inc(1)
task := &StartTask{ task := &startTask{
Err: e.Err, Err: e.Err,
Container: container, Container: container,
StartResponse: e.StartResponse, StartResponse: e.StartResponse,

View file

@ -7,21 +7,22 @@ import (
"github.com/docker/containerd/runtime" "github.com/docker/containerd/runtime"
) )
type DeleteEvent struct { type DeleteTask struct {
s *Supervisor s *Supervisor
} }
func (h *DeleteEvent) Handle(e *Event) error { func (h *DeleteTask) Handle(e *Task) error {
if i, ok := h.s.containers[e.ID]; ok { if i, ok := h.s.containers[e.ID]; ok {
start := time.Now() start := time.Now()
if err := h.deleteContainer(i.container); err != nil { if err := h.deleteContainer(i.container); err != nil {
logrus.WithField("error", err).Error("containerd: deleting container") logrus.WithField("error", err).Error("containerd: deleting container")
} }
h.s.notifySubscribers(&Event{ h.s.notifySubscribers(Event{
Type: ExitEventType, Type: "exit",
ID: e.ID, Timestamp: time.Now(),
Status: e.Status, ID: e.ID,
Pid: e.Pid, Status: e.Status,
Pid: e.Pid,
}) })
ContainersCounter.Dec(1) ContainersCounter.Dec(1)
ContainerDeleteTimer.UpdateSince(start) ContainerDeleteTimer.UpdateSince(start)
@ -29,7 +30,7 @@ func (h *DeleteEvent) Handle(e *Event) error {
return nil return nil
} }
func (h *DeleteEvent) deleteContainer(container runtime.Container) error { func (h *DeleteTask) deleteContainer(container runtime.Container) error {
delete(h.s.containers, container.ID()) delete(h.s.containers, container.ID())
return container.Delete() return container.Delete()
} }

View file

@ -4,13 +4,13 @@ import "errors"
var ( var (
// External errors // External errors
ErrEventChanNil = errors.New("containerd: event channel is nil") ErrTaskChanNil = errors.New("containerd: task channel is nil")
ErrBundleNotFound = errors.New("containerd: bundle not found") ErrBundleNotFound = errors.New("containerd: bundle not found")
ErrContainerNotFound = errors.New("containerd: container not found") ErrContainerNotFound = errors.New("containerd: container not found")
ErrContainerExists = errors.New("containerd: container already exists") ErrContainerExists = errors.New("containerd: container already exists")
ErrProcessNotFound = errors.New("containerd: processs not found for container") ErrProcessNotFound = errors.New("containerd: processs not found for container")
ErrUnknownContainerStatus = errors.New("containerd: unknown container status ") ErrUnknownContainerStatus = errors.New("containerd: unknown container status ")
ErrUnknownEvent = errors.New("containerd: unknown event type") ErrUnknownTask = errors.New("containerd: unknown task type")
// Internal errors // Internal errors
errShutdown = errors.New("containerd: supervisor is shutdown") errShutdown = errors.New("containerd: supervisor is shutdown")

View file

@ -7,11 +7,11 @@ import (
"github.com/docker/containerd/runtime" "github.com/docker/containerd/runtime"
) )
type ExitEvent struct { type ExitTask struct {
s *Supervisor s *Supervisor
} }
func (h *ExitEvent) Handle(e *Event) error { func (h *ExitTask) Handle(e *Task) error {
start := time.Now() start := time.Now()
proc := e.Process proc := e.Process
status, err := proc.ExitStatus() status, err := proc.ExitStatus()
@ -23,37 +23,43 @@ func (h *ExitEvent) Handle(e *Event) error {
// if the process is the the init process of the container then // if the process is the the init process of the container then
// fire a separate event for this process // fire a separate event for this process
if proc.ID() != runtime.InitProcessID { if proc.ID() != runtime.InitProcessID {
ne := NewEvent(ExecExitEventType) ne := NewTask(ExecExitTaskType)
ne.ID = proc.Container().ID() ne.ID = proc.Container().ID()
ne.Pid = proc.ID() ne.Pid = proc.ID()
ne.Status = status ne.Status = status
ne.Process = proc ne.Process = proc
h.s.SendEvent(ne) h.s.SendTask(ne)
return nil return nil
} }
container := proc.Container() container := proc.Container()
ne := NewEvent(DeleteEventType) ne := NewTask(DeleteTaskType)
ne.ID = container.ID() ne.ID = container.ID()
ne.Status = status ne.Status = status
ne.Pid = proc.ID() ne.Pid = proc.ID()
h.s.SendEvent(ne) h.s.SendTask(ne)
ExitProcessTimer.UpdateSince(start) ExitProcessTimer.UpdateSince(start)
return nil return nil
} }
type ExecExitEvent struct { type ExecExitTask struct {
s *Supervisor s *Supervisor
} }
func (h *ExecExitEvent) Handle(e *Event) error { func (h *ExecExitTask) Handle(e *Task) error {
container := e.Process.Container() container := e.Process.Container()
// exec process: we remove this process without notifying the main event loop // exec process: we remove this process without notifying the main event loop
if err := container.RemoveProcess(e.Pid); err != nil { if err := container.RemoveProcess(e.Pid); err != nil {
logrus.WithField("error", err).Error("containerd: find container for pid") logrus.WithField("error", err).Error("containerd: find container for pid")
} }
h.s.notifySubscribers(e) h.s.notifySubscribers(Event{
Timestamp: time.Now(),
ID: e.ID,
Type: "exit",
Pid: e.Pid,
Status: e.Status,
})
return nil return nil
} }

View file

@ -1,10 +1,10 @@
package supervisor package supervisor
type GetContainersEvent struct { type GetContainersTask struct {
s *Supervisor s *Supervisor
} }
func (h *GetContainersEvent) Handle(e *Event) error { func (h *GetContainersTask) Handle(e *Task) error {
if e.ID != "" { if e.ID != "" {
ci := h.s.containers[e.ID] ci := h.s.containers[e.ID]
if ci == nil { if ci == nil {

View file

@ -9,7 +9,7 @@ var (
ContainerStatsTimer = metrics.NewTimer() ContainerStatsTimer = metrics.NewTimer()
ContainersCounter = metrics.NewCounter() ContainersCounter = metrics.NewCounter()
EventSubscriberCounter = metrics.NewCounter() EventSubscriberCounter = metrics.NewCounter()
EventsCounter = metrics.NewCounter() TasksCounter = metrics.NewCounter()
ExecProcessTimer = metrics.NewTimer() ExecProcessTimer = metrics.NewTimer()
ExitProcessTimer = metrics.NewTimer() ExitProcessTimer = metrics.NewTimer()
EpollFdCounter = metrics.NewCounter() EpollFdCounter = metrics.NewCounter()
@ -23,7 +23,7 @@ func Metrics() map[string]interface{} {
"container-stats-time": ContainerStatsTimer, "container-stats-time": ContainerStatsTimer,
"containers": ContainersCounter, "containers": ContainersCounter,
"event-subscribers": EventSubscriberCounter, "event-subscribers": EventSubscriberCounter,
"events": EventsCounter, "tasks": TasksCounter,
"exec-process-time": ExecProcessTimer, "exec-process-time": ExecProcessTimer,
"exit-process-time": ExitProcessTimer, "exit-process-time": ExitProcessTimer,
"epoll-fds": EpollFdCounter, "epoll-fds": EpollFdCounter,

View file

@ -1,10 +1,10 @@
package supervisor package supervisor
type SignalEvent struct { type SignalTask struct {
s *Supervisor s *Supervisor
} }
func (h *SignalEvent) Handle(e *Event) error { func (h *SignalTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID] i, ok := h.s.containers[e.ID]
if !ok { if !ok {
return ErrContainerNotFound return ErrContainerNotFound

View file

@ -2,11 +2,11 @@ package supervisor
import "time" import "time"
type StatsEvent struct { type StatsTask struct {
s *Supervisor s *Supervisor
} }
func (h *StatsEvent) Handle(e *Event) error { func (h *StatsTask) Handle(e *Task) error {
start := time.Now() start := time.Now()
i, ok := h.s.containers[e.ID] i, ok := h.s.containers[e.ID]
if !ok { if !ok {

View file

@ -5,6 +5,7 @@ import (
"os" "os"
"sort" "sort"
"sync" "sync"
"time"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/docker/containerd/chanotify" "github.com/docker/containerd/chanotify"
@ -17,7 +18,8 @@ const (
) )
// New returns an initialized Process supervisor. // New returns an initialized Process supervisor.
func New(stateDir string, tasks chan *StartTask, oom bool) (*Supervisor, error) { func New(stateDir string, oom bool) (*Supervisor, error) {
tasks := make(chan *startTask, 10)
if err := os.MkdirAll(stateDir, 0755); err != nil { if err := os.MkdirAll(stateDir, 0755); err != nil {
return nil, err return nil, err
} }
@ -34,7 +36,7 @@ func New(stateDir string, tasks chan *StartTask, oom bool) (*Supervisor, error)
containers: make(map[string]*containerInfo), containers: make(map[string]*containerInfo),
tasks: tasks, tasks: tasks,
machine: machine, machine: machine,
subscribers: make(map[chan *Event]struct{}), subscribers: make(map[chan Event]struct{}),
el: eventloop.NewChanLoop(defaultBufferSize), el: eventloop.NewChanLoop(defaultBufferSize),
monitor: monitor, monitor: monitor,
} }
@ -42,26 +44,26 @@ func New(stateDir string, tasks chan *StartTask, oom bool) (*Supervisor, error)
s.notifier = chanotify.New() s.notifier = chanotify.New()
go func() { go func() {
for id := range s.notifier.Chan() { for id := range s.notifier.Chan() {
e := NewEvent(OOMEventType) e := NewTask(OOMTaskType)
e.ID = id.(string) e.ID = id.(string)
s.SendEvent(e) s.SendTask(e)
} }
}() }()
} }
// register default event handlers // register default event handlers
s.handlers = map[EventType]Handler{ s.handlers = map[TaskType]Handler{
ExecExitEventType: &ExecExitEvent{s}, ExecExitTaskType: &ExecExitTask{s},
ExitEventType: &ExitEvent{s}, ExitTaskType: &ExitTask{s},
StartContainerEventType: &StartEvent{s}, StartContainerTaskType: &StartTask{s},
DeleteEventType: &DeleteEvent{s}, DeleteTaskType: &DeleteTask{s},
GetContainerEventType: &GetContainersEvent{s}, GetContainerTaskType: &GetContainersTask{s},
SignalEventType: &SignalEvent{s}, SignalTaskType: &SignalTask{s},
AddProcessEventType: &AddProcessEvent{s}, AddProcessTaskType: &AddProcessTask{s},
UpdateContainerEventType: &UpdateEvent{s}, UpdateContainerTaskType: &UpdateTask{s},
CreateCheckpointEventType: &CreateCheckpointEvent{s}, CreateCheckpointTaskType: &CreateCheckpointTask{s},
DeleteCheckpointEventType: &DeleteCheckpointEvent{s}, DeleteCheckpointTaskType: &DeleteCheckpointTask{s},
StatsEventType: &StatsEvent{s}, StatsTaskType: &StatsTask{s},
UpdateProcessEventType: &UpdateProcessEvent{s}, UpdateProcessTaskType: &UpdateProcessTask{s},
} }
go s.exitHandler() go s.exitHandler()
if err := s.restore(); err != nil { if err := s.restore(); err != nil {
@ -78,13 +80,13 @@ type Supervisor struct {
// stateDir is the directory on the system to store container runtime state information. // stateDir is the directory on the system to store container runtime state information.
stateDir string stateDir string
containers map[string]*containerInfo containers map[string]*containerInfo
handlers map[EventType]Handler handlers map[TaskType]Handler
events chan *Event events chan *Task
tasks chan *StartTask tasks chan *startTask
// we need a lock around the subscribers map only because additions and deletions from // we need a lock around the subscribers map only because additions and deletions from
// the map are via the API so we cannot really control the concurrency // the map are via the API so we cannot really control the concurrency
subscriberLock sync.RWMutex subscriberLock sync.RWMutex
subscribers map[chan *Event]struct{} subscribers map[chan Event]struct{}
machine Machine machine Machine
notifier *chanotify.Notifier notifier *chanotify.Notifier
el eventloop.EventLoop el eventloop.EventLoop
@ -105,19 +107,27 @@ func (s *Supervisor) Close() error {
return nil return nil
} }
type Event struct {
ID string `json:"id"`
Type string `json:"type"`
Timestamp time.Time `json:"timestamp"`
Pid string `json:"pid,omitempty"`
Status int `json:"status,omitempty"`
}
// Events returns an event channel that external consumers can use to receive updates // Events returns an event channel that external consumers can use to receive updates
// on container events // on container events
func (s *Supervisor) Events() chan *Event { func (s *Supervisor) Events() chan Event {
s.subscriberLock.Lock() s.subscriberLock.Lock()
defer s.subscriberLock.Unlock() defer s.subscriberLock.Unlock()
c := make(chan *Event, defaultBufferSize) c := make(chan Event, defaultBufferSize)
EventSubscriberCounter.Inc(1) EventSubscriberCounter.Inc(1)
s.subscribers[c] = struct{}{} s.subscribers[c] = struct{}{}
return c return c
} }
// Unsubscribe removes the provided channel from receiving any more events // Unsubscribe removes the provided channel from receiving any more events
func (s *Supervisor) Unsubscribe(sub chan *Event) { func (s *Supervisor) Unsubscribe(sub chan Event) {
s.subscriberLock.Lock() s.subscriberLock.Lock()
defer s.subscriberLock.Unlock() defer s.subscriberLock.Unlock()
delete(s.subscribers, sub) delete(s.subscribers, sub)
@ -127,7 +137,7 @@ func (s *Supervisor) Unsubscribe(sub chan *Event) {
// notifySubscribers will send the provided event to the external subscribers // notifySubscribers will send the provided event to the external subscribers
// of the events channel // of the events channel
func (s *Supervisor) notifySubscribers(e *Event) { func (s *Supervisor) notifySubscribers(e Event) {
s.subscriberLock.RLock() s.subscriberLock.RLock()
defer s.subscriberLock.RUnlock() defer s.subscriberLock.RUnlock()
for sub := range s.subscribers { for sub := range s.subscribers {
@ -159,17 +169,17 @@ func (s *Supervisor) Machine() Machine {
return s.machine return s.machine
} }
// SendEvent sends the provided event the the supervisors main event loop // SendTask sends the provided event the the supervisors main event loop
func (s *Supervisor) SendEvent(evt *Event) { func (s *Supervisor) SendTask(evt *Task) {
EventsCounter.Inc(1) TasksCounter.Inc(1)
s.el.Send(&commonEvent{data: evt, sv: s}) s.el.Send(&commonTask{data: evt, sv: s})
} }
func (s *Supervisor) exitHandler() { func (s *Supervisor) exitHandler() {
for p := range s.monitor.Exits() { for p := range s.monitor.Exits() {
e := NewEvent(ExitEventType) e := NewTask(ExitTaskType)
e.Process = p e.Process = p
s.SendEvent(e) s.SendTask(e)
} }
} }
@ -215,9 +225,9 @@ func (s *Supervisor) restore() error {
// exit events // exit events
sort.Sort(&processSorter{exitedProcesses}) sort.Sort(&processSorter{exitedProcesses})
for _, p := range exitedProcesses { for _, p := range exitedProcesses {
e := NewEvent(ExitEventType) e := NewTask(ExitTaskType)
e.Process = p e.Process = p
s.SendEvent(e) s.SendTask(e)
} }
} }
} }

View file

@ -8,26 +8,26 @@ import (
"github.com/opencontainers/specs" "github.com/opencontainers/specs"
) )
type EventType string type TaskType string
const ( const (
ExecExitEventType EventType = "execExit" ExecExitTaskType TaskType = "execExit"
ExitEventType EventType = "exit" ExitTaskType TaskType = "exit"
StartContainerEventType EventType = "startContainer" StartContainerTaskType TaskType = "startContainer"
DeleteEventType EventType = "deleteContainerEvent" DeleteTaskType TaskType = "deleteContainerEvent"
GetContainerEventType EventType = "getContainer" GetContainerTaskType TaskType = "getContainer"
SignalEventType EventType = "signal" SignalTaskType TaskType = "signal"
AddProcessEventType EventType = "addProcess" AddProcessTaskType TaskType = "addProcess"
UpdateContainerEventType EventType = "updateContainer" UpdateContainerTaskType TaskType = "updateContainer"
UpdateProcessEventType EventType = "updateProcess" UpdateProcessTaskType TaskType = "updateProcess"
CreateCheckpointEventType EventType = "createCheckpoint" CreateCheckpointTaskType TaskType = "createCheckpoint"
DeleteCheckpointEventType EventType = "deleteCheckpoint" DeleteCheckpointTaskType TaskType = "deleteCheckpoint"
StatsEventType EventType = "events" StatsTaskType TaskType = "events"
OOMEventType EventType = "oom" OOMTaskType TaskType = "oom"
) )
func NewEvent(t EventType) *Event { func NewTask(t TaskType) *Task {
return &Event{ return &Task{
Type: t, Type: t,
Timestamp: time.Now(), Timestamp: time.Now(),
Err: make(chan error, 1), Err: make(chan error, 1),
@ -38,8 +38,8 @@ type StartResponse struct {
Container runtime.Container Container runtime.Container
} }
type Event struct { type Task struct {
Type EventType Type TaskType
Timestamp time.Time Timestamp time.Time
ID string ID string
BundlePath string BundlePath string
@ -66,18 +66,18 @@ type Event struct {
} }
type Handler interface { type Handler interface {
Handle(*Event) error Handle(*Task) error
} }
type commonEvent struct { type commonTask struct {
data *Event data *Task
sv *Supervisor sv *Supervisor
} }
func (e *commonEvent) Handle() { func (e *commonTask) Handle() {
h, ok := e.sv.handlers[e.data.Type] h, ok := e.sv.handlers[e.data.Type]
if !ok { if !ok {
e.data.Err <- ErrUnknownEvent e.data.Err <- ErrUnknownTask
return return
} }
err := h.Handle(e.data) err := h.Handle(e.data)

View file

@ -1,12 +1,16 @@
package supervisor package supervisor
import "github.com/docker/containerd/runtime" import (
"time"
type UpdateEvent struct { "github.com/docker/containerd/runtime"
)
type UpdateTask struct {
s *Supervisor s *Supervisor
} }
func (h *UpdateEvent) Handle(e *Event) error { func (h *UpdateTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID] i, ok := h.s.containers[e.ID]
if !ok { if !ok {
return ErrContainerNotFound return ErrContainerNotFound
@ -18,10 +22,20 @@ func (h *UpdateEvent) Handle(e *Event) error {
if err := container.Resume(); err != nil { if err := container.Resume(); err != nil {
return ErrUnknownContainerStatus return ErrUnknownContainerStatus
} }
h.s.notifySubscribers(Event{
ID: e.ID,
Type: "resume",
Timestamp: time.Now(),
})
case runtime.Paused: case runtime.Paused:
if err := container.Pause(); err != nil { if err := container.Pause(); err != nil {
return ErrUnknownContainerStatus return ErrUnknownContainerStatus
} }
h.s.notifySubscribers(Event{
ID: e.ID,
Type: "pause",
Timestamp: time.Now(),
})
default: default:
return ErrUnknownContainerStatus return ErrUnknownContainerStatus
} }
@ -29,11 +43,11 @@ func (h *UpdateEvent) Handle(e *Event) error {
return nil return nil
} }
type UpdateProcessEvent struct { type UpdateProcessTask struct {
s *Supervisor s *Supervisor
} }
func (h *UpdateProcessEvent) Handle(e *Event) error { func (h *UpdateProcessTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID] i, ok := h.s.containers[e.ID]
if !ok { if !ok {
return ErrContainerNotFound return ErrContainerNotFound

View file

@ -12,7 +12,7 @@ type Worker interface {
Start() Start()
} }
type StartTask struct { type startTask struct {
Container runtime.Container Container runtime.Container
Checkpoint string Checkpoint string
Stdin string Stdin string
@ -40,9 +40,9 @@ func (w *worker) Start() {
started := time.Now() started := time.Now()
process, err := t.Container.Start(t.Checkpoint, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr)) process, err := t.Container.Start(t.Checkpoint, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr))
if err != nil { if err != nil {
evt := NewEvent(DeleteEventType) evt := NewTask(DeleteTaskType)
evt.ID = t.Container.ID() evt.ID = t.Container.ID()
w.s.SendEvent(evt) w.s.SendTask(evt)
t.Err <- err t.Err <- err
continue continue
} }
@ -64,5 +64,10 @@ func (w *worker) Start() {
t.StartResponse <- StartResponse{ t.StartResponse <- StartResponse{
Container: t.Container, Container: t.Container,
} }
w.s.notifySubscribers(Event{
Timestamp: time.Now(),
ID: t.Container.ID(),
Type: "start-container",
})
} }
} }