Skip to content

Commit 8125993

Browse files
AlliBalliBabaa.stecher
andauthored
fix: disallow 2 workers with same filename (#1492)
* Disallows 2 workers with the same filename. * Adds test. * Prevent duplicate names. --------- Co-authored-by: a.stecher <a.stecher@sportradar.com> Co-authored-by: Alliballibaba <alliballibaba@gmail.com>
1 parent 8583afd commit 8125993

File tree

5 files changed

+38
-118
lines changed

5 files changed

+38
-118
lines changed

caddy/caddy.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -295,15 +295,6 @@ func (f *FrankenPHPApp) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
295295
wc.FileName = filepath.Join(frankenphp.EmbeddedAppPath, wc.FileName)
296296
}
297297

298-
if wc.Name == "" {
299-
// let worker initialization validate if the FileName is valid or not
300-
name, _ := fastabs.FastAbs(wc.FileName)
301-
if name == "" {
302-
name = wc.FileName
303-
}
304-
wc.Name = name
305-
}
306-
307298
f.Workers = append(f.Workers, wc)
308299
default:
309300
allowedDirectives := "num_threads, max_threads, php_ini, worker, max_wait_time"

caddy/caddy_test.go

Lines changed: 1 addition & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -975,111 +975,6 @@ func TestMultiWorkersMetrics(t *testing.T) {
975975
))
976976
}
977977

