github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/support-perf-site-replication.go (about)

     1  // Copyright (c) 2023 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"context"
    22  	"os"
    23  	"time"
    24  
    25  	tea "github.com/charmbracelet/bubbletea"
    26  	"github.com/minio/cli"
    27  	"github.com/minio/madmin-go/v3"
    28  	"github.com/minio/mc/pkg/probe"
    29  )
    30  
    31  func mainAdminSpeedTestSiteReplication(ctx *cli.Context, aliasedURL string, outCh chan<- PerfTestResult) error {
    32  	client, perr := newAdminClient(aliasedURL)
    33  	if perr != nil {
    34  		fatalIf(perr.Trace(aliasedURL), "Unable to initialize admin client.")
    35  		return nil
    36  	}
    37  
    38  	ctxt, cancel := context.WithCancel(globalContext)
    39  	defer cancel()
    40  
    41  	duration, e := time.ParseDuration(ctx.String("duration"))
    42  	if e != nil {
    43  		fatalIf(probe.NewError(e), "Unable to parse duration")
    44  		return nil
    45  	}
    46  	if duration <= 0 {
    47  		fatalIf(errInvalidArgument(), "duration cannot be 0 or negative")
    48  		return nil
    49  	}
    50  
    51  	resultCh := make(chan madmin.SiteNetPerfResult)
    52  	errorCh := make(chan error)
    53  	go func() {
    54  		defer close(resultCh)
    55  		defer close(errorCh)
    56  
    57  		result, e := client.SiteReplicationPerf(ctxt, duration)
    58  		if e != nil {
    59  			errorCh <- e
    60  		}
    61  		resultCh <- result
    62  	}()
    63  
    64  	if globalJSON {
    65  		select {
    66  		case e := <-errorCh:
    67  			printMsg(convertPerfResult(PerfTestResult{
    68  				Type:  SiteReplicationPerfTest,
    69  				Err:   e.Error(),
    70  				Final: true,
    71  			}))
    72  		case result := <-resultCh:
    73  			printMsg(convertPerfResult(PerfTestResult{
    74  				Type:                  SiteReplicationPerfTest,
    75  				SiteReplicationResult: &result,
    76  				Final:                 true,
    77  			}))
    78  		}
    79  		return nil
    80  	}
    81  
    82  	done := make(chan struct{})
    83  
    84  	p := tea.NewProgram(initSpeedTestUI())
    85  	go func() {
    86  		if _, e := p.Run(); e != nil {
    87  			os.Exit(1)
    88  		}
    89  		close(done)
    90  	}()
    91  
    92  	go func() {
    93  		for {
    94  			select {
    95  			case e := <-errorCh:
    96  				r := PerfTestResult{
    97  					Type:  SiteReplicationPerfTest,
    98  					Err:   e.Error(),
    99  					Final: true,
   100  				}
   101  				p.Send(r)
   102  				if outCh != nil {
   103  					outCh <- r
   104  				}
   105  				return
   106  			case result := <-resultCh:
   107  				r := PerfTestResult{
   108  					Type:                  SiteReplicationPerfTest,
   109  					SiteReplicationResult: &result,
   110  					Final:                 true,
   111  				}
   112  				p.Send(r)
   113  				if outCh != nil {
   114  					outCh <- r
   115  				}
   116  				return
   117  			default:
   118  				p.Send(PerfTestResult{
   119  					Type:                  SiteReplicationPerfTest,
   120  					SiteReplicationResult: &madmin.SiteNetPerfResult{},
   121  				})
   122  				time.Sleep(100 * time.Millisecond)
   123  			}
   124  		}
   125  	}()
   126  
   127  	<-done
   128  
   129  	return nil
   130  }