| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package service
- import (
- "fmt"
- "os"
- "path/filepath"
- "strconv"
- "syscall"
- "yunion.io/x/log"
- "yunion.io/x/pkg/util/signalutils"
- "yunion.io/x/pkg/utils"
- "yunion.io/x/onecloud/pkg/cloudcommon/options"
- "yunion.io/x/onecloud/pkg/util/fileutils2"
- "yunion.io/x/onecloud/pkg/util/procutils"
- )
- type IService interface {
- InitService()
- RunService()
- OnExitService()
- }
- type SServiceBase struct {
- Service IService
- O *options.BaseOptions
- }
- func NewBaseService(service IService) *SServiceBase {
- return &SServiceBase{Service: service}
- }
- func (s *SServiceBase) StartService() {
- defer s.Service.OnExitService()
- defer s.RemovePid()
- s.Service.InitService()
- if err := s.CreatePid(); err != nil {
- log.Fatalln(err)
- }
- s.Service.RunService()
- }
- func (s *SServiceBase) CreatePid() error {
- if s.O == nil || len(s.O.PidFile) == 0 {
- return nil
- }
- absPath, err := filepath.Abs(s.O.PidFile)
- if err != nil {
- return fmt.Errorf("Get pidfile %s absolute path failed: %s", s.O.PidFile, err)
- }
- s.O.PidFile = absPath
- pidDir := filepath.Dir(s.O.PidFile)
- if !fileutils2.Exists(pidDir) {
- output, err := procutils.NewCommand("mkdir", "-p", pidDir).Output()
- if err != nil {
- return fmt.Errorf("Make pid dir %s failed: %s", pidDir, output)
- }
- }
- err = fileutils2.FilePutContents(s.O.PidFile, strconv.Itoa(os.Getpid()), false)
- if err != nil {
- return fmt.Errorf("Write pidfile %s failed: %s", s.O.PidFile, err)
- }
- return nil
- }
- func (s *SServiceBase) RemovePid() {
- if s.O != nil && len(s.O.PidFile) > 0 && fileutils2.Exists(s.O.PidFile) {
- os.Remove(s.O.PidFile)
- }
- }
- func (s *SServiceBase) SignalTrap(onExit func()) {
- // dump goroutine stack
- signalutils.RegisterSignal(func() {
- utils.DumpAllGoroutineStack(log.Logger().Out)
- }, syscall.SIGUSR1)
- if onExit != nil {
- quitSignals := []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM}
- signalutils.RegisterSignal(onExit, quitSignals...)
- }
- signalutils.StartTrap()
- }
|