guerrilla.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. package guerrilla
  2. import (
  3. "errors"
  4. "fmt"
  5. "os"
  6. "strings"
  7. "sync"
  8. "sync/atomic"
  9. "github.com/flashmob/go-guerrilla/backends"
  10. "github.com/flashmob/go-guerrilla/log"
  11. )
  12. const (
  13. // all configured servers were just been created
  14. daemonStateNew = iota
  15. // ... been started and running
  16. daemonStateStarted
  17. // ... been stopped
  18. daemonStateStopped
  19. )
  20. type Errors []error
  21. // implement the Error interface
  22. func (e Errors) Error() string {
  23. if len(e) == 1 {
  24. return e[0].Error()
  25. }
  26. // multiple errors
  27. msg := ""
  28. for _, err := range e {
  29. msg += "\n" + err.Error()
  30. }
  31. return msg
  32. }
  33. type Guerrilla interface {
  34. Start() error
  35. Shutdown()
  36. Subscribe(topic Event, fn interface{}) error
  37. Publish(topic Event, args ...interface{})
  38. Unsubscribe(topic Event, handler interface{}) error
  39. SetLogger(log.Logger)
  40. }
  41. type guerrilla struct {
  42. Config AppConfig
  43. servers map[string]*server
  44. // guard controls access to g.servers
  45. guard sync.Mutex
  46. state int8
  47. EventHandler
  48. logStore
  49. beGuard sync.Mutex
  50. backends BackendContainer
  51. }
  52. type logStore struct {
  53. atomic.Value
  54. }
  55. type BackendContainer map[string]backends.Backend
  56. type daemonEvent func(c *AppConfig)
  57. type serverEvent func(sc *ServerConfig)
  58. type backendEvent func(c *AppConfig, gateway string)
  59. // Get loads the log.logger in an atomic operation. Returns a stderr logger if not able to load
  60. func (ls *logStore) mainlog() log.Logger {
  61. if v, ok := ls.Load().(log.Logger); ok {
  62. return v
  63. }
  64. l, _ := log.GetLogger(log.OutputStderr.String(), log.InfoLevel.String())
  65. return l
  66. }
  67. // setMainlog stores the log value in an atomic operation
  68. func (ls *logStore) setMainlog(log log.Logger) {
  69. ls.Store(log)
  70. }
  71. // makeConfiguredBackends makes backends from the config
  72. func (g *guerrilla) makeConfiguredBackends(l log.Logger) ([]backends.Backend, error) {
  73. var list []backends.Backend
  74. config := g.Config.BackendConfig[backends.ConfigGateways]
  75. if len(config) == 0 {
  76. return list, errors.New("no backends configured")
  77. }
  78. list = make([]backends.Backend, 0)
  79. for name := range config {
  80. if b, err := backends.New(name, g.Config.BackendConfig, l); err != nil {
  81. return nil, err
  82. } else {
  83. list = append(list, b)
  84. }
  85. }
  86. return list, nil
  87. }
  88. // New creates a new Guerrilla instance configured with backends and a logger
  89. // Returns a new instance of Guerrilla with the given config, not yet running. Backend started.
  90. // b can be nil. If nil. then it will use the config to make the backends
  91. func New(ac *AppConfig, l log.Logger, b ...backends.Backend) (Guerrilla, error) {
  92. g := &guerrilla{
  93. Config: *ac, // take a local copy
  94. servers: make(map[string]*server, len(ac.Servers)),
  95. }
  96. if 0 == len(b) {
  97. var err error
  98. b, err = g.makeConfiguredBackends(l)
  99. if err != nil {
  100. return g, err
  101. }
  102. }
  103. if g.backends == nil {
  104. g.backends = make(BackendContainer)
  105. }
  106. for i := range b {
  107. if b[i] == nil {
  108. return g, errors.New("cannot use a nil backend")
  109. }
  110. g.storeBackend(b[i])
  111. }
  112. g.setMainlog(l)
  113. if ac.LogLevel != "" {
  114. if h, ok := l.(*log.HookedLogger); ok {
  115. if h, err := log.GetLogger(h.GetLogDest(), ac.LogLevel); err == nil {
  116. g.setMainlog(h)
  117. }
  118. }
  119. }
  120. // Write the process id (pid) to a file
  121. // we should still be able to continue even if we can't write the pid, error will be logged by writePid()
  122. _ = g.writePid()
  123. g.state = daemonStateNew
  124. err := g.makeServers()
  125. if err != nil {
  126. return g, err
  127. }
  128. // start backends for processing email
  129. _, err = g.mapBackends(func(b backends.Backend) error {
  130. return b.Start()
  131. })
  132. if err != nil {
  133. return g, err
  134. }
  135. // subscribe for any events that may come in while running
  136. g.subscribeEvents()
  137. return g, err
  138. }
  139. // Instantiate servers
  140. func (g *guerrilla) makeServers() error {
  141. g.mainlog().Debug("making servers")
  142. var errs Errors
  143. for serverID, sc := range g.Config.Servers {
  144. if _, ok := g.servers[sc.ListenInterface]; ok {
  145. // server already instantiated
  146. continue
  147. }
  148. if err := sc.Validate(); err != nil {
  149. g.mainlog().Fields("error", errs, "iface", sc.ListenInterface).
  150. Error("failed to create server")
  151. errs = append(errs, err)
  152. continue
  153. } else {
  154. sc := sc // pin!
  155. server, err := newServer(&sc, g.backend(sc.Gateway), g.mainlog(), serverID)
  156. if err != nil {
  157. g.mainlog().Fields("error", err, "iface", sc.ListenInterface).
  158. Error("failed to create server")
  159. errs = append(errs, err)
  160. }
  161. if server != nil {
  162. g.servers[sc.ListenInterface] = server
  163. server.setAllowedHosts(g.Config.AllowedHosts)
  164. }
  165. }
  166. }
  167. if len(g.servers) == 0 {
  168. errs = append(errs, errors.New("there are no servers that can start, please check your config"))
  169. }
  170. if len(errs) == 0 {
  171. return nil
  172. }
  173. return errs
  174. }
  175. // findServer finds a server by iface (interface), retuning the server or err
  176. func (g *guerrilla) findServer(iface string) (*server, error) {
  177. g.guard.Lock()
  178. defer g.guard.Unlock()
  179. if server, ok := g.servers[iface]; ok {
  180. return server, nil
  181. }
  182. return nil, errors.New("server not found in g.servers")
  183. }
  184. // removeServer removes a server from the list of servers
  185. func (g *guerrilla) removeServer(iface string) {
  186. g.guard.Lock()
  187. defer g.guard.Unlock()
  188. delete(g.servers, iface)
  189. }
  190. // setConfig sets the app config
  191. func (g *guerrilla) setConfig(c *AppConfig) {
  192. g.guard.Lock()
  193. defer g.guard.Unlock()
  194. g.Config = *c
  195. }
  196. // setServerConfig config updates the server's config, which will update for the next connected client
  197. func (g *guerrilla) setServerConfig(sc *ServerConfig) {
  198. g.guard.Lock()
  199. defer g.guard.Unlock()
  200. if _, ok := g.servers[sc.ListenInterface]; ok {
  201. g.servers[sc.ListenInterface].setConfig(sc)
  202. }
  203. }
  204. // mapServers calls a callback on each server in g.servers map
  205. // It locks the g.servers map before mapping
  206. func (g *guerrilla) mapServers(callback func(*server)) map[string]*server {
  207. defer g.guard.Unlock()
  208. g.guard.Lock()
  209. for _, server := range g.servers {
  210. callback(server)
  211. }
  212. return g.servers
  213. }
  214. type mapBackendErrors []error
  215. func (e mapBackendErrors) Error() string {
  216. data := make([]string, len(e))
  217. for i, s := range e {
  218. data[i] = fmt.Sprint(s)
  219. }
  220. return strings.Join(data, ",")
  221. }
  222. func (g *guerrilla) mapBackends(callback func(backend backends.Backend) error) (BackendContainer, error) {
  223. defer g.beGuard.Unlock()
  224. g.beGuard.Lock()
  225. var e mapBackendErrors
  226. for name := range g.backends {
  227. if err := callback(g.backends[name]); err != nil {
  228. e = append(e, err)
  229. }
  230. }
  231. if len(e) == 0 {
  232. return g.backends, nil
  233. }
  234. return g.backends, e
  235. }
  236. // subscribeEvents subscribes event handlers for configuration change events
  237. func (g *guerrilla) subscribeEvents() {
  238. events := map[Event]interface{}{}
  239. // main config changed
  240. events[EventConfigNewConfig] = daemonEvent(func(c *AppConfig) {
  241. g.setConfig(c)
  242. })
  243. // allowed_hosts changed, set for all servers
  244. events[EventConfigAllowedHosts] = daemonEvent(func(c *AppConfig) {
  245. g.mapServers(func(server *server) {
  246. server.setAllowedHosts(c.AllowedHosts)
  247. g.mainlog().Fields("serverID", server.serverID, "event", EventConfigAllowedHosts).
  248. Info("allowed_hosts config changed, a new list was set")
  249. })
  250. })
  251. // the main log file changed
  252. events[EventConfigLogFile] = daemonEvent(func(c *AppConfig) {
  253. var err error
  254. var l log.Logger
  255. if l, err = log.GetLogger(c.LogFile, c.LogLevel); err == nil {
  256. g.setMainlog(l)
  257. g.mapServers(func(server *server) {
  258. // it will change server's logger when the next client gets accepted
  259. server.mainlogStore.Store(l)
  260. })
  261. g.mainlog().Fields("file", c.LogFile).
  262. Info("main log for new clients changed")
  263. } else {
  264. g.mainlog().Fields("error", err, "file", c.LogFile).
  265. Error("main logging change failed")
  266. }
  267. })
  268. // re-open the main log file (file not changed)
  269. events[EventConfigLogReopen] = daemonEvent(func(c *AppConfig) {
  270. err := g.mainlog().Reopen()
  271. if err != nil {
  272. g.mainlog().Fields("error", err, "file", c.LogFile).
  273. Error("main log file failed to re-open")
  274. return
  275. }
  276. g.mainlog().Fields("file", c.LogFile).Info("re-opened main log file")
  277. })
  278. // when log level changes, apply to mainlog and server logs
  279. events[EventConfigLogLevel] = daemonEvent(func(c *AppConfig) {
  280. l, err := log.GetLogger(g.mainlog().GetLogDest(), c.LogLevel)
  281. if err == nil {
  282. g.logStore.Store(l)
  283. g.mapServers(func(server *server) {
  284. server.logStore.Store(l)
  285. })
  286. g.mainlog().Fields("level", c.LogLevel).Info("log level changed")
  287. }
  288. })
  289. // write out our pid whenever the file name changes in the config
  290. events[EventConfigPidFile] = daemonEvent(func(ac *AppConfig) {
  291. _ = g.writePid()
  292. })
  293. // server config was updated
  294. events[EventConfigServerConfig] = serverEvent(func(sc *ServerConfig) {
  295. g.setServerConfig(sc)
  296. g.mainlog().Fields("iface", sc.ListenInterface).
  297. Info("server config change event, a new config has been saved")
  298. })
  299. // add a new server to the config & start
  300. events[EventConfigServerNew] = serverEvent(func(sc *ServerConfig) {
  301. values := []interface{}{"iface", sc.ListenInterface, "event", EventConfigServerNew}
  302. g.mainlog().Fields(values...).
  303. Debug("event fired")
  304. if _, err := g.findServer(sc.ListenInterface); err != nil {
  305. // not found, lets add it
  306. if err := g.makeServers(); err != nil {
  307. g.mainlog().Fields(append(values, "error", err)...).
  308. Error("cannot add server")
  309. return
  310. }
  311. g.mainlog().Fields(values...).Info("new server added")
  312. if g.state == daemonStateStarted {
  313. err := g.Start()
  314. if err != nil {
  315. g.mainlog().Fields(append(values, "error", err)...).
  316. Error("new server errors when starting")
  317. }
  318. }
  319. } else {
  320. g.mainlog().Fields(values...).
  321. Debug("new event, but server already fund")
  322. }
  323. })
  324. // start a server that already exists in the config and has been enabled
  325. events[EventConfigServerStart] = serverEvent(func(sc *ServerConfig) {
  326. if server, err := g.findServer(sc.ListenInterface); err == nil {
  327. fields := []interface{}{
  328. "iface", server.listenInterface,
  329. "serverID", server.serverID,
  330. "event", EventConfigServerStart}
  331. if server.state == ServerStateStopped || server.state == ServerStateNew {
  332. g.mainlog().Fields(fields...).
  333. Info("starting server")
  334. err := g.Start()
  335. if err != nil {
  336. g.mainlog().Fields(append(fields, "error", err)...).
  337. Info("event server_change:start_server returned errors when starting")
  338. }
  339. }
  340. }
  341. })
  342. // stop running a server
  343. events[EventConfigServerStop] = serverEvent(func(sc *ServerConfig) {
  344. if server, err := g.findServer(sc.ListenInterface); err == nil {
  345. if server.state == ServerStateRunning {
  346. server.Shutdown()
  347. g.mainlog().Fields(
  348. "event", EventConfigServerStop,
  349. "server", sc.ListenInterface,
  350. "serverID", server.serverID).
  351. Info("server stopped.")
  352. }
  353. }
  354. })
  355. // server was removed from config
  356. events[EventConfigServerRemove] = serverEvent(func(sc *ServerConfig) {
  357. if server, err := g.findServer(sc.ListenInterface); err == nil {
  358. server.Shutdown()
  359. g.removeServer(sc.ListenInterface)
  360. g.mainlog().Fields(
  361. "event", EventConfigServerRemove,
  362. "server", sc.ListenInterface,
  363. "serverID", server.serverID).
  364. Info("server removed from config, stopped it")
  365. }
  366. })
  367. // TLS changes
  368. events[EventConfigServerTLSConfig] = serverEvent(func(sc *ServerConfig) {
  369. if server, err := g.findServer(sc.ListenInterface); err == nil {
  370. fields := []interface{}{
  371. "iface", server.listenInterface,
  372. "serverID", server.serverID,
  373. "event", EventConfigServerTLSConfig}
  374. if err := server.configureTLS(); err == nil {
  375. g.mainlog().Fields(fields...).Info("server new TLS configuration loaded")
  376. } else {
  377. g.mainlog().Fields(append(fields, "error", err)...).
  378. Error("Server failed to load the new TLS configuration")
  379. }
  380. }
  381. })
  382. // when server's timeout change.
  383. events[EventConfigServerTimeout] = serverEvent(func(sc *ServerConfig) {
  384. g.mapServers(func(server *server) {
  385. fields := []interface{}{
  386. "iface", server.listenInterface,
  387. "serverID", server.serverID,
  388. "event", EventConfigServerTimeout,
  389. "timeout", sc.Timeout,
  390. }
  391. server.setTimeout(sc.Timeout)
  392. g.mainlog().Fields(fields...).Info("server timeout set")
  393. })
  394. })
  395. // when server's max clients change.
  396. events[EventConfigServerMaxClients] = serverEvent(func(sc *ServerConfig) {
  397. g.mapServers(func(server *server) {
  398. // TODO resize the pool somehow
  399. })
  400. })
  401. // when a server's log file changes
  402. events[EventConfigServerLogFile] = serverEvent(func(sc *ServerConfig) {
  403. if server, err := g.findServer(sc.ListenInterface); err == nil {
  404. var err error
  405. var l log.Logger
  406. level := g.mainlog().GetLevel()
  407. fields := []interface{}{
  408. "iface", server.listenInterface,
  409. "serverID", server.serverID,
  410. "event", EventConfigServerLogFile,
  411. "file", sc.LogFile,
  412. }
  413. if l, err = log.GetLogger(sc.LogFile, level); err == nil {
  414. g.setMainlog(l)
  415. backends.Svc.SetMainlog(l)
  416. // it will change to the new logger on the next accepted client
  417. server.logStore.Store(l)
  418. g.mainlog().Fields(fields...).Info("server log changed",
  419. sc.ListenInterface,
  420. sc.LogFile,
  421. )
  422. } else {
  423. g.mainlog().Fields(append(fields, "error", err)...).Error(
  424. "server log change failed")
  425. }
  426. }
  427. })
  428. // when the daemon caught a sighup, event for individual server
  429. events[EventConfigServerLogReopen] = serverEvent(func(sc *ServerConfig) {
  430. if server, err := g.findServer(sc.ListenInterface); err == nil {
  431. fields := []interface{}{"file", sc.LogFile,
  432. "iface", sc.ListenInterface,
  433. "serverID", server.serverID,
  434. "file", sc.LogFile,
  435. "event", EventConfigServerLogReopen}
  436. if err = server.log().Reopen(); err != nil {
  437. g.mainlog().Fields(
  438. append(fields, "error", err)...).
  439. Error("server log file failed to re-open")
  440. return
  441. }
  442. g.mainlog().Fields(fields).Info("server re-opened log file")
  443. }
  444. })
  445. // when the server's gateway setting changed
  446. events[EventConfigServerGatewayConfig] = serverEvent(func(sc *ServerConfig) {
  447. b := g.backend(sc.Gateway)
  448. if b == nil {
  449. g.mainlog().Fields("gateway", sc.Gateway, "event", EventConfigServerGatewayConfig).
  450. Error("could not change to gateway, not configured")
  451. return
  452. }
  453. g.storeBackend(b)
  454. })
  455. revertIfError := func(err error, name string, logger log.Logger, g *guerrilla) {
  456. if err != nil {
  457. logger.Fields("error", err, "gateway", name, "event", EventConfigServerGatewayConfig).
  458. Error("cannot change gateway config, reverting to old config")
  459. err = g.backend(name).Reinitialize()
  460. if err != nil {
  461. logger.Fields("error", err, "gateway", name, "event", EventConfigServerGatewayConfig).
  462. Error("failed to revert to old gateway config")
  463. return
  464. }
  465. err = g.backend(name).Start()
  466. if err != nil {
  467. logger.Fields("error", err, "gateway", name, "event", EventConfigServerGatewayConfig).
  468. Error("failed to start gateway with old config")
  469. return
  470. }
  471. logger.Fields("gateway", name, "event", EventConfigServerGatewayConfig).
  472. Info("reverted to old gateway config")
  473. }
  474. }
  475. events[EventConfigBackendConfigChanged] = backendEvent(func(appConfig *AppConfig, name string) {
  476. logger, _ := log.GetLogger(appConfig.LogFile, appConfig.LogLevel)
  477. var err error
  478. // shutdown the backend first.
  479. if err = g.backend(name).Shutdown(); err != nil {
  480. logger.Fields("error", err, "gateway", name, "event", EventConfigBackendConfigChanged).
  481. Error("gateway failed to shutdown")
  482. return // we can't do anything then
  483. }
  484. if newBackend, newErr := backends.New(name, appConfig.BackendConfig, logger); newErr != nil {
  485. err = newErr
  486. revertIfError(newErr, name, logger, g) // revert to old backend
  487. return
  488. } else {
  489. if err = newBackend.Start(); err != nil {
  490. logger.Fields("error", err, "gateway", name, "event", EventConfigBackendConfigChanged).
  491. Error("gateway could not start")
  492. revertIfError(err, name, logger, g) // revert to old backend
  493. return
  494. } else {
  495. logger.Fields("gateway", name, "event", EventConfigBackendConfigChanged).
  496. Info("gateway with new config started")
  497. g.storeBackend(newBackend)
  498. }
  499. }
  500. })
  501. // a new gateway was added
  502. events[EventConfigBackendConfigAdded] = backendEvent(func(appConfig *AppConfig, name string) {
  503. logger, _ := log.GetLogger(appConfig.LogFile, appConfig.LogLevel)
  504. // shutdown any old backend first.
  505. if newBackend, newErr := backends.New(name, appConfig.BackendConfig, logger); newErr != nil {
  506. logger.Fields("error", newErr, "gateway", name, "event", EventConfigBackendConfigAdded).
  507. Error("cannot add new gateway")
  508. } else {
  509. // swap to the bew gateway (assuming old gateway was shutdown so it can be safely swapped)
  510. if err := newBackend.Start(); err != nil {
  511. logger.Fields("error", err, "gateway", name, "event", EventConfigBackendConfigAdded).
  512. Error("cannot start new gateway")
  513. }
  514. logger.Fields("gateway", name).Info("new gateway started")
  515. g.storeBackend(newBackend)
  516. }
  517. })
  518. // remove a gateway (shut it down)
  519. events[EventConfigBackendConfigRemoved] = backendEvent(func(appConfig *AppConfig, name string) {
  520. logger, _ := log.GetLogger(appConfig.LogFile, appConfig.LogLevel)
  521. // shutdown the backend first.
  522. var err error
  523. // revert
  524. defer revertIfError(err, name, logger, g)
  525. if err = g.backend(name).Shutdown(); err != nil {
  526. logger.Fields("error", err, "gateway", name, "event", EventConfigBackendConfigRemoved).
  527. Error("gateway failed to shutdown")
  528. return
  529. }
  530. g.removeBackend(g.backend(name))
  531. logger.Fields("gateway", name, "event", EventConfigBackendConfigRemoved).Info("gateway removed")
  532. })
  533. // subscribe all of the above events
  534. var err error
  535. for topic, fn := range events {
  536. err = g.Subscribe(topic, fn)
  537. if err != nil {
  538. g.mainlog().Fields("error", err, "event", topic).
  539. Error("failed to subscribe on topic")
  540. break
  541. }
  542. }
  543. }
  544. func (g *guerrilla) removeBackend(b backends.Backend) {
  545. g.beGuard.Lock()
  546. defer g.beGuard.Unlock()
  547. delete(g.backends, b.Name())
  548. }
  549. func (g *guerrilla) storeBackend(b backends.Backend) {
  550. g.beGuard.Lock()
  551. defer g.beGuard.Unlock()
  552. g.backends[b.Name()] = b
  553. g.mapServers(func(server *server) {
  554. sc := server.configStore.Load().(ServerConfig)
  555. if b.Name() == sc.Gateway {
  556. server.setBackend(b)
  557. }
  558. })
  559. }
  560. func (g *guerrilla) backend(name string) backends.Backend {
  561. g.beGuard.Lock()
  562. defer g.beGuard.Unlock()
  563. if b, ok := g.backends[name]; ok {
  564. return b
  565. }
  566. // if not found, return a random one
  567. for b := range g.backends {
  568. return g.backends[b]
  569. }
  570. return nil
  571. }
  572. // Entry point for the application. Starts all servers.
  573. func (g *guerrilla) Start() error {
  574. var startErrors Errors
  575. g.guard.Lock()
  576. defer func() {
  577. g.state = daemonStateStarted
  578. g.guard.Unlock()
  579. }()
  580. if len(g.servers) == 0 {
  581. return append(startErrors, errors.New("no servers to start, please check the config"))
  582. }
  583. if g.state == daemonStateStopped {
  584. // when a backend is shutdown, we need to re-initialize before it can be started again
  585. if _, err := g.mapBackends(func(b backends.Backend) error {
  586. if err := b.Reinitialize(); err != nil {
  587. return err
  588. }
  589. return b.Start()
  590. }); err != nil {
  591. startErrors = append(startErrors, err)
  592. }
  593. }
  594. // channel for reading errors
  595. errs := make(chan error, len(g.servers))
  596. var startWG sync.WaitGroup
  597. // start servers, send any errors back to errs channel
  598. for ListenInterface := range g.servers {
  599. if !g.servers[ListenInterface].isEnabled() {
  600. // not enabled
  601. continue
  602. }
  603. if g.servers[ListenInterface].state != ServerStateNew &&
  604. g.servers[ListenInterface].state != ServerStateStopped {
  605. continue
  606. }
  607. startWG.Add(1)
  608. go func(s *server) {
  609. g.mainlog().Fields("iface", s.listenInterface, "serverID", s.serverID).
  610. Info("starting server")
  611. if err := s.Start(&startWG); err != nil {
  612. errs <- err
  613. }
  614. }(g.servers[ListenInterface])
  615. }
  616. // wait for all servers to start (or fail)
  617. startWG.Wait()
  618. // close, then read any errors
  619. close(errs)
  620. for err := range errs {
  621. if err != nil {
  622. startErrors = append(startErrors, err)
  623. }
  624. }
  625. if len(startErrors) > 0 {
  626. return startErrors
  627. }
  628. return nil
  629. }
  630. func (g *guerrilla) Shutdown() {
  631. // shut down the servers first
  632. g.mapServers(func(s *server) {
  633. if s.state == ServerStateRunning {
  634. s.Shutdown()
  635. g.mainlog().Fields("iface", s.listenInterface, "serverID", s.serverID).Info("shutdown completed")
  636. }
  637. })
  638. g.guard.Lock()
  639. defer func() {
  640. g.state = daemonStateStopped
  641. defer g.guard.Unlock()
  642. }()
  643. if _, err := g.mapBackends(func(b backends.Backend) error {
  644. return b.Shutdown()
  645. }); err != nil {
  646. fmt.Println(err)
  647. g.mainlog().Fields("error", err).Error("backend failed to shutdown")
  648. } else {
  649. g.mainlog().Info("backend shutdown completed")
  650. }
  651. }
  652. // SetLogger sets the logger for the app and propagates it to sub-packages (eg.
  653. func (g *guerrilla) SetLogger(l log.Logger) {
  654. g.setMainlog(l)
  655. backends.Svc.SetMainlog(l)
  656. }
  657. // writePid writes the pid (process id) to the file specified in the config.
  658. // Won't write anything if no file specified
  659. func (g *guerrilla) writePid() (err error) {
  660. var f *os.File
  661. defer func() {
  662. if f != nil {
  663. if closeErr := f.Close(); closeErr != nil {
  664. err = closeErr
  665. }
  666. }
  667. if err != nil {
  668. g.mainlog().Fields("error", err, "file", g.Config.PidFile).Error("error while writing pidFile")
  669. }
  670. }()
  671. if len(g.Config.PidFile) > 0 {
  672. if f, err = os.Create(g.Config.PidFile); err != nil {
  673. return err
  674. }
  675. pid := os.Getpid()
  676. if _, err := f.WriteString(fmt.Sprintf("%d", pid)); err != nil {
  677. return err
  678. }
  679. if err = f.Sync(); err != nil {
  680. return err
  681. }
  682. g.mainlog().Fields("file", g.Config.PidFile, "pid", pid).Info("pid_file written")
  683. }
  684. return nil
  685. }
  686. // CheckFileLimit checks the number of files we can open (works on OS'es that support the ulimit command)
  687. func CheckFileLimit(c *AppConfig) (bool, int, uint64) {
  688. fileLimit, err := getFileLimit()
  689. maxClients := 0
  690. if err != nil {
  691. // since we can't get the limit, return true to indicate the check passed
  692. return true, maxClients, fileLimit
  693. }
  694. if c.Servers == nil {
  695. // no servers have been configured, assuming default
  696. maxClients = defaultMaxClients
  697. } else {
  698. for _, s := range c.Servers {
  699. maxClients += s.MaxClients
  700. }
  701. }
  702. if uint64(maxClients) > fileLimit {
  703. return false, maxClients, fileLimit
  704. }
  705. return true, maxClients, fileLimit
  706. }