| 233 | } |
| 234 | |
| 235 | func (m *SessionModule) SetRunning(running bool, cb func()) error { |
| 236 | if running == m.Running() { |
| 237 | if m.Started { |
| 238 | return ErrAlreadyStarted(m.Name) |
| 239 | } else { |
| 240 | return ErrAlreadyStopped(m.Name) |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | if running == true { |
| 245 | for _, modName := range m.Required() { |
| 246 | if m.Session.IsOn(modName) == false { |
| 247 | m.Info("starting %s as a requirement for %s", modName, m.Name) |
| 248 | if err := m.Session.Run(modName + " on"); err != nil { |
| 249 | return fmt.Errorf("error while starting module %s as a requirement for %s: %v", modName, m.Name, err) |
| 250 | } |
| 251 | } |
| 252 | } |
| 253 | } |
| 254 | |
| 255 | m.StatusLock.Lock() |
| 256 | m.Started = running |
| 257 | m.StatusLock.Unlock() |
| 258 | |
| 259 | if running { |
| 260 | m.Session.Events.Add("mod.started", m.Name) |
| 261 | } else { |
| 262 | m.Session.Events.Add("mod.stopped", m.Name) |
| 263 | } |
| 264 | |
| 265 | if cb != nil { |
| 266 | if running { |
| 267 | // this is the worker, start async |
| 268 | go cb() |
| 269 | } else { |
| 270 | // stop callback, this is sync with a 10 seconds timeout |
| 271 | done := make(chan bool, 1) |
| 272 | go func() { |
| 273 | cb() |
| 274 | done <- true |
| 275 | }() |
| 276 | |
| 277 | select { |
| 278 | case <-done: |
| 279 | return nil |
| 280 | case <-time.After(10 * time.Second): |
| 281 | fmt.Printf("%s: Stopping module %s timed out.\n", tui.Yellow(tui.Bold("WARNING")), m.Name) |
| 282 | } |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | return nil |
| 287 | } |
| 288 | |
| 289 | type moduleJSON struct { |
| 290 | Name string `json:"name"` |