|
| 1 | +package status |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "errors" |
| 6 | + "fmt" |
| 7 | + "sync" |
| 8 | + |
| 9 | + "github.com/lightninglabs/lightning-terminal/litrpc" |
| 10 | +) |
| 11 | + |
| 12 | +// SubServerStatus represents the status of a sub-server. |
| 13 | +type SubServerStatus struct { |
| 14 | + // Disabled is true if the sub-server is available in the LiT bundle but |
| 15 | + // has explicitly been disabled by the user. |
| 16 | + Disabled bool |
| 17 | + |
| 18 | + // Running is true if the sub-server is enabled and has successfully |
| 19 | + // been started. |
| 20 | + Running bool |
| 21 | + |
| 22 | + // Err will be a non-empty string if the sub-server failed to start. |
| 23 | + Err string |
| 24 | +} |
| 25 | + |
| 26 | +// newSubServerStatus constructs a new SubServerStatus. |
| 27 | +func newSubServerStatus() *SubServerStatus { |
| 28 | + return &SubServerStatus{ |
| 29 | + Disabled: true, |
| 30 | + } |
| 31 | +} |
| 32 | + |
| 33 | +// Manager manages the status of any sub-server registered to it. It is also an |
| 34 | +// implementation of the litrpc.StatusServer which can be queried for the status |
| 35 | +// of various LiT sub-servers. |
| 36 | +type Manager struct { |
| 37 | + litrpc.UnimplementedStatusServer |
| 38 | + |
| 39 | + subServers map[string]*SubServerStatus |
| 40 | + mu sync.RWMutex |
| 41 | +} |
| 42 | + |
| 43 | +// NewStatusManager constructs a new Manager. |
| 44 | +func NewStatusManager() *Manager { |
| 45 | + return &Manager{ |
| 46 | + subServers: make(map[string]*SubServerStatus), |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +// SubServerStatus queries the current status of a given sub-server. |
| 51 | +// |
| 52 | +// NOTE: this is part of the litrpc.StatusServer interface. |
| 53 | +func (s *Manager) SubServerStatus(_ context.Context, |
| 54 | + _ *litrpc.SubServerStatusReq) (*litrpc.SubServerStatusResp, |
| 55 | + error) { |
| 56 | + |
| 57 | + s.mu.RLock() |
| 58 | + defer s.mu.RUnlock() |
| 59 | + |
| 60 | + resp := make(map[string]*litrpc.SubServerStatus, len(s.subServers)) |
| 61 | + for server, status := range s.subServers { |
| 62 | + resp[server] = &litrpc.SubServerStatus{ |
| 63 | + Disabled: status.Disabled, |
| 64 | + Running: status.Running, |
| 65 | + Error: status.Err, |
| 66 | + } |
| 67 | + } |
| 68 | + |
| 69 | + return &litrpc.SubServerStatusResp{ |
| 70 | + SubServers: resp, |
| 71 | + }, nil |
| 72 | +} |
| 73 | + |
| 74 | +// RegisterSubServer will create a new sub-server entry for the Manager to |
| 75 | +// keep track of. |
| 76 | +func (s *Manager) RegisterSubServer(name string) { |
| 77 | + s.mu.RLock() |
| 78 | + defer s.mu.RUnlock() |
| 79 | + |
| 80 | + s.subServers[name] = newSubServerStatus() |
| 81 | +} |
| 82 | + |
| 83 | +// RegisterAndEnableSubServer will create a new sub-server entry for the |
| 84 | +// Manager to keep track of and will set it as enabled. |
| 85 | +func (s *Manager) RegisterAndEnableSubServer(name string) { |
| 86 | + s.mu.RLock() |
| 87 | + defer s.mu.RUnlock() |
| 88 | + |
| 89 | + ss := newSubServerStatus() |
| 90 | + ss.Disabled = false |
| 91 | + |
| 92 | + s.subServers[name] = ss |
| 93 | + |
| 94 | +} |
| 95 | + |
| 96 | +// GetStatus returns the current status of a given sub-server. This will |
| 97 | +// silently fail if the referenced sub-server has not yet been registered. |
| 98 | +func (s *Manager) GetStatus(name string) (*SubServerStatus, error) { |
| 99 | + s.mu.RLock() |
| 100 | + defer s.mu.RUnlock() |
| 101 | + |
| 102 | + status, ok := s.subServers[name] |
| 103 | + if !ok { |
| 104 | + return nil, errors.New("a sub-server with name %s has not " + |
| 105 | + "yet been registered") |
| 106 | + } |
| 107 | + |
| 108 | + return status, nil |
| 109 | +} |
| 110 | + |
| 111 | +// SetEnabled marks the sub-server with the given name as enabled. |
| 112 | +// |
| 113 | +// NOTE: This will silently fail if the referenced sub-server has not yet been |
| 114 | +// registered. |
| 115 | +func (s *Manager) SetEnabled(name string) { |
| 116 | + s.mu.Lock() |
| 117 | + defer s.mu.Unlock() |
| 118 | + |
| 119 | + log.Debugf("Setting the %s sub-server as enabled", name) |
| 120 | + |
| 121 | + ss, ok := s.subServers[name] |
| 122 | + if !ok { |
| 123 | + return |
| 124 | + } |
| 125 | + |
| 126 | + ss.Disabled = false |
| 127 | +} |
| 128 | + |
| 129 | +// SetRunning can be used to set the status of a sub-server as Running |
| 130 | +// with no errors. |
| 131 | +// |
| 132 | +// NOTE: This will silently fail if the referenced sub-server has not yet been |
| 133 | +// registered. |
| 134 | +func (s *Manager) SetRunning(name string) { |
| 135 | + s.mu.Lock() |
| 136 | + defer s.mu.Unlock() |
| 137 | + |
| 138 | + log.Debugf("Setting the %s sub-server as running", name) |
| 139 | + |
| 140 | + ss, ok := s.subServers[name] |
| 141 | + if !ok { |
| 142 | + return |
| 143 | + } |
| 144 | + |
| 145 | + ss.Running = true |
| 146 | +} |
| 147 | + |
| 148 | +// SetStopped can be used to set the status of a sub-server as not Running and |
| 149 | +// with no errors. |
| 150 | +// |
| 151 | +// NOTE: This will silently fail if the referenced sub-server has not yet been |
| 152 | +// registered. |
| 153 | +func (s *Manager) SetStopped(name string) { |
| 154 | + s.mu.Lock() |
| 155 | + defer s.mu.Unlock() |
| 156 | + |
| 157 | + log.Debugf("Setting the %s sub-server as stopped", name) |
| 158 | + |
| 159 | + ss, ok := s.subServers[name] |
| 160 | + if !ok { |
| 161 | + return |
| 162 | + } |
| 163 | + |
| 164 | + ss.Running = false |
| 165 | + ss.Err = "" |
| 166 | +} |
| 167 | + |
| 168 | +// SetErrored can be used to set the status of a sub-server as not Running |
| 169 | +// and also to set an error message for the sub-server. |
| 170 | +// |
| 171 | +// NOTE: This will silently fail if the referenced sub-server has not yet been |
| 172 | +// registered. |
| 173 | +func (s *Manager) SetErrored(name string, errStr string, |
| 174 | + params ...interface{}) { |
| 175 | + |
| 176 | + s.mu.Lock() |
| 177 | + defer s.mu.Unlock() |
| 178 | + |
| 179 | + log.Debugf("Setting the %s sub-server as errored: %s", name, errStr) |
| 180 | + |
| 181 | + ss, ok := s.subServers[name] |
| 182 | + if !ok { |
| 183 | + return |
| 184 | + } |
| 185 | + |
| 186 | + err := fmt.Sprintf(errStr, params...) |
| 187 | + log.Errorf("could not start the %s sub-server: %s", name, err) |
| 188 | + |
| 189 | + ss.Running = false |
| 190 | + ss.Err = err |
| 191 | +} |
0 commit comments