@@ -48,6 +48,8 @@ import (
4848
4949const scaletestTracerName = "coder_scaletest"
5050
51+ var BypassHeader = map [string ][]string {codersdk .BypassRatelimitHeader : {"true" }}
52+
5153func (r * RootCmd ) scaletestCmd () * serpent.Command {
5254 cmd := & serpent.Command {
5355 Use : "scaletest" ,
@@ -690,15 +692,6 @@ func (r *RootCmd) scaletestCreateWorkspaces() *serpent.Command {
690692 return err
691693 }
692694
693- client .HTTPClient = & http.Client {
694- Transport : & codersdk.HeaderTransport {
695- Transport : http .DefaultTransport ,
696- Header : map [string ][]string {
697- codersdk .BypassRatelimitHeader : {"true" },
698- },
699- },
700- }
701-
702695 if count <= 0 {
703696 return xerrors .Errorf ("--count is required and must be greater than 0" )
704697 }
@@ -810,7 +803,13 @@ func (r *RootCmd) scaletestCreateWorkspaces() *serpent.Command {
810803 return xerrors .Errorf ("validate config: %w" , err )
811804 }
812805
813- var runner harness.Runnable = createworkspaces .NewRunner (client , config )
806+ // use an independent client for each Runner, so they don't reuse TCP connections. This can lead to
807+ // requests being unbalanced among Coder instances.
808+ runnerClient , err := loadtestutil .DupClientCopyingHeaders (client , BypassHeader )
809+ if err != nil {
810+ return xerrors .Errorf ("create runner client: %w" , err )
811+ }
812+ var runner harness.Runnable = createworkspaces .NewRunner (runnerClient , config )
814813 if tracingEnabled {
815814 runner = & runnableTraceWrapper {
816815 tracer : tracer ,
@@ -1011,15 +1010,6 @@ func (r *RootCmd) scaletestWorkspaceUpdates() *serpent.Command {
10111010 return err
10121011 }
10131012
1014- client .HTTPClient = & http.Client {
1015- Transport : & codersdk.HeaderTransport {
1016- Transport : http .DefaultTransport ,
1017- Header : map [string ][]string {
1018- codersdk .BypassRatelimitHeader : {"true" },
1019- },
1020- },
1021- }
1022-
10231013 if workspaceCount <= 0 {
10241014 return xerrors .Errorf ("--workspace-count must be greater than 0" )
10251015 }
@@ -1158,7 +1148,14 @@ func (r *RootCmd) scaletestWorkspaceUpdates() *serpent.Command {
11581148 for i , config := range configs {
11591149 name := fmt .Sprintf ("workspaceupdates-%dw" , config .WorkspaceCount )
11601150 id := strconv .Itoa (i )
1161- var runner harness.Runnable = workspaceupdates .NewRunner (client , config )
1151+
1152+ // use an independent client for each Runner, so they don't reuse TCP connections. This can lead to
1153+ // requests being unbalanced among Coder instances.
1154+ runnerClient , err := loadtestutil .DupClientCopyingHeaders (client , BypassHeader )
1155+ if err != nil {
1156+ return xerrors .Errorf ("create runner client: %w" , err )
1157+ }
1158+ var runner harness.Runnable = workspaceupdates .NewRunner (runnerClient , config )
11621159 if tracingEnabled {
11631160 runner = & runnableTraceWrapper {
11641161 tracer : tracer ,
@@ -1421,7 +1418,13 @@ func (r *RootCmd) scaletestWorkspaceTraffic() *serpent.Command {
14211418 if err := config .Validate (); err != nil {
14221419 return xerrors .Errorf ("validate config: %w" , err )
14231420 }
1424- var runner harness.Runnable = workspacetraffic .NewRunner (client , config )
1421+ // use an independent client for each Runner, so they don't reuse TCP connections. This can lead to
1422+ // requests being unbalanced among Coder instances.
1423+ runnerClient , err := loadtestutil .DupClientCopyingHeaders (client , BypassHeader )
1424+ if err != nil {
1425+ return xerrors .Errorf ("create runner client: %w" , err )
1426+ }
1427+ var runner harness.Runnable = workspacetraffic .NewRunner (runnerClient , config )
14251428 if tracingEnabled {
14261429 runner = & runnableTraceWrapper {
14271430 tracer : tracer ,
@@ -1609,9 +1612,13 @@ func (r *RootCmd) scaletestDashboard() *serpent.Command {
16091612 return xerrors .Errorf ("create token for user: %w" , err )
16101613 }
16111614
1612- userClient := codersdk .New (client .URL ,
1613- codersdk .WithSessionToken (userTokResp .Key ),
1614- )
1615+ // use an independent client for each Runner, so they don't reuse TCP connections. This can lead to
1616+ // requests being unbalanced among Coder instances.
1617+ userClient , err := loadtestutil .DupClientCopyingHeaders (client , BypassHeader )
1618+ if err != nil {
1619+ return xerrors .Errorf ("create runner client: %w" , err )
1620+ }
1621+ codersdk .WithSessionToken (userTokResp .Key )(userClient )
16151622
16161623 config := dashboard.Config {
16171624 Interval : interval ,
@@ -1758,15 +1765,6 @@ func (r *RootCmd) scaletestAutostart() *serpent.Command {
17581765 return err
17591766 }
17601767
1761- client .HTTPClient = & http.Client {
1762- Transport : & codersdk.HeaderTransport {
1763- Transport : http .DefaultTransport ,
1764- Header : map [string ][]string {
1765- codersdk .BypassRatelimitHeader : {"true" },
1766- },
1767- },
1768- }
1769-
17701768 if workspaceCount <= 0 {
17711769 return xerrors .Errorf ("--workspace-count must be greater than zero" )
17721770 }
@@ -1832,7 +1830,13 @@ func (r *RootCmd) scaletestAutostart() *serpent.Command {
18321830 if err := config .Validate (); err != nil {
18331831 return xerrors .Errorf ("validate config: %w" , err )
18341832 }
1835- var runner harness.Runnable = autostart .NewRunner (client , config )
1833+ // use an independent client for each Runner, so they don't reuse TCP connections. This can lead to
1834+ // requests being unbalanced among Coder instances.
1835+ runnerClient , err := loadtestutil .DupClientCopyingHeaders (client , BypassHeader )
1836+ if err != nil {
1837+ return xerrors .Errorf ("create runner client: %w" , err )
1838+ }
1839+ var runner harness.Runnable = autostart .NewRunner (runnerClient , config )
18361840 if tracingEnabled {
18371841 runner = & runnableTraceWrapper {
18381842 tracer : tracer ,
0 commit comments