github.com/ladydascalie/elvish@v0.0.0-20170703214355-2964dd3ece7f/daemon/service/service.go (about)

     1  // Package service implements the daemon service for mediating access to the
     2  // storage backend.
     3  package service
     4  
     5  import (
     6  	"net"
     7  	"net/rpc"
     8  	"os"
     9  	"os/signal"
    10  	"syscall"
    11  
    12  	"github.com/elves/elvish/daemon/api"
    13  	"github.com/elves/elvish/store"
    14  	"github.com/elves/elvish/util"
    15  )
    16  
    17  var logger = util.GetLogger("[daemon] ")
    18  
    19  // Serve runs the daemon service. It does not return.
    20  func Serve(sockpath, dbpath string) {
    21  	logger.Println("pid is", syscall.Getpid())
    22  
    23  	st, err := store.NewStore(dbpath)
    24  	if err != nil {
    25  		logger.Printf("failed to create storage: %v", err)
    26  		logger.Println("aborting")
    27  		os.Exit(2)
    28  	}
    29  
    30  	logger.Println("going to listen", sockpath)
    31  	listener, err := net.Listen("unix", sockpath)
    32  	if err != nil {
    33  		logger.Printf("failed to listen on %s: %v", sockpath, err)
    34  		logger.Println("aborting")
    35  		os.Exit(2)
    36  	}
    37  
    38  	quitSignals := make(chan os.Signal)
    39  	signal.Notify(quitSignals, syscall.SIGTERM, syscall.SIGINT)
    40  	go func() {
    41  		sig := <-quitSignals
    42  		logger.Printf("received signal %s", sig)
    43  		err := os.Remove(sockpath)
    44  		if err != nil {
    45  			logger.Printf("failed to remove socket %s: %v", sockpath, err)
    46  		}
    47  		err = st.Close()
    48  		if err != nil {
    49  			logger.Printf("failed to close storage: %v", err)
    50  		}
    51  		err = listener.Close()
    52  		if err != nil {
    53  			logger.Printf("failed to close listener: %v", err)
    54  		}
    55  		logger.Println("listener closed, waiting to exit")
    56  	}()
    57  
    58  	service := &Service{st}
    59  	rpc.RegisterName(api.ServiceName, service)
    60  
    61  	logger.Println("starting to serve RPC calls")
    62  	rpc.Accept(listener)
    63  
    64  	logger.Println("exiting")
    65  }
    66  
    67  // Service provides the daemon RPC service.
    68  type Service struct {
    69  	store *store.Store
    70  }
    71  
    72  func (s *Service) Version(req *api.VersionRequest, res *api.VersionResponse) error {
    73  	res.Version = api.Version
    74  	return nil
    75  }
    76  
    77  func (s *Service) Pid(req *api.PidRequest, res *api.PidResponse) error {
    78  	res.Pid = syscall.Getpid()
    79  	return nil
    80  }
    81  
    82  func (s *Service) NextCmdSeq(req *api.NextCmdSeqRequest, res *api.NextCmdSeqResponse) error {
    83  	seq, err := s.store.NextCmdSeq()
    84  	res.Seq = seq
    85  	return err
    86  }
    87  
    88  func (s *Service) AddCmd(req *api.AddCmdRequest, res *api.AddCmdResponse) error {
    89  	seq, err := s.store.AddCmd(req.Text)
    90  	res.Seq = seq
    91  	return err
    92  }
    93  
    94  func (s *Service) Cmd(req *api.CmdRequest, res *api.CmdResponse) error {
    95  	text, err := s.store.Cmd(req.Seq)
    96  	res.Text = text
    97  	return err
    98  }
    99  
   100  func (s *Service) Cmds(req *api.CmdsRequest, res *api.CmdsResponse) error {
   101  	cmds, err := s.store.Cmds(req.From, req.Upto)
   102  	res.Cmds = cmds
   103  	return err
   104  }
   105  
   106  func (s *Service) NextCmd(req *api.NextCmdRequest, res *api.NextCmdResponse) error {
   107  	seq, text, err := s.store.NextCmd(req.From, req.Prefix)
   108  	res.Seq, res.Text = seq, text
   109  	return err
   110  }
   111  
   112  func (s *Service) PrevCmd(req *api.PrevCmdRequest, res *api.PrevCmdResponse) error {
   113  	seq, text, err := s.store.PrevCmd(req.Upto, req.Prefix)
   114  	res.Seq, res.Text = seq, text
   115  	return err
   116  }
   117  
   118  func (s *Service) AddDir(req *api.AddDirRequest, res *api.AddDirResponse) error {
   119  	return s.store.AddDir(req.Dir, req.IncFactor)
   120  }
   121  
   122  func (s *Service) Dirs(req *api.DirsRequest, res *api.DirsResponse) error {
   123  	dirs, err := s.store.GetDirs(req.Blacklist)
   124  	res.Dirs = dirs
   125  	return err
   126  }
   127  
   128  func (s *Service) SharedVar(req *api.SharedVarRequest, res *api.SharedVarResponse) error {
   129  	value, err := s.store.GetSharedVar(req.Name)
   130  	res.Value = value
   131  	return err
   132  }
   133  
   134  func (s *Service) SetSharedVar(req *api.SetSharedVarRequest, res *api.SetSharedVarResponse) error {
   135  	return s.store.SetSharedVar(req.Name, req.Value)
   136  }
   137  
   138  func (s *Service) DelSharedVar(req *api.DelSharedVarRequest, res *api.DelSharedVarResponse) error {
   139  	return s.store.DelSharedVar(req.Name)
   140  }