978-
func TestMultiWorkersMetricsWithDuplicateName(t *testing.T) {
979-
var wg sync.WaitGroup
980-
tester := caddytest.NewTester(t)
981-
tester.InitServer(`
982-
{
983-
skip_install_trust
984-
admin localhost:2999
985-
http_port `+testPort+`
986-
https_port 9443
987-
metrics
988-
989-
frankenphp {
990-
worker {
991-
name service1
992-
file ../testdata/index.php
993-
num 2
994-
}
995-
worker {
996-
name service1
997-
file ../testdata/ini.php
998-
num 3
999-
}
1000-
}
1001-
}
1002-
1003-
localhost:`+testPort+` {
1004-
route {
1005-
php {
1006-
root ../testdata
1007-
}
1008-
}
1009-
}
1010-
1011-
example.com:`+testPort+` {
1012-
route {
1013-
php {
1014-
root ../testdata
1015-
}
1016-
}
1017-
}
1018-
`, "caddyfile")
1019-
1020-
// Make some requests
1021-
for i := 0; i < 10; i++ {
1022-
wg.Add(1)
1023-
go func(i int) {
1024-
tester.AssertGetResponse(fmt.Sprintf("http://localhost:"+testPort+"/index.php?i=%d", i), http.StatusOK, fmt.Sprintf("I am by birth a Genevese (%d)", i))
1025-
wg.Done()
1026-
}(i)
1027-
}
1028-
wg.Wait()
1029-
1030-
// Fetch metrics
1031-
resp, err := http.Get("http://localhost:2999/metrics")
1032-
require.NoError(t, err, "failed to fetch metrics")
1033-
defer resp.Body.Close()
1034-
1035-
// Read and parse metrics
1036-
metrics := new(bytes.Buffer)
1037-
_, err = metrics.ReadFrom(resp.Body)
1038-
require.NoError(t, err, "failed to read metrics")
1039-
1040-
cpus := fmt.Sprintf("%d", frankenphp.MaxThreads)
1041-
1042-
// Check metrics
1043-
expectedMetrics := `
1044-
# HELP frankenphp_total_threads Total number of PHP threads
1045-
# TYPE frankenphp_total_threads counter
1046-
frankenphp_total_threads ` + cpus + `
1047-
1048-
# HELP frankenphp_busy_threads Number of busy PHP threads
1049-
# TYPE frankenphp_busy_threads gauge
1050-
frankenphp_busy_threads 5
1051-
1052-
# HELP frankenphp_busy_workers Number of busy PHP workers for this worker
1053-
# TYPE frankenphp_busy_workers gauge
1054-
frankenphp_busy_workers{worker="service1"} 0
1055-
1056-
# HELP frankenphp_total_workers Total number of PHP workers for this worker
1057-
# TYPE frankenphp_total_workers gauge
1058-
frankenphp_total_workers{worker="service1"} 5
1059-
1060-
# HELP frankenphp_worker_request_count
1061-
# TYPE frankenphp_worker_request_count counter
1062-
frankenphp_worker_request_count{worker="service1"} 10
1063-
1064-
# HELP frankenphp_ready_workers Running workers that have successfully called frankenphp_handle_request at least once
1065-
# TYPE frankenphp_ready_workers gauge
1066-
frankenphp_ready_workers{worker="service1"} 5
1067-
`
1068-
1069-
ctx := caddy.ActiveContext()
1070-
require.NoError(t,
1071-
testutil.GatherAndCompare(
1072-
ctx.GetMetricsRegistry(),
1073-
strings.NewReader(expectedMetrics),
1074-
"frankenphp_total_threads",
1075-
"frankenphp_busy_threads",
1076-
"frankenphp_busy_workers",
1077-
"frankenphp_total_workers",
1078-
"frankenphp_worker_request_count",
1079-
"frankenphp_ready_workers",
1080-
))
1081-
}
1082-
1083978
func TestDisabledMetrics(t *testing.T) {
1084979
var wg sync.WaitGroup
1085980
tester := caddytest.NewTester(t)
@@ -1097,7 +992,7 @@ func TestDisabledMetrics(t *testing.T) {
1097992
num 2
1098993
}
1099994
worker {
1100-
name service1
995+
name service2
1101996
file ../testdata/ini.php
1102997
num 3
1103998
}

phpmainthread_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,24 @@ func TestFinishBootingAWorkerScript(t *testing.T) {
177177
assert.Nil(t, phpThreads)
178178
}
179179

180+
func TestReturnAnErrorIf2WorkersHaveTheSameFileName(t *testing.T) {
181+
workers = make(map[string]*worker)
182+
_, err1 := newWorker(workerOpt{fileName: "filename.php"})
183+
_, err2 := newWorker(workerOpt{fileName: "filename.php"})
184+
185+
assert.NoError(t, err1)
186+
assert.Error(t, err2, "2 workers cannot have the same filename")
187+
}
188+
189+
func TestReturnAnErrorIf2WorkersHaveTheSameName(t *testing.T) {
190+
workers = make(map[string]*worker)
191+
_, err1 := newWorker(workerOpt{fileName: "filename.php", name: "workername"})
192+
_, err2 := newWorker(workerOpt{fileName: "filename2.php", name: "workername"})
193+
194+
assert.NoError(t, err1)
195+
assert.Error(t, err2, "2 workers cannot have the same name")
196+
}
197+
180198
func getDummyWorker(fileName string) *worker {
181199
if workers == nil {
182200
workers = make(map[string]*worker)

worker.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ func initWorkers(opt []workerOpt) error {
3535

3636
for _, o := range opt {
3737
worker, err := newWorker(o)
38-
worker.threads = make([]*phpThread, 0, o.num)
39-
workersReady.Add(o.num)
4038
if err != nil {
4139
return err
4240
}
41+
42+
workersReady.Add(o.num)
4343
for i := 0; i < worker.num; i++ {
4444
thread := getInactivePHPThread()
4545
convertToWorkerThread(thread, worker)
@@ -74,14 +74,30 @@ func newWorker(o workerOpt) (*worker, error) {
7474
o.env = make(PreparedEnv, 1)
7575
}
7676

77+
if o.name == "" {
78+
o.name = absFileName
79+
}
80+
7781
o.env["FRANKENPHP_WORKER\x00"] = "1"
7882
w := &worker{
7983
name: o.name,
8084
fileName: absFileName,
8185
num: o.num,
8286
env: o.env,
8387
requestChan: make(chan *frankenPHPContext),
88+
threads: make([]*phpThread, 0, o.num),
8489
}
90+
91+
// ensure the filename or name are not already registered
92+
for _, w := range workers {
93+
if w.name == o.name {
94+
return w, fmt.Errorf("2 workers cannot have the same name: %q.", o.name)
95+
}
96+
if w.fileName == absFileName {
97+
return w, fmt.Errorf("2 workers cannot have the same filename: %q.", absFileName)
98+
}
99+
}
100+
85101
workers[absFileName] = w
86102

87103
return w, nil

worker_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func TestWorkerGetOpt(t *testing.T) {
122122
func ExampleServeHTTP_workers() {
123123
if err := frankenphp.Init(
124124
frankenphp.WithWorkers("worker1", "worker1.php", 4, map[string]string{"ENV1": "foo"}, []string{}),
125-
frankenphp.WithWorkers("worker1", "worker2.php", 2, map[string]string{"ENV2": "bar"}, []string{}),
125+
frankenphp.WithWorkers("worker2", "worker2.php", 2, map[string]string{"ENV2": "bar"}, []string{}),
126126
); err != nil {
127127
panic(err)
128128
}

0 commit comments

Comments
 (0)