@@ -9,12 +9,9 @@ import (
99)
1010
1111// AppConfig holds the application's runtime configuration.
12- // Struct tags: e.g.: when reading from YAML, the field named uri maps to URI in this struct
1312type AppConfig struct {
1413 URI string `yaml:"uri"`
1514 // DefaultWorkload controls both file loading and generator logic.
16- // True: Load only "default.json" and use custom workload logic (e.g. flights).
17- // False: Load user files (excluding default.json) and use generic generator.
1815 DefaultWorkload bool `yaml:"default_workload"`
1916
2017 CollectionsPath string `yaml:"collections_path"`
@@ -24,13 +21,15 @@ type AppConfig struct {
2421 DocumentsCount int `yaml:"documents_count"`
2522 Concurrency int `yaml:"concurrency"`
2623
27- Duration string `yaml:"duration"`
28- FindPercent int `yaml:"find_percent"`
29- UpdatePercent int `yaml:"update_percent"`
30- DeletePercent int `yaml:"delete_percent"`
31- InsertPercent int `yaml:"insert_percent"`
32- AggregatePercent int `yaml:"aggregate_percent"`
33- DebugMode bool `yaml:"debug_mode"`
24+ Duration string `yaml:"duration"`
25+ FindPercent int `yaml:"find_percent"`
26+ UpdatePercent int `yaml:"update_percent"`
27+ DeletePercent int `yaml:"delete_percent"`
28+ InsertPercent int `yaml:"insert_percent"`
29+ AggregatePercent int `yaml:"aggregate_percent"`
30+ TransactionPercent int `yaml:"transaction_percent"`
31+ UseTransactions bool `yaml:"use_transactions"`
32+ DebugMode bool `yaml:"debug_mode"`
3433
3534 FindBatchSize int `yaml:"find_batch_size"`
3635 FindLimit int64 `yaml:"find_limit"`
@@ -41,19 +40,14 @@ type AppConfig struct {
4140 RetryAttempts int `yaml:"retry_attempts"`
4241 RetryBackoffMs int `yaml:"retry_backoff_ms"`
4342
44- // Typed struct view
45- ConnectionParams ConnectionParams `yaml:"connection_params"`
46-
47- // Raw/dynamic view
48- CustomParamsMap map [string ]interface {} `yaml:"custom_params"`
49-
50- // Enable debugging
51- Debug bool `yaml:"debug"`
43+ ConnectionParams ConnectionParams `yaml:"connection_params"`
44+ CustomParamsMap map [string ]interface {} `yaml:"custom_params"`
45+ Debug bool `yaml:"debug"`
5246}
5347
5448type ConnectionParams struct {
5549 Username string `yaml:"username"`
56- Password string `yaml:"-"` // Never load from YAML
50+ Password string `yaml:"-"`
5751 AuthSource string `yaml:"auth_source"`
5852 DirectConnection bool `yaml:"direct_connection"`
5953 ConnectionTimeout int `yaml:"connection_timeout"`
@@ -65,7 +59,6 @@ type ConnectionParams struct {
6559 ReadPreference string `yaml:"read_preference"`
6660}
6761
68- // LoadAppConfig reads the configuration from the specified path and applies environment variable overrides.
6962func LoadAppConfig (path string ) (* AppConfig , error ) {
7063 b , err := os .ReadFile (path )
7164 if err != nil {
@@ -106,7 +99,6 @@ func applyDefaults(cfg *AppConfig) {
10699 if cfg .RetryBackoffMs <= 0 {
107100 cfg .RetryBackoffMs = 5
108101 }
109-
110102}
111103
112104func applyEnvOverrides (cfg * AppConfig ) {
@@ -134,22 +126,14 @@ func applyEnvOverrides(cfg *AppConfig) {
134126 cfg .ConnectionParams .DirectConnection = b
135127 }
136128 }
137- // Check if the environment variable is explicitly defined (even if empty)
138129 if v , exists := os .LookupEnv ("PERCONALOAD_REPLICA_SET" ); exists {
139130 cfg .ConnectionParams .ReplicaSetName = v
140131 }
141132 if v , exists := os .LookupEnv ("PERCONALOAD_READ_PREFERENCE" ); exists {
142133 cfg .ConnectionParams .ReadPreference = v
143134 }
144135
145- // -------------------------------------------------------------------------
146- // Custom Workload Logic:
147- // If the user provides custom paths via environment variables, we infer
148- // that they want to run a custom workload, so we force DefaultWorkload to false.
149- // This overrides any previous setting (YAML or PERCONALOAD_DEFAULT_WORKLOAD).
150- // -------------------------------------------------------------------------
151136 customWorkloadEnv := false
152-
153137 if envCollectionsPath := os .Getenv ("PERCONALOAD_COLLECTIONS_PATH" ); envCollectionsPath != "" {
154138 cfg .CollectionsPath = envCollectionsPath
155139 customWorkloadEnv = true
@@ -158,22 +142,25 @@ func applyEnvOverrides(cfg *AppConfig) {
158142 cfg .QueriesPath = envQueriesPath
159143 customWorkloadEnv = true
160144 }
161-
162145 if customWorkloadEnv {
163146 cfg .DefaultWorkload = false
164147 }
165- // -------------------------------------------------------------------------
166148
167149 if envDrop := os .Getenv ("PERCONALOAD_DROP_COLLECTIONS" ); envDrop != "" {
168150 if b , err := strconv .ParseBool (envDrop ); err == nil {
169151 cfg .DropCollections = b
170152 }
171153 }
172- if envDrop := os .Getenv ("PERCONALOAD_SKIP_SEED" ); envDrop != "" {
173- if b , err := strconv .ParseBool (envDrop ); err == nil {
154+ if envSkip := os .Getenv ("PERCONALOAD_SKIP_SEED" ); envSkip != "" {
155+ if b , err := strconv .ParseBool (envSkip ); err == nil {
174156 cfg .SkipSeed = b
175157 }
176158 }
159+ if envTx := os .Getenv ("PERCONALOAD_USE_TRANSACTIONS" ); envTx != "" {
160+ if b , err := strconv .ParseBool (envTx ); err == nil {
161+ cfg .UseTransactions = b
162+ }
163+ }
177164 if envDocs := os .Getenv ("PERCONALOAD_DOCUMENTS_COUNT" ); envDocs != "" {
178165 if n , err := strconv .Atoi (envDocs ); err == nil && n >= 0 {
179166 cfg .DocumentsCount = n
@@ -212,7 +199,12 @@ func applyEnvOverrides(cfg *AppConfig) {
212199 cfg .AggregatePercent = n
213200 }
214201 }
215- // runtime optimization
202+ if p := os .Getenv ("PERCONALOAD_TRANSACTION_PERCENT" ); p != "" {
203+ if n , err := strconv .Atoi (p ); err == nil && n >= 0 {
204+ cfg .TransactionPercent = n
205+ }
206+ }
207+
216208 if v := os .Getenv ("PERCONALOAD_FIND_BATCH_SIZE" ); v != "" {
217209 if n , err := strconv .Atoi (v ); err == nil && n > 0 {
218210 cfg .FindBatchSize = n
@@ -251,20 +243,27 @@ func applyEnvOverrides(cfg *AppConfig) {
251243}
252244
253245func normalizePercentages (cfg * AppConfig ) {
254- total := cfg .FindPercent + cfg .UpdatePercent + cfg .DeletePercent + cfg .InsertPercent + cfg .AggregatePercent
246+ // If transactions are disabled, ignore their percentage entirely
247+ if ! cfg .UseTransactions {
248+ cfg .TransactionPercent = 0
249+ }
250+
251+ total := cfg .FindPercent + cfg .UpdatePercent + cfg .DeletePercent + cfg .InsertPercent + cfg .AggregatePercent + cfg .TransactionPercent
255252 if total <= 0 {
256253 cfg .FindPercent = 100
257254 return
258255 }
256+
259257 if total != 100 {
260258 factor := 100.0 / float64 (total )
261259 cfg .FindPercent = int (float64 (cfg .FindPercent ) * factor )
262260 cfg .UpdatePercent = int (float64 (cfg .UpdatePercent ) * factor )
263261 cfg .DeletePercent = int (float64 (cfg .DeletePercent ) * factor )
264262 cfg .InsertPercent = int (float64 (cfg .InsertPercent ) * factor )
265263 cfg .AggregatePercent = int (float64 (cfg .AggregatePercent ) * factor )
264+ cfg .TransactionPercent = int (float64 (cfg .TransactionPercent ) * factor )
266265
267- finalTotal := cfg .FindPercent + cfg .UpdatePercent + cfg .DeletePercent + cfg .InsertPercent + cfg .AggregatePercent
266+ finalTotal := cfg .FindPercent + cfg .UpdatePercent + cfg .DeletePercent + cfg .InsertPercent + cfg .AggregatePercent + cfg . TransactionPercent
268267 if finalTotal != 100 {
269268 cfg .FindPercent += (100 - finalTotal )
270269 }
0 commit comments