1
1
package cmd
2
2
3
3
import (
4
+ "context"
5
+ "crypto/rand"
6
+ "crypto/tls"
7
+ "encoding/binary"
4
8
"fmt"
5
9
"github.com/unpackdev/fdb"
6
- "github.com/unpackdev/fdb/pkg/ config"
7
- "github.com/unpackdev/fdb/pkg/ types"
10
+ "github.com/unpackdev/fdb/config"
11
+ "github.com/unpackdev/fdb/types"
8
12
"github.com/urfave/cli/v2"
9
- "log "
13
+ "io "
10
14
"runtime"
11
15
"time"
16
+
17
+ "github.com/quic-go/quic-go"
12
18
)
13
19
14
20
// BenchmarkCommand returns a cli.Command that benchmarks the real client
@@ -17,62 +23,154 @@ func BenchmarkCommand() *cli.Command {
17
23
Name : "test" ,
18
24
Usage : "Benchmark the real client" ,
19
25
Action : func (c * cli.Context ) error {
20
- // Simulate benchmarking logic here
21
26
fmt .Println ("Running client benchmark..." )
22
27
28
+ // Configure QUIC transport
23
29
cnf := config.Config {
24
30
Transports : []config.Transport {
25
31
{
26
32
Type : types .QUICTransportType ,
27
33
Enabled : true ,
28
34
Config : config.QuicTransport {IPv4 : "127.0.0.1" , Port : 4433 },
29
35
},
30
- /* {
31
- Type: fdb.UDS,
32
- Enabled: true,
33
- Config: fdb.UdsTransport{IPv4: "127.0.0.1", Port: 8000},
34
- },*/
35
36
},
36
37
}
37
38
38
- fdbc , fdbcErr := fdb .New (c .Context , cnf )
39
- if fdbcErr != nil {
40
- return fdbcErr
39
+ // Initialize FDB
40
+ fdbc , err := fdb .New (c .Context , cnf )
41
+ if err != nil {
42
+ return err
43
+ }
44
+
45
+ // Get QUIC transport
46
+ quicTransport , err := fdbc .GetTransportByType (types .QUICTransportType )
47
+ if err != nil {
48
+ return fmt .Errorf ("failed to retrieve QUIC transport: %w" , err )
41
49
}
42
50
43
- _ = fdbc
51
+ // Start the QUIC server
52
+ quicServer , ok := quicTransport .(* fdb.QuicServer )
53
+ if ! ok {
54
+ return fmt .Errorf ("failed to cast transport to QuicServer" )
55
+ }
56
+ if err := quicServer .Start (); err != nil {
57
+ return fmt .Errorf ("failed to start QUIC server: %w" , err )
58
+ }
44
59
45
- // Example: Perform a benchmark by running some mock client operations
46
- benchmarkClient ()
60
+ fmt .Println ("QUIC server started successfully" )
61
+
62
+ // Benchmark client
63
+ err = benchmarkQuicClient (quicServer .Addr ())
64
+ if err != nil {
65
+ return fmt .Errorf ("client benchmark failed: %w" , err )
66
+ }
47
67
48
68
return nil
49
69
},
50
70
}
51
71
}
52
72
53
- // benchmarkClient simulates client benchmarking
54
- func benchmarkClient () {
55
- // Capture initial memory usage
73
+ // benchmarkQuicClient benchmarks the QUIC client by simulating write and read operations
74
+ func benchmarkQuicClient (serverAddr string ) error {
75
+ // Setup TLS configuration for QUIC client
76
+ clientTLSConfig := & tls.Config {
77
+ InsecureSkipVerify : true ,
78
+ NextProtos : []string {"quic-example" },
79
+ }
80
+
81
+ // Start benchmarking
82
+ start := time .Now ()
56
83
var memStart runtime.MemStats
57
84
runtime .ReadMemStats (& memStart )
58
85
59
- // Simulate some work being done by the client
60
- start := time .Now ()
86
+ // Connect to the QUIC server
87
+ client , err := quic .DialAddr (context .Background (), serverAddr , clientTLSConfig , nil )
88
+ if err != nil {
89
+ return fmt .Errorf ("failed to dial QUIC server: %w" , err )
90
+ }
91
+ defer client .CloseWithError (0 , "closing connection" )
92
+
93
+ // Open stream
94
+ stream , err := client .OpenStreamSync (context .Background ())
95
+ if err != nil {
96
+ return fmt .Errorf ("failed to open stream: %w" , err )
97
+ }
98
+ defer stream .Close ()
99
+
100
+ // Simulate write operation
101
+ message := createWriteMessage ()
102
+ encodedMessage , err := message .Encode ()
103
+ if err != nil {
104
+ return fmt .Errorf ("failed to encode message: %w" , err )
105
+ }
106
+
107
+ _ , err = stream .Write (encodedMessage )
108
+ if err != nil {
109
+ return fmt .Errorf ("failed to write message to server: %w" , err )
110
+ }
111
+
112
+ // Read server response
113
+ buffer := make ([]byte , 1024 )
114
+ _ , err = stream .Read (buffer )
115
+ if err != nil {
116
+ return fmt .Errorf ("failed to read response: %w" , err )
117
+ }
118
+ fmt .Printf ("Response from server: %s\n " , string (buffer ))
119
+
120
+ // Simulate read operation
121
+ readMessage := createReadMessage (message .Key )
122
+ encodedReadMessage , err := readMessage .Encode ()
123
+ if err != nil {
124
+ return fmt .Errorf ("failed to encode read message: %w" , err )
125
+ }
126
+
127
+ _ , err = stream .Write (encodedReadMessage )
128
+ if err != nil {
129
+ return fmt .Errorf ("failed to write read message to server: %w" , err )
130
+ }
131
+
132
+ // Read back the data length
133
+ _ , err = io .ReadFull (stream , buffer [:4 ])
134
+ if err != nil {
135
+ return fmt .Errorf ("failed to read data length: %w" , err )
136
+ }
137
+ valueLength := binary .BigEndian .Uint32 (buffer [:4 ])
61
138
62
- // Replace this loop with real benchmarking code
63
- for i := 0 ; i < 1000 ; i ++ {
64
- // Simulate work by sleeping
65
- time .Sleep (1 * time .Millisecond )
139
+ // Read the actual value
140
+ readBuffer := make ([]byte , valueLength )
141
+ _ , err = io .ReadFull (stream , readBuffer )
142
+ if err != nil {
143
+ return fmt .Errorf ("failed to read value: %w" , err )
66
144
}
145
+ fmt .Printf ("Data read from server: %s\n " , string (readBuffer ))
67
146
68
- // Measure memory usage after
147
+ // Capture memory usage after the operation
69
148
var memEnd runtime.MemStats
70
149
runtime .ReadMemStats (& memEnd )
71
150
151
+ // Calculate elapsed time
72
152
elapsed := time .Since (start )
73
-
74
- // Output benchmarking results
75
153
fmt .Printf ("Benchmark completed in %s\n " , elapsed )
76
154
fmt .Printf ("Memory used: %d bytes\n " , memEnd .Alloc - memStart .Alloc )
77
- log .Printf ("Test completed." )
155
+
156
+ return nil
157
+ }
158
+
159
+ // createWriteMessage generates a random write message
160
+ func createWriteMessage () fdb.Message {
161
+ var key [32 ]byte
162
+ rand .Read (key [:])
163
+ return fdb.Message {
164
+ Handler : fdb .WriteHandlerType ,
165
+ Key : key ,
166
+ Data : []byte ("benchmark test data" ),
167
+ }
168
+ }
169
+
170
+ // createReadMessage generates a read message for a given key
171
+ func createReadMessage (key [32 ]byte ) fdb.Message {
172
+ return fdb.Message {
173
+ Handler : fdb .ReadHandlerType ,
174
+ Key : key ,
175
+ }
78
176
}
0 commit comments