Skip to content

Commit af18d04

Browse files
committed
sum up logic a bit, put worker thread addition into moduleWorkers parsing, before workers are actually created
1 parent 3b15199 commit af18d04

4 files changed

Lines changed: 54 additions & 15 deletions

File tree

caddy/caddy.go

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
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.
495520
func (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

caddy/caddy_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ func TestGlobalAndModuleWorker(t *testing.T) {
164164
}
165165
`, "caddyfile")
166166

167-
for i := 0; i < 2; i++ {
167+
for i := 0; i < 10; i++ {
168168
wg.Add(1)
169169

170170
go func(i int) {

caddy/config_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ func TestModuleWorkerDuplicateFilenamesFail(t *testing.T) {
4444
resetModuleWorkers()
4545
}
4646

47-
func TestModuleWorkersDuplicateNameFail(t *testing.T) {
47+
func TestModuleWorkersDuplicateNameWithDifferentEnvironmentsFail(t *testing.T) {
4848
// Create a test configuration with a worker name
4949
configWithWorkerName1 := `
5050
{
5151
php_server {
52+
env APP_ENV something
5253
worker {
5354
name test-worker
5455
file ../testdata/worker-with-env.php
@@ -70,6 +71,7 @@ func TestModuleWorkersDuplicateNameFail(t *testing.T) {
7071
{
7172
php_server {
7273
worker {
74+
env APP_ENV mismatch
7375
name test-worker
7476
file ../testdata/worker-with-env.php
7577
num 1
@@ -85,8 +87,8 @@ func TestModuleWorkersDuplicateNameFail(t *testing.T) {
8587
err = module2.UnmarshalCaddyfile(d2)
8688

8789
// Verify that an error was returned
88-
require.Error(t, err, "Expected an error when two workers have the same name")
89-
require.Contains(t, err.Error(), "workers must not have duplicate names", "Error message should mention duplicate names")
90+
require.Error(t, err, "Expected an error when two workers have the same name, but different environments")
91+
require.Contains(t, err.Error(), "module workers with different environments must not have duplicate names", "Error message should mention duplicate names")
9092
resetModuleWorkers()
9193
}
9294

worker.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ func initWorkers(opt []workerOpt) error {
4141
}
4242
if worker.threads == nil {
4343
worker.threads = make([]*phpThread, 0, o.num)
44-
} else {
45-
worker.num += o.num
4644
}
4745
workersReady.Add(o.num)
4846
for i := 0; i < o.num; i++ {

0 commit comments

Comments
 (0)