77 "encoding/json"
88 "errors"
99 "fmt"
10- "net"
1110 "net/http"
1211 "net/url"
1312 "os"
@@ -38,16 +37,17 @@ type Services struct {
3837}
3938
4039type BootstrapApp struct {
41- config model.Config
42- runtime model.RuntimeConfig
43- services Services
44- log * logger.Logger
45- ctx context.Context
46- cancel context.CancelFunc
47- queries * repository.Queries
48- router * gin.Engine
49- db * sql.DB
50- wg sync.WaitGroup
40+ config model.Config
41+ runtime model.RuntimeConfig
42+ services Services
43+ log * logger.Logger
44+ ctx context.Context
45+ cancel context.CancelFunc
46+ queries * repository.Queries
47+ router * gin.Engine
48+ db * sql.DB
49+ wg sync.WaitGroup
50+ listeners []Listener
5151}
5252
5353func NewBootstrapApp (config model.Config ) * BootstrapApp {
@@ -254,56 +254,32 @@ func (app *BootstrapApp) Setup() error {
254254 app .wg .Go (app .heartbeatRoutine )
255255 }
256256
257- // create err channel to listen for server errors
258- errChanLen := 0
259-
257+ // setup listeners
260258 runUnix := app .config .Server .SocketPath != ""
261259 runHTTP := app .config .Server .SocketPath == "" || app .config .Server .ConcurrentListenersEnabled
262260 runTailscale := app .services .tailscaleService != nil
263261
264- if runUnix {
265- errChanLen ++
262+ if runHTTP {
263+ app . listeners = append ( app . listeners , ListenerHTTP )
266264 }
267265
268- if runHTTP {
269- errChanLen ++
266+ if runUnix {
267+ app . listeners = append ( app . listeners , ListenerUnix )
270268 }
271269
272270 if runTailscale {
273- errChanLen ++
271+ app . listeners = append ( app . listeners , ListenerTailscale )
274272 }
275273
276- errChan := make (chan error , errChanLen )
277-
278274 if app .config .Server .ConcurrentListenersEnabled {
279275 app .log .App .Info ().Msg ("Concurrent listeners enabled, will run on all available listeners" )
280276 }
281277
282- // serve unix
283- if runUnix {
284- app .wg .Go (func () {
285- if err := app .serveUnix (); err != nil {
286- errChan <- err
287- }
288- })
289- }
290-
291- // serve to http
292- if runHTTP {
293- app .wg .Go (func () {
294- if err := app .serveHTTP (); err != nil {
295- errChan <- err
296- }
297- })
298- }
278+ // run listeners
279+ lec , err := app .runListeners ()
299280
300- // serve to tailscale
301- if runTailscale {
302- app .wg .Go (func () {
303- if err := app .serveTailscale (); err != nil {
304- errChan <- err
305- }
306- })
281+ if err != nil {
282+ return fmt .Errorf ("failed to run listeners: %w" , err )
307283 }
308284
309285 // monitor cancellation and server errors
@@ -312,123 +288,14 @@ func (app *BootstrapApp) Setup() error {
312288 case <- app .ctx .Done ():
313289 app .log .App .Info ().Msg ("Oh, it's time for me to go, bye!" )
314290 return nil
315- case err := <- errChan :
291+ case err := <- lec :
316292 if err != nil {
317- return fmt .Errorf ("server error: %w" , err )
293+ return fmt .Errorf ("listener error: %w" , err )
318294 }
319295 }
320296 }
321297}
322298
323- func (app * BootstrapApp ) serveHTTP () error {
324- address := fmt .Sprintf ("%s:%d" , app .config .Server .Address , app .config .Server .Port )
325-
326- app .log .App .Info ().Msgf ("Starting server on %s" , address )
327-
328- server := & http.Server {
329- Addr : address ,
330- Handler : app .router .Handler (),
331- }
332-
333- go func () {
334- <- app .ctx .Done ()
335- app .log .App .Debug ().Msg ("Shutting down http listener" )
336- server .Shutdown (app .ctx )
337- }()
338-
339- err := server .ListenAndServe ()
340-
341- if err != nil && ! errors .Is (err , http .ErrServerClosed ) {
342- return fmt .Errorf ("failed to start http listener: %w" , err )
343- }
344-
345- return nil
346- }
347-
348- func (app * BootstrapApp ) serveUnix () error {
349- if app .config .Server .SocketPath == "" {
350- return nil
351- }
352-
353- _ , err := os .Stat (app .config .Server .SocketPath )
354-
355- if err == nil {
356- app .log .App .Info ().Msgf ("Removing existing socket file %s" , app .config .Server .SocketPath )
357- err := os .Remove (app .config .Server .SocketPath )
358-
359- if err != nil {
360- return fmt .Errorf ("failed to remove existing socket file: %w" , err )
361- }
362- }
363-
364- app .log .App .Info ().Msgf ("Starting server on unix socket %s" , app .config .Server .SocketPath )
365-
366- listener , err := net .Listen ("unix" , app .config .Server .SocketPath )
367-
368- if err != nil {
369- return fmt .Errorf ("failed to create unix socket listener: %w" , err )
370- }
371-
372- server := & http.Server {
373- Handler : app .router .Handler (),
374- }
375-
376- shutdown := func () {
377- server .Shutdown (app .ctx )
378- listener .Close ()
379- os .Remove (app .config .Server .SocketPath )
380- }
381-
382- go func () {
383- <- app .ctx .Done ()
384- app .log .App .Debug ().Msg ("Shutting down unix socket listener" )
385- shutdown ()
386- }()
387-
388- err = server .Serve (listener )
389-
390- if err != nil && ! errors .Is (err , http .ErrServerClosed ) {
391- shutdown ()
392- return fmt .Errorf ("failed to start unix socket listener: %w" , err )
393- }
394-
395- return nil
396- }
397-
398- func (app * BootstrapApp ) serveTailscale () error {
399- app .log .App .Info ().Msgf ("Starting Tailscale server on %s" , fmt .Sprintf ("https://%s" , app .services .tailscaleService .GetHostname ()))
400-
401- listener , err := app .services .tailscaleService .CreateListener ()
402-
403- if err != nil {
404- return fmt .Errorf ("failed to create tailscale listener: %w" , err )
405- }
406-
407- server := & http.Server {
408- Handler : app .router .Handler (),
409- }
410-
411- shutdown := func () {
412- server .Shutdown (app .ctx )
413- listener .Close ()
414- }
415-
416- go func () {
417- <- app .ctx .Done ()
418- app .log .App .Debug ().Msg ("Shutting down Tailscale listener" )
419- shutdown ()
420- }()
421-
422- err = server .Serve (listener )
423-
424- if err != nil && ! errors .Is (err , http .ErrServerClosed ) {
425- shutdown ()
426- return fmt .Errorf ("failed to start tailscale listener: %w" , err )
427- }
428-
429- return nil
430- }
431-
432299func (app * BootstrapApp ) heartbeatRoutine () {
433300 ticker := time .NewTicker (time .Duration (12 ) * time .Hour )
434301 defer ticker .Stop ()
0 commit comments