github.com/matrixorigin/matrixone@v1.2.0/pkg/proxy/server.go (about)

     1  // Copyright 2021 - 2023 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package proxy
    16  
    17  import (
    18  	"context"
    19  	"github.com/matrixorigin/matrixone/pkg/util"
    20  	"time"
    21  
    22  	"github.com/fagongzi/goetty/v2"
    23  	"github.com/matrixorigin/matrixone/pkg/common/runtime"
    24  	"github.com/matrixorigin/matrixone/pkg/common/stopper"
    25  	"github.com/matrixorigin/matrixone/pkg/frontend"
    26  	"github.com/matrixorigin/matrixone/pkg/logservice"
    27  	"github.com/matrixorigin/matrixone/pkg/util/metric/stats"
    28  	"github.com/matrixorigin/matrixone/pkg/version"
    29  )
    30  
    31  var statsFamilyName = "proxy counter"
    32  
    33  type Server struct {
    34  	runtime runtime.Runtime
    35  	stopper *stopper.Stopper
    36  	config  Config
    37  	app     goetty.NetApplication
    38  
    39  	// handler handles the client connection.
    40  	handler *handler
    41  	// counterSet counts the events in proxy.
    42  	counterSet     *counterSet
    43  	haKeeperClient logservice.ProxyHAKeeperClient
    44  	// configData will be sent to HAKeeper.
    45  	configData *util.ConfigData
    46  }
    47  
    48  // NewServer creates the proxy server.
    49  //
    50  // NB: runtime must be included in opts.
    51  func NewServer(ctx context.Context, config Config, opts ...Option) (*Server, error) {
    52  	config.FillDefault()
    53  	if err := config.Validate(); err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	frontend.InitServerVersion(version.Version)
    58  
    59  	configKVMap, _ := dumpProxyConfig(config)
    60  	opts = append(opts, WithConfigData(configKVMap))
    61  
    62  	s := &Server{
    63  		config:     config,
    64  		counterSet: newCounterSet(),
    65  	}
    66  	for _, opt := range opts {
    67  		opt(s)
    68  	}
    69  	if s.runtime == nil {
    70  		panic("runtime of proxy is not set")
    71  	}
    72  
    73  	var err error
    74  	if s.haKeeperClient == nil {
    75  		ctx, cancel := context.WithTimeout(ctx, time.Second*3)
    76  		defer cancel()
    77  		s.haKeeperClient, err = logservice.NewProxyHAKeeperClient(ctx, config.HAKeeper.ClientConfig)
    78  		if err != nil {
    79  			return nil, err
    80  		}
    81  	}
    82  
    83  	logExporter := newCounterLogExporter(s.counterSet)
    84  	stats.Register(statsFamilyName, stats.WithLogExporter(logExporter))
    85  
    86  	s.stopper = stopper.NewStopper("mo-proxy", stopper.WithLogger(s.runtime.Logger().RawLogger()))
    87  	h, err := newProxyHandler(ctx, s.runtime, s.config, s.stopper, s.counterSet, s.haKeeperClient)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	go h.bootstrap(ctx)
    93  
    94  	if err := s.stopper.RunNamedTask("proxy heartbeat", s.heartbeat); err != nil {
    95  		return nil, err
    96  	}
    97  
    98  	s.handler = h
    99  	app, err := goetty.NewApplication(config.ListenAddress, nil,
   100  		goetty.WithAppLogger(s.runtime.Logger().RawLogger()),
   101  		goetty.WithAppHandleSessionFunc(s.handler.handle),
   102  		goetty.WithAppSessionOptions(
   103  			goetty.WithSessionCodec(WithProxyProtocolCodec(frontend.NewSqlCodec())),
   104  			goetty.WithSessionLogger(s.runtime.Logger().RawLogger()),
   105  		),
   106  	)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	s.app = app
   111  	return s, nil
   112  }
   113  
   114  // Start starts the proxy server.
   115  func (s *Server) Start() error {
   116  	return s.app.Start()
   117  }
   118  
   119  // Close closes the proxy server.
   120  func (s *Server) Close() error {
   121  	_ = s.handler.Close()
   122  	s.stopper.Stop()
   123  	stats.Unregister(statsFamilyName)
   124  	return s.app.Stop()
   125  }