99 "fmt"
1010 "net/http"
1111 "path/filepath"
12+ "sort"
1213 "strconv"
1314 "strings"
1415 "time"
@@ -491,6 +492,30 @@ func (f *FrankenPHPModule) ServeHTTP(w http.ResponseWriter, r *http.Request, _ c
491492 return nil
492493}
493494
495+ func getEnvString (env map [string ]string ) string {
496+ // 1. Create a slice of keys from the map
497+ keys := make ([]string , 0 , len (env ))
498+ for k := range env {
499+ keys = append (keys , k )
500+ }
501+
502+ // 2. Sort the keys alphabetically
503+ sort .Strings (keys )
504+
505+ // 3. Build the string using sorted keys
506+ var builder strings.Builder
507+ for i , k := range keys {
508+ v := env [k ] // Get value from the original map using the sorted key
509+ if i > 0 {
510+ }
511+ builder .WriteString (k )
512+ builder .WriteString ("=" )
513+ builder .WriteString (v )
514+ builder .WriteString ("," )
515+ }
516+ return strings .TrimSuffix (builder .String (), "," )
517+ }
518+
494519// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
495520func (f * FrankenPHPModule ) UnmarshalCaddyfile (d * caddyfile.Dispenser ) error {
496521 // First pass: Parse all directives except "worker"
@@ -576,17 +601,14 @@ func (f *FrankenPHPModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
576601 }
577602 }
578603
604+ envString := getEnvString (wc .Env )
605+
579606 if wc .Name == "" {
580607 if len (wc .Env ) > 0 {
581- envString := ""
582- for k , v := range wc .Env {
583- envString += k + "=" + v + ","
584- }
585- envString = strings .TrimSuffix (envString , "," )
586608 // Environment is required in order not to collide with other FrankenPHPModules
587- // Filename is required to avoid collisions with other workers in this module
588609 wc .Name += "env:" + envString
589610 }
611+ // Filename is required to avoid collisions with other workers in this module
590612 wc .Name += "_" + wc .FileName
591613 }
592614 if ! strings .HasPrefix (wc .Name , "m#" ) {
@@ -599,10 +621,27 @@ func (f *FrankenPHPModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
599621 return fmt .Errorf ("workers must not have duplicate filenames: %s" , wc .FileName )
600622 }
601623 }
602- // Check if a worker with this name already exists
603- for _ , existingWorker := range moduleWorkers {
624+ // Check if a worker with this name and a different environment or filename already exists
625+ for i , existingWorker := range moduleWorkers {
604626 if existingWorker .Name == wc .Name {
605- return fmt .Errorf ("workers must not have duplicate names: %s" , wc .Name )
627+ efs , _ := fastabs .FastAbs (existingWorker .FileName )
628+ wcfs , _ := fastabs .FastAbs (wc .FileName )
629+ if efs != wcfs {
630+ return fmt .Errorf ("module workers with different filenames must not have duplicate names: %s" , wc .Name )
631+ }
632+ if len (existingWorker .Env ) != len (wc .Env ) {
633+ // If lengths are different, the maps are definitely different
634+ return fmt .Errorf ("module workers with different environments must not have duplicate names: %s" , wc .Name )
635+ }
636+ // If lengths are the same, iterate and compare key-value pairs
637+ if getEnvString (existingWorker .Env ) != envString {
638+ return fmt .Errorf ("module workers with different environments must not have duplicate names: %s" , wc .Name )
639+ }
640+ // If we reach this point, the maps are equal.
641+ // Increase the number of threads for this worker and skip adding it to the moduleWorkers again
642+ moduleWorkers [i ].Num += wc .Num
643+ f .Workers = append (f .Workers , wc )
644+ return nil
606645 }
607646 }
608647
0 commit comments