summaryrefslogtreecommitdiff
path: root/internal/clients/common.go
blob: 14fb5fe2e47b91e8899c7db177231ddc3e325bd5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package clients

import (
	"fmt"
	"runtime"
	"strings"

	"github.com/mimecast/dtail/internal/clients/handlers"
	"github.com/mimecast/dtail/internal/config"
	"github.com/mimecast/dtail/internal/io/dlog"
	"github.com/mimecast/dtail/internal/omode"
)

// CommonClient provides shared functionality for CatClient, GrepClient, and TailClient.
// It embeds baseClient to inherit core connection management and SSH functionality,
// while providing specialized command generation and handler creation for standard
// file operations (cat, grep, tail).
//
// This structure reduces code duplication across the three most common client types
// by centralizing their shared behavior and configuration patterns.
type CommonClient struct {
	baseClient
}

// NewCommonClient creates a new CommonClient with the specified configuration.
// This constructor initializes the embedded baseClient with appropriate settings
// for standard file operations.
//
// Parameters:
//   args: Complete configuration arguments for the client
//   retry: Whether to automatically retry failed connections
//
// Returns:
//   CommonClient: Configured client ready for initialization and connection setup
//
// The client is configured with:
// - Connection throttling based on CPU cores
// - Retry behavior as specified
// - All provided configuration arguments
func NewCommonClient(args config.Args, retry bool) CommonClient {
	return CommonClient{
		baseClient: baseClient{
			Args:       args,
			throttleCh: make(chan struct{}, args.ConnectionsPerCPU*runtime.NumCPU()),
			retry:      retry,
		},
	}
}

// makeHandler creates a standard client handler for basic file operations.
// This method implements the maker interface requirement and provides the
// handler used for cat, grep, and tail operations.
//
// Parameters:
//   server: The server hostname/address for this handler
//
// Returns:
//   handlers.Handler: A ClientHandler configured for the specified server
//
// The returned handler manages the protocol communication and result processing
// for standard file operations across all CommonClient-based client types.
func (c CommonClient) makeHandler(server string) handlers.Handler {
	return handlers.NewClientHandler(server)
}

// makeCommands generates the appropriate DTail server commands based on the
// client's operating mode and configuration. This method implements the maker
// interface requirement and creates commands for cat, grep, or tail operations.
//
// Returns:
//   []string: List of commands to send to DTail servers
//
// Command generation process:
// 1. Serializes the regex pattern for transmission
// 2. Creates one command per file specified in the What field
// 3. Includes mode-specific options and parameters
// 4. Formats commands using the mode:options filename regex pattern
//
// The generated commands follow the DTail protocol format and include
// all necessary options for proper server-side execution.
func (c CommonClient) makeCommands() (commands []string) {
	regex, err := c.Regex.Serialize()
	if err != nil {
		dlog.Client.FatalPanic(err)
	}
	for _, file := range strings.Split(c.What, ",") {
		commands = append(commands, fmt.Sprintf("%s:%s %s %s",
			c.Mode.String(), c.Args.SerializeOptions(), file, regex))
	}
	if c.Mode == omode.TailClient {
		dlog.Client.Debug(commands)
	}
	return
}