github.com/matrixorigin/matrixone@v0.7.0/pkg/tests/service/cnservice.go (about)

     1  // Copyright 2022 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 service
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"path/filepath"
    21  	"strconv"
    22  	"sync"
    23  
    24  	"github.com/google/uuid"
    25  	"github.com/matrixorigin/matrixone/pkg/cnservice"
    26  	"github.com/matrixorigin/matrixone/pkg/config"
    27  	"github.com/matrixorigin/matrixone/pkg/fileservice"
    28  	"github.com/matrixorigin/matrixone/pkg/taskservice"
    29  	"github.com/matrixorigin/matrixone/pkg/tests"
    30  )
    31  
    32  // CNService describes expected behavior for dn service.
    33  type CNService interface {
    34  	// Start sends heartbeat and start to handle command.
    35  	Start() error
    36  	// Close stops store
    37  	Close() error
    38  	// Status returns the status of service.
    39  	Status() ServiceStatus
    40  
    41  	// ID returns uuid of store
    42  	ID() string
    43  	// SQLAddress returns the sql listen address
    44  	SQLAddress() string
    45  	//GetTaskRunner returns the taskRunner.
    46  	GetTaskRunner() taskservice.TaskRunner
    47  	// GetTaskService returns the taskservice
    48  	GetTaskService() (taskservice.TaskService, bool)
    49  	// WaitSystemInitCompleted wait system init task completed
    50  	WaitSystemInitCompleted(ctx context.Context) error
    51  	//SetCancel sets CancelFunc to stop GetClusterDetailsFromHAKeeper
    52  	SetCancel(context.CancelFunc)
    53  }
    54  
    55  // cnService wraps cnservice.Service.
    56  //
    57  // The main purpose of this structure is to maintain status.
    58  type cnService struct {
    59  	sync.Mutex
    60  	status ServiceStatus
    61  	svc    cnservice.Service
    62  	cfg    *cnservice.Config
    63  
    64  	cancel context.CancelFunc
    65  }
    66  
    67  func (c *cnService) Start() error {
    68  	c.Lock()
    69  	defer c.Unlock()
    70  
    71  	if c.status == ServiceInitialized {
    72  		err := c.svc.Start()
    73  		if err != nil {
    74  			return err
    75  		}
    76  		c.status = ServiceStarted
    77  	}
    78  
    79  	return nil
    80  }
    81  
    82  func (c *cnService) Close() error {
    83  	c.Lock()
    84  	defer c.Unlock()
    85  
    86  	if c.status == ServiceStarted {
    87  		err := c.svc.Close()
    88  		c.cancel()
    89  		if err != nil {
    90  			return err
    91  		}
    92  		c.status = ServiceClosed
    93  	}
    94  
    95  	return nil
    96  }
    97  
    98  func (c *cnService) Status() ServiceStatus {
    99  	c.Lock()
   100  	defer c.Unlock()
   101  
   102  	return c.status
   103  }
   104  
   105  func (c *cnService) ID() string {
   106  	c.Lock()
   107  	defer c.Unlock()
   108  
   109  	return c.cfg.UUID
   110  }
   111  
   112  func (c *cnService) SQLAddress() string {
   113  	return fmt.Sprintf("127.0.0.1:%d", c.cfg.Frontend.Port)
   114  }
   115  
   116  func (c *cnService) GetTaskRunner() taskservice.TaskRunner {
   117  	return c.svc.GetTaskRunner()
   118  }
   119  
   120  func (c *cnService) GetTaskService() (taskservice.TaskService, bool) {
   121  	return c.svc.GetTaskService()
   122  }
   123  
   124  func (c *cnService) WaitSystemInitCompleted(ctx context.Context) error {
   125  	return c.svc.WaitSystemInitCompleted(ctx)
   126  }
   127  
   128  func (c *cnService) SetCancel(cancel context.CancelFunc) {
   129  	c.cancel = cancel
   130  }
   131  
   132  // cnOptions is options for a cn service.
   133  type cnOptions []cnservice.Option
   134  
   135  // newCNService initializes an instance of `CNService`.
   136  func newCNService(
   137  	cfg *cnservice.Config,
   138  	ctx context.Context,
   139  	fileService fileservice.FileService,
   140  	options cnOptions,
   141  ) (CNService, error) {
   142  	srv, err := cnservice.NewService(cfg, ctx, fileService, options...)
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  
   147  	return &cnService{
   148  		status: ServiceInitialized,
   149  		svc:    srv,
   150  		cfg:    cfg,
   151  	}, nil
   152  }
   153  
   154  func buildCNConfig(index int, opt Options, address serviceAddresses) *cnservice.Config {
   155  	port, err := tests.GetAvailablePort("127.0.0.1")
   156  	if err != nil {
   157  		panic(err)
   158  	}
   159  	p, err := strconv.Atoi(port)
   160  	if err != nil {
   161  		panic(err)
   162  	}
   163  	cfg := &cnservice.Config{
   164  		UUID:          uuid.New().String(),
   165  		ListenAddress: address.getCNListenAddress(index),
   166  		SQLAddress:    fmt.Sprintf("127.0.0.1:%d", p),
   167  		Frontend: config.FrontendParameters{
   168  			Port: int64(p),
   169  		},
   170  	}
   171  	cfg.Frontend.StorePath = filepath.Join(opt.rootDataDir, cfg.UUID)
   172  	cfg.HAKeeper.ClientConfig.ServiceAddresses = address.listHAKeeperListenAddresses()
   173  	cfg.HAKeeper.HeatbeatInterval.Duration = opt.heartbeat.cn
   174  	cfg.Engine.Type = opt.storage.cnEngine
   175  	cfg.TaskRunner.Parallelism = 4
   176  
   177  	// We need the filled version of configuration.
   178  	// It's necessary when building cnservice.Option.
   179  	if err := cfg.Validate(); err != nil {
   180  		panic(fmt.Sprintf("fatal when building cnservice.Config: %s", err))
   181  	}
   182  
   183  	return cfg
   184  }
   185  
   186  func buildCNOptions() cnOptions {
   187  	return nil
   188  }