github.com/awesome-flow/flow@v0.0.3-0.20190918184116-508d75d68a2c/web/app/http.go (about)

     1  package app
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	core "github.com/awesome-flow/flow/pkg/corev1alpha1"
     8  	"github.com/awesome-flow/flow/pkg/types"
     9  	"github.com/awesome-flow/flow/web/app/agent"
    10  )
    11  
    12  type HttpMux struct {
    13  	ctx    *core.Context
    14  	server *http.Server
    15  	agents agent.WebAgents
    16  	done   chan struct{}
    17  }
    18  
    19  var _ core.Runner = (*HttpMux)(nil)
    20  
    21  func NewHttpMux(ctx *core.Context) (*HttpMux, error) {
    22  	syscfg, ok := ctx.Config().Get(types.NewKey("system"))
    23  	if !ok {
    24  		return nil, fmt.Errorf("failed to get system config from the pipeline context")
    25  	}
    26  
    27  	srvMx := http.NewServeMux()
    28  	regs := agent.AllAgentRegistrators()
    29  	agents := make(agent.WebAgents, 0, len(regs))
    30  
    31  	for _, ar := range regs {
    32  		wa, err := ar(ctx)
    33  		if err != nil {
    34  			return nil, err
    35  		}
    36  		srvMx.Handle(wa.GetPath(), wa.GetHandler())
    37  		agents = append(agents, wa)
    38  	}
    39  
    40  	server := &http.Server{
    41  		Addr:    syscfg.(types.CfgBlockSystem).Admin.Bind,
    42  		Handler: srvMx,
    43  	}
    44  
    45  	return &HttpMux{
    46  		ctx:    ctx,
    47  		server: server,
    48  		agents: agents,
    49  		done:   make(chan struct{}),
    50  	}, nil
    51  }
    52  
    53  func (h *HttpMux) Start() error {
    54  	for _, wa := range h.agents {
    55  		if err := wa.Start(); err != nil {
    56  			return err
    57  		}
    58  	}
    59  	go func() {
    60  		if err := h.server.ListenAndServe(); err != nil {
    61  			switch err {
    62  			case http.ErrServerClosed:
    63  				h.ctx.Logger().Info("admin server closed")
    64  			default:
    65  				h.ctx.Logger().Fatal("admin server critical error: %s", err)
    66  			}
    67  			close(h.done)
    68  		}
    69  	}()
    70  
    71  	return nil
    72  }
    73  
    74  func (h *HttpMux) Stop() error {
    75  	for _, wa := range h.agents {
    76  		if err := wa.Stop(); err != nil {
    77  			return err
    78  		}
    79  	}
    80  
    81  	err := h.server.Close()
    82  	<-h.done
    83  
    84  	return err
    85  }