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 }