Ignore "no such process" error (#1686)
* Cleanup how status is updated for service. Ignore "no such process" error as it could be that the pid died * add nice error log to record process error exit
This commit is contained in:
		| @@ -373,7 +373,6 @@ func (r *runtime) Create(s *Service, opts ...CreateOption) error { | |||||||
| 	if err := service.Start(); err != nil { | 	if err := service.Start(); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// save service | 	// save service | ||||||
| 	r.namespaces[options.Namespace][serviceKey(s)] = service | 	r.namespaces[options.Namespace][serviceKey(s)] = service | ||||||
|  |  | ||||||
| @@ -536,7 +535,7 @@ func (r *runtime) Read(opts ...ReadOption) ([]*Service, error) { | |||||||
| 	return services, nil | 	return services, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // Update attemps to update the service | // Update attempts to update the service | ||||||
| func (r *runtime) Update(s *Service, opts ...UpdateOption) error { | func (r *runtime) Update(s *Service, opts ...UpdateOption) error { | ||||||
| 	var options UpdateOptions | 	var options UpdateOptions | ||||||
| 	for _, o := range opts { | 	for _, o := range opts { | ||||||
| @@ -565,7 +564,8 @@ func (r *runtime) Update(s *Service, opts ...UpdateOption) error { | |||||||
| 		return errors.New("Service not found") | 		return errors.New("Service not found") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := service.Stop(); err != nil { | 	if err := service.Stop(); err != nil && err.Error() != "no such process" { | ||||||
|  | 		logger.Errorf("Error stopping service %s: %s", service.Name, err) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -167,11 +167,10 @@ func (k *kubernetes) getService(labels map[string]string, opts ...client.GetOpti | |||||||
|  |  | ||||||
| 			// parse out deployment status and inject into service metadata | 			// parse out deployment status and inject into service metadata | ||||||
| 			if len(kdep.Status.Conditions) > 0 { | 			if len(kdep.Status.Conditions) > 0 { | ||||||
| 				svc.Metadata["status"] = kdep.Status.Conditions[0].Type | 				svc.Status(kdep.Status.Conditions[0].Type, nil) | ||||||
| 				svc.Metadata["started"] = kdep.Status.Conditions[0].LastUpdateTime | 				svc.Metadata["started"] = kdep.Status.Conditions[0].LastUpdateTime | ||||||
| 				delete(svc.Metadata, "error") |  | ||||||
| 			} else { | 			} else { | ||||||
| 				svc.Metadata["status"] = "n/a" | 				svc.Status("n/a", nil) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// get the real status | 			// get the real status | ||||||
| @@ -214,8 +213,7 @@ func (k *kubernetes) getService(labels map[string]string, opts ...client.GetOpti | |||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				// TODO: set from terminated | 				// TODO: set from terminated | ||||||
|  | 				svc.Status(status, nil) | ||||||
| 				svc.Metadata["status"] = status |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// save deployment | 			// save deployment | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ package kubernetes | |||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/micro/go-micro/v2/logger" | 	"github.com/micro/go-micro/v2/logger" | ||||||
| 	"github.com/micro/go-micro/v2/runtime" | 	"github.com/micro/go-micro/v2/runtime" | ||||||
| @@ -185,8 +186,10 @@ func (s *service) Update(k client.Client, opts ...client.UpdateOption) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (s *service) Status(status string, err error) { | func (s *service) Status(status string, err error) { | ||||||
|  | 	s.Metadata["lastStatusUpdate"] = time.Now().Format(time.RFC3339) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		s.Metadata["status"] = status | 		s.Metadata["status"] = status | ||||||
|  | 		delete(s.Metadata, "error") | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	s.Metadata["status"] = "error" | 	s.Metadata["status"] = "error" | ||||||
|   | |||||||
| @@ -93,7 +93,7 @@ func (s *service) Running() bool { | |||||||
| 	return s.running | 	return s.running | ||||||
| } | } | ||||||
|  |  | ||||||
| // Start stars the service | // Start starts the service | ||||||
| func (s *service) Start() error { | func (s *service) Start() error { | ||||||
| 	s.Lock() | 	s.Lock() | ||||||
| 	defer s.Unlock() | 	defer s.Unlock() | ||||||
| @@ -110,10 +110,7 @@ func (s *service) Start() error { | |||||||
| 	if s.Metadata == nil { | 	if s.Metadata == nil { | ||||||
| 		s.Metadata = make(map[string]string) | 		s.Metadata = make(map[string]string) | ||||||
| 	} | 	} | ||||||
|  | 	s.Status("starting", nil) | ||||||
| 	s.Metadata["status"] = "starting" |  | ||||||
| 	// delete any existing error |  | ||||||
| 	delete(s.Metadata, "error") |  | ||||||
|  |  | ||||||
| 	// TODO: pull source & build binary | 	// TODO: pull source & build binary | ||||||
| 	if logger.V(logger.DebugLevel, logger.DefaultLogger) { | 	if logger.V(logger.DebugLevel, logger.DefaultLogger) { | ||||||
| @@ -122,17 +119,15 @@ func (s *service) Start() error { | |||||||
|  |  | ||||||
| 	p, err := s.Process.Fork(s.Exec) | 	p, err := s.Process.Fork(s.Exec) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		s.Metadata["status"] = "error" | 		s.Status("error", err) | ||||||
| 		s.Metadata["error"] = err.Error() |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// set the pid | 	// set the pid | ||||||
| 	s.PID = p | 	s.PID = p | ||||||
| 	// set to running | 	// set to running | ||||||
| 	s.running = true | 	s.running = true | ||||||
| 	// set status | 	// set status | ||||||
| 	s.Metadata["status"] = "running" | 	s.Status("running", nil) | ||||||
| 	// set started | 	// set started | ||||||
| 	s.Metadata["started"] = time.Now().Format(time.RFC3339) | 	s.Metadata["started"] = time.Now().Format(time.RFC3339) | ||||||
|  |  | ||||||
| @@ -146,6 +141,18 @@ func (s *service) Start() error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Status updates the status of the service. Assumes it's called under a lock as it mutates state | ||||||
|  | func (s *service) Status(status string, err error) { | ||||||
|  | 	s.Metadata["lastStatusUpdate"] = time.Now().Format(time.RFC3339) | ||||||
|  | 	s.Metadata["status"] = status | ||||||
|  | 	if err == nil { | ||||||
|  | 		delete(s.Metadata, "error") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	s.Metadata["error"] = err.Error() | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| // Stop stops the service | // Stop stops the service | ||||||
| func (s *service) Stop() error { | func (s *service) Stop() error { | ||||||
| 	s.Lock() | 	s.Lock() | ||||||
| @@ -163,18 +170,17 @@ func (s *service) Stop() error { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// set status | 		// set status | ||||||
| 		s.Metadata["status"] = "stopping" | 		s.Status("stopping", nil) | ||||||
|  |  | ||||||
| 		// kill the process | 		// kill the process | ||||||
| 		err := s.Process.Kill(s.PID) | 		err := s.Process.Kill(s.PID) | ||||||
| 		if err != nil { | 		if err == nil { | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 			// wait for it to exit | 			// wait for it to exit | ||||||
| 			s.Process.Wait(s.PID) | 			s.Process.Wait(s.PID) | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		// set status | 		// set status | ||||||
| 		s.Metadata["status"] = "stopped" | 		s.Status("stopped", err) | ||||||
|  |  | ||||||
| 		// return the kill error | 		// return the kill error | ||||||
| 		return err | 		return err | ||||||
| @@ -198,14 +204,16 @@ func (s *service) Wait() { | |||||||
|  |  | ||||||
| 	// save the error | 	// save the error | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | 		if logger.V(logger.ErrorLevel, logger.DefaultLogger) { | ||||||
|  | 			logger.Errorf("Service %s terminated with error %s", s.Name, err) | ||||||
|  | 		} | ||||||
| 		s.retries++ | 		s.retries++ | ||||||
| 		s.Metadata["status"] = "error" | 		s.Status("error", err) | ||||||
| 		s.Metadata["error"] = err.Error() |  | ||||||
| 		s.Metadata["retries"] = strconv.Itoa(s.retries) | 		s.Metadata["retries"] = strconv.Itoa(s.retries) | ||||||
|  |  | ||||||
| 		s.err = err | 		s.err = err | ||||||
| 	} else { | 	} else { | ||||||
| 		s.Metadata["status"] = "done" | 		s.Status("done", nil) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// no longer running | 	// no longer running | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user