Skip to content

fix(envd): fix fan-out deadlock when process subscriber disconnects#2579

Open
arkamar wants to merge 2 commits intomainfrom
envd/fix-multiplex-fanout-deadlock
Open

fix(envd): fix fan-out deadlock when process subscriber disconnects#2579
arkamar wants to merge 2 commits intomainfrom
envd/fix-multiplex-fanout-deadlock

Conversation

@arkamar
Copy link
Copy Markdown
Contributor

@arkamar arkamar commented May 6, 2026

The fan-out loop sent to unbuffered subscriber channels while holding
RLock. If a subscriber stopped reading (e.g. client disconnect), the
send blocked forever, preventing remove() from acquiring the write lock.
This froze the output stream for all subscribers and hung any new
Connect RPC to that process.

Each subscriber now carries a done channel; fan-out delivers via
select { case s.ch <- v: case <-s.done: } so a cancelled subscriber
never wedges the loop. Includes regression tests.

Also bumps envd version to 0.5.16.

arkamar added 2 commits May 6, 2026 11:11
The fan-out loop sent to unbuffered subscriber channels while holding
RLock. If a subscriber stopped reading (e.g. client disconnect), the
send blocked forever, preventing remove() from acquiring the write lock.
This froze the output stream for all subscribers and hung any new
Connect RPC to that process.

Each subscriber now carries a done channel; fan-out delivers via
select { case s.ch <- v: case <-s.done: } so a cancelled subscriber
never wedges the loop. Includes regression tests.
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization has reached its monthly code review spending cap.

An organization admin can view or raise the cap at claude.ai/admin-settings/claude-code. The cap resets at the start of the next billing period.

Once the cap resets or is raised, push a new commit or reopen this pull request to trigger a review.

@qodo-code-review
Copy link
Copy Markdown

ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one.

@cursor
Copy link
Copy Markdown

cursor Bot commented May 6, 2026

PR Summary

Medium Risk
Touches core process event streaming concurrency; mistakes could cause hangs, missed events, or goroutine leaks under load. Added tests reduce risk but timing-based coverage may still miss edge cases.

Overview
Fixes a fan-out deadlock where a disconnected subscriber could block run() and prevent unsubscribe, freezing output and new connects; delivery now selects on a per-subscriber done signal to unblock in-flight sends, and shutdown closes remaining subscriber channels. Potential remaining issue: calling cancel/remove does not close the subscriber channel, so consumers that rely on channel close (rather than context) can still block until Source is closed. Adds regression tests for abandon/cancel behavior and bumps version to 0.5.16.

Reviewed by Cursor Bugbot for commit 62d63c2. Bugbot is set up for automated code reviews on this repo. Configure here.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 6, 2026

❌ 10 Tests Failed:

Tests completed Failed Passed Skipped
2583 10 2573 7
View the full list of 12 ❄️ flaky test(s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/metrics::TestTeamMetrics

Flake rate in main: 69.49% (Passed 18 times, Failed 41 times)

Stack Traces | 1.46s run time
=== RUN   TestTeamMetrics
=== PAUSE TestTeamMetrics
=== CONT  TestTeamMetrics
    team_metrics_test.go:61: 
        	Error Trace:	.../api/metrics/team_metrics_test.go:61
        	Error:      	Should be true
        	Test:       	TestTeamMetrics
        	Messages:   	MaxConcurrentSandboxes should be >= 0
--- FAIL: TestTeamMetrics (1.46s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestSnapshotTemplateCreate

Flake rate in main: 43.33% (Passed 17 times, Failed 13 times)

Stack Traces | 0s run time
=== RUN   TestSnapshotTemplateCreate
=== PAUSE TestSnapshotTemplateCreate
=== CONT  TestSnapshotTemplateCreate
--- FAIL: TestSnapshotTemplateCreate (0.00s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestSnapshotTemplateCreate/create_snapshot_with_name

Flake rate in main: 43.33% (Passed 17 times, Failed 13 times)

Stack Traces | 33.5s run time
=== RUN   TestSnapshotTemplateCreate/create_snapshot_with_name
=== PAUSE TestSnapshotTemplateCreate/create_snapshot_with_name
=== CONT  TestSnapshotTemplateCreate/create_snapshot_with_name
    snapshot_template_test.go:79: 
        	Error Trace:	.../api/sandboxes/snapshot_template_test.go:79
        	Error:      	Not equal: 
        	            	expected: 201
        	            	actual  : 409
        	Test:       	TestSnapshotTemplateCreate/create_snapshot_with_name
--- FAIL: TestSnapshotTemplateCreate/create_snapshot_with_name (33.55s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestUpdateNetworkConfig

Flake rate in main: 69.70% (Passed 20 times, Failed 46 times)

Stack Traces | 33.9s run time
=== RUN   TestUpdateNetworkConfig
=== PAUSE TestUpdateNetworkConfig
=== CONT  TestUpdateNetworkConfig
--- FAIL: TestUpdateNetworkConfig (33.87s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false

Flake rate in main: 68.25% (Passed 20 times, Failed 43 times)

Stack Traces | 2.5s run time
=== RUN   TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false
Executing command curl in sandbox idp02pj8i5jjy0jpr9dap
    sandbox_network_update_test.go:372: Command [curl] output: event:{start:{pid:1366}}
    sandbox_network_update_test.go:372: Command [curl] output: event:{end:{exit_code:35  exited:true  status:"exit status 35"  error:"exit status 35"}}
Executing command curl in sandbox idp02pj8i5jjy0jpr9dap
    sandbox_network_update_test.go:372: Command [curl] output: event:{start:{pid:1367}}
    sandbox_network_update_test.go:372: Command [curl] output: event:{end:{exit_code:35  exited:true  status:"exit status 35"  error:"exit status 35"}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{start:{pid:1368}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{data:{stdout:"HTTP/2 302 \r\nx-content-type-options: nosniff\r\nlocation: https://dns.google/\r\ndate: Wed, 06 May 2026 10:40:17 GMT\r\ncontent-type: text/html; charset=UTF-8\r\nserver: HTTP server (unknown)\r\ncontent-length: 216\r\nx-xss-protection: 0\r\nx-frame-options: SAMEORIGIN\r\nalt-svc: h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\r\n\r\n"}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{end:{exited:true  status:"exit status 0"}}
    sandbox_network_update_test.go:391: Command [curl] completed successfully in sandbox idp02pj8i5jjy0jpr9dap
    sandbox_network_update_test.go:391: 
        	Error Trace:	.../api/sandboxes/sandbox_network_out_test.go:74
        	            				.../api/sandboxes/sandbox_network_update_test.go:60
        	            				.../api/sandboxes/sandbox_network_update_test.go:391
        	Error:      	An error is expected but got nil.
        	Test:       	TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false
        	Messages:   	https://8.8.8.8 should be blocked
--- FAIL: TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false (2.50s)
github.com/e2b-dev/infra/tests/integration/internal/tests/envd::TestBindLocalhost

Flake rate in main: 48.08% (Passed 27 times, Failed 25 times)

Stack Traces | 0s run time
=== RUN   TestBindLocalhost
=== PAUSE TestBindLocalhost
=== CONT  TestBindLocalhost
--- FAIL: TestBindLocalhost (0.00s)
github.com/e2b-dev/infra/tests/integration/internal/tests/envd::TestBindLocalhost/bind_0_0_0_0

Flake rate in main: 54.29% (Passed 16 times, Failed 19 times)

Stack Traces | 6.9s run time
=== RUN   TestBindLocalhost/bind_0_0_0_0
=== PAUSE TestBindLocalhost/bind_0_0_0_0
=== CONT  TestBindLocalhost/bind_0_0_0_0
    localhost_bind_test.go:69: Command [python] output: event:{start:{pid:1269}}
Executing command python in sandbox iyfs8zdstcdw2i0bqpsdw
    localhost_bind_test.go:90: 
        	Error Trace:	.../tests/envd/localhost_bind_test.go:90
        	Error:      	Not equal: 
        	            	expected: 200
        	            	actual  : 502
        	Test:       	TestBindLocalhost/bind_0_0_0_0
        	Messages:   	Unexpected status code 502 for bind address 0.0.0.0
--- FAIL: TestBindLocalhost/bind_0_0_0_0 (6.90s)
github.com/e2b-dev/infra/tests/integration/internal/tests/envd::TestBindLocalhost/bind_::1

Flake rate in main: 55.56% (Passed 16 times, Failed 20 times)

Stack Traces | 7.33s run time
=== RUN   TestBindLocalhost/bind_::1
=== PAUSE TestBindLocalhost/bind_::1
=== CONT  TestBindLocalhost/bind_::1
Executing command python in sandbox ik414ajfwkxle67402ckt
    localhost_bind_test.go:69: Command [python] output: event:{start:{pid:1269}}
    localhost_bind_test.go:90: 
        	Error Trace:	.../tests/envd/localhost_bind_test.go:90
        	Error:      	Not equal: 
        	            	expected: 200
        	            	actual  : 502
        	Test:       	TestBindLocalhost/bind_::1
        	Messages:   	Unexpected status code 502 for bind address ::1
--- FAIL: TestBindLocalhost/bind_::1 (7.33s)
github.com/e2b-dev/infra/tests/integration/internal/tests/envd::TestBindLocalhost/bind_localhost

Flake rate in main: 55.56% (Passed 16 times, Failed 20 times)

Stack Traces | 6.84s run time
=== RUN   TestBindLocalhost/bind_localhost
=== PAUSE TestBindLocalhost/bind_localhost
=== CONT  TestBindLocalhost/bind_localhost
Executing command python in sandbox ifn6yw0pf9kdbs7uq6t6s
    localhost_bind_test.go:69: Command [python] output: event:{start:{pid:1269}}
    localhost_bind_test.go:90: 
        	Error Trace:	.../tests/envd/localhost_bind_test.go:90
        	Error:      	Not equal: 
        	            	expected: 200
        	            	actual  : 502
        	Test:       	TestBindLocalhost/bind_localhost
        	Messages:   	Unexpected status code 502 for bind address localhost
--- FAIL: TestBindLocalhost/bind_localhost (6.84s)
github.com/e2b-dev/infra/tests/integration/internal/tests/orchestrator::TestSandboxMemoryIntegrity

Flake rate in main: 54.35% (Passed 21 times, Failed 25 times)

Stack Traces | 0s run time
=== RUN   TestSandboxMemoryIntegrity
=== PAUSE TestSandboxMemoryIntegrity
=== CONT  TestSandboxMemoryIntegrity
--- FAIL: TestSandboxMemoryIntegrity (0.00s)
github.com/e2b-dev/infra/tests/integration/internal/tests/orchestrator::TestSandboxMemoryIntegrity/stress-ng_verify

Flake rate in main: 56.76% (Passed 16 times, Failed 21 times)

Stack Traces | 34.2s run time
=== RUN   TestSandboxMemoryIntegrity/stress-ng_verify
=== PAUSE TestSandboxMemoryIntegrity/stress-ng_verify
=== CONT  TestSandboxMemoryIntegrity/stress-ng_verify
Executing command bash in sandbox ip0ujq9xiuicspiaxjh0b (user: root)
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{start:{pid:1268}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Hit:1 http://deb.debian.org/debian bookworm InRelease\nHit:2 http://deb.debian.org/debian bookworm-updates InRelease\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Hit:3 http://deb.debian.org/debian-security bookworm-security InRelease\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Reading package lists..."}}
Executing command bash in sandbox ip0ujq9xiuicspiaxjh0b (user: root)
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Reading package lists..."}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Building dependency tree..."}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"\nReading state information..."}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"The following additional packages will be installed:\n  libdrm-common libdrm2 libegl-mesa0 libegl1 libgbm1 libglapi-mesa libgles2\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"  libglvnd0 libipsec-mb1 libjudydebian1 libsctp1 libwayland-client0\n  libwayland-server0 libx11-xcb1 libxcb-dri2-0 libxcb-dri3-0 libxcb-present0\n  libxcb-randr0 libxcb-sync1 libxcb-xfixes0 libxshmfence1\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Suggested packages:\n  lksctp-tools\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"The following NEW packages will be installed:\n  libdrm-common libdrm2 libegl-mesa0 libegl1 libgbm1 libglapi-mesa libgles2\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"  libglvnd0 libipsec-mb1 libjudydebian1 libsctp1 libwayland-client0\n  libwayland-server0 libx11-xcb1 libxcb-dri2-0 libxcb-dri3-0 libxcb-present0\n  libxcb-randr0 libxcb-sync1 libxcb-xfixes0 libxshmfence1 stress-ng time\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"0 upgraded, 23 newly installed, 0 to remove and 146 not upgraded.\nNeed to get 4781 kB of archives.\nAfter this operation, 25.6 MB of additional disk space will be used.\nGet:1 http://deb.debian.org/debian bookworm/main amd64 libdrm-common all 2.4.114-1 [7112 B]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:2 http://deb.debian.org/debian bookworm/main amd64 libdrm2 amd64 2.4.114-1+b1 [37.5 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:3 http://deb.debian.org/debian bookworm/main amd64 libwayland-server0 amd64 1.21.0-1 [35.9 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:4 http://deb.debian.org/debian bookworm/main amd64 libgbm1 amd64 22.3.6-1+deb12u1 [38.0 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:5 http://deb.debian.org/debian bookworm/main amd64 libglapi-mesa amd64 22.3.6-1+deb12u1 [35.7 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:6 http://deb.debian.org/debian bookworm/main amd64 libwayland-client0 amd64 1.21.0-1 [28.3 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:7 http://deb.debian.org/debian bookworm/main amd64 libx11-xcb1 amd64 2:1.8.4-2+deb12u2 [192 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:8 http://deb.debian.org/debian bookworm/main amd64 libxcb-dri2-0 amd64 1.15-1 [107 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:9 http://deb.debian.org/debian bookworm/main amd64 libxcb-dri3-0 amd64 1.15-1 [107 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:10 http://deb.debian.org/debian bookworm/main amd64 libxcb-present0 amd64 1.15-1 [105 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:11 http://deb.debian.org/debian bookworm/main amd64 libxcb-randr0 amd64 1.15-1 [117 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:12 http://deb.debian.org/debian bookworm/main amd64 libxcb-sync1 amd64 1.15-1 [109 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:13 http://deb.debian.org/debian bookworm/main amd64 libxcb-xfixes0 amd64 1.15-1 [109 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:14 http://deb.debian.org/debian bookworm/main amd64 libxshmfence1 amd64 1.3-1 [8820 B]\nGet:15 http://deb.debian.org/debian bookworm/main amd64 libegl-mesa0 amd64 22.3.6-1+deb12u1 [114 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:16 http://deb.debian.org/debian bookworm/main amd64 libglvnd0 amd64 1.6.0-1 [51.8 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:17 http://deb.debian.org/debian bookworm/main amd64 libgles2 amd64 1.6.0-1 [16.8 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:18 http://deb.debian.org/debian bookworm/main amd64 libipsec-mb1 amd64 1.3-2 [981 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:19 http://deb.debian.org/debian bookworm/main amd64 libjudydebian1 amd64 1.0.5-5+b2 [102 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:20 http://deb.debian.org/debian bookworm/main amd64 libsctp1 amd64 1.0.19+dfsg-2 [29.7 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:21 http://deb.debian.org/debian bookworm/main amd64 libegl1 amd64 1.6.0-1 [33.7 kB]\nGet:22 http://deb.debian.org/debian bookworm/main amd64 stress-ng amd64 0.15.06-2 [2363 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:23 http://deb.debian.org/debian bookworm/main amd64 time amd64 1.9-0.2 [50.8 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stderr:"debconf: delaying package configuration, since apt-utils is not installed\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Fetched 4781 kB in 2s (3087 kB/s)\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libdrm-common.\r\n(Reading database ... \r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 5%\r(Reading database ... 10%\r(Reading database ... 15%\r(Reading database ... 20%\r(Reading database ... 25%\r(Reading database ... 30%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 35%\r(Reading database ... 40%\r(Reading database ... 45%\r(Reading database ... 50%\r(Reading database ... 55%\r(Reading database ... 60%\r(Reading database ... 65%\r"}}
Executing command bash in sandbox iklt2s95pf7s8y4z1db2g (user: root)
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 70%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 75%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 80%\r"}}
Executing command bash in sandbox iklt2s95pf7s8y4z1db2g (user: root)
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 85%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 90%\r"}}
Executing command bash in sandbox iklt2s95pf7s8y4z1db2g (user: root)
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 95%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 100%\r(Reading database ... 25971 files and directories currently installed.)\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../00-libdrm-common_2.4.114-1_all.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libdrm-common (2.4.114-1) ...\r\n"}}
Executing command bash in sandbox izdeq5japp57skqd4gibg (user: root)
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libdrm2:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../01-libdrm2_2.4.114-1+b1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libdrm2:amd64 (2.4.114-1+b1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libwayland-server0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../02-libwayland-server0_1.21.0-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libwayland-server0:amd64 (1.21.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libgbm1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../03-libgbm1_22.3.6-1+deb12u1_amd64.deb ..."}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libgbm1:amd64 (22.3.6-1+deb12u1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libglapi-mesa:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../04-libglapi-mesa_22.3.6-1+deb12u1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libglapi-mesa:amd64 (22.3.6-1+deb12u1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libwayland-client0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../05-libwayland-client0_1.21.0-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libwayland-client0:amd64 (1.21.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libx11-xcb1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../06-libx11-xcb1_2%3a1.8.4-2+deb12u2_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libx11-xcb1:amd64 (2:1.8.4-2+deb12u2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-dri2-0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../07-libxcb-dri2-0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-dri2-0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-dri3-0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../08-libxcb-dri3-0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-dri3-0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-present0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../09-libxcb-present0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-present0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-randr0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../10-libxcb-randr0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-randr0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-sync1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../11-libxcb-sync1_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-sync1:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-xfixes0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../12-libxcb-xfixes0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-xfixes0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxshmfence1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../13-libxshmfence1_1.3-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxshmfence1:amd64 (1.3-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libegl-mesa0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../14-libegl-mesa0_22.3.6-1+deb12u1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libegl-mesa0:amd64 (22.3.6-1+deb12u1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libglvnd0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../15-libglvnd0_1.6.0-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libglvnd0:amd64 (1.6.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libgles2:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../16-libgles2_1.6.0-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libgles2:amd64 (1.6.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libipsec-mb1.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../17-libipsec-mb1_1.3-2_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libipsec-mb1 (1.3-2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libjudydebian1.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../18-libjudydebian1_1.0.5-5+b2_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libjudydebian1 (1.0.5-5+b2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libsctp1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../19-libsctp1_1.0.19+dfsg-2_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libsctp1:amd64 (1.0.19+dfsg-2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libegl1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../20-libegl1_1.6.0-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libegl1:amd64 (1.6.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package stress-ng.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../21-stress-ng_0.15.06-2_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking stress-ng (0.15.06-2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package time.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../22-time_1.9-0.2_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking time (1.9-0.2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libxcb-dri3-0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libwayland-server0:amd64 (1.21.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libx11-xcb1:amd64 (2:1.8.4-2+deb12u2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up time (1.9-0.2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libxcb-xfixes0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libglvnd0:amd64 (1.6.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libjudydebian1 (1.0.5-5+b2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libxcb-present0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libipsec-mb1 (1.3-2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libgles2:amd64 (1.6.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libxcb-sync1:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libglapi-mesa:amd64 (22.3.6-1+deb12u1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libxcb-dri2-0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libsctp1:amd64 (1.0.19+dfsg-2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libxshmfence1:amd64 (1.3-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libxcb-randr0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libdrm-common (2.4.114-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libwayland-client0:amd64 (1.21.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libdrm2:amd64 (2.4.114-1+b1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libgbm1:amd64 (22.3.6-1+deb12u1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libegl-mesa0:amd64 (22.3.6-1+deb12u1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up libegl1:amd64 (1.6.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Setting up stress-ng (0.15.06-2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Processing triggers for libc-bin (2.36-9+deb12u3) ...\r\n"}}
    sandbox_memory_integrity_test.go:142: 
        	Error Trace:	.../tests/orchestrator/sandbox_memory_integrity_test.go:142
        	Error:      	Received unexpected error:
        	            	failed to execute command bash in sandbox ilzhqfy6qh5qc0m13uqkf: invalid_argument: protocol error: incomplete envelope: unexpected EOF
        	Test:       	TestSandboxMemoryIntegrity/stress-ng_verify
--- FAIL: TestSandboxMemoryIntegrity/stress-ng_verify (34.17s)
github.com/e2b-dev/infra/tests/integration/internal/tests/orchestrator::TestSandboxMemoryIntegrity/tmpfs_hash

Flake rate in main: 58.97% (Passed 16 times, Failed 23 times)

Stack Traces | 31.8s run time
=== RUN   TestSandboxMemoryIntegrity/tmpfs_hash
=== PAUSE TestSandboxMemoryIntegrity/tmpfs_hash
=== CONT  TestSandboxMemoryIntegrity/tmpfs_hash
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{start:{pid:1268}}
Executing command bash in sandbox ilzhqfy6qh5qc0m13uqkf (user: root)
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Hit:1 http://deb.debian.org/debian bookworm InRelease\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Hit:2 http://deb.debian.org/debian bookworm-updates InRelease\nHit:3 http://deb.debian.org/debian-security bookworm-security InRelease\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Reading package lists..."}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Reading package lists..."}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Building dependency tree..."}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"\nReading state information..."}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"The following NEW packages will be installed:\n  time\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"0 upgraded, 1 newly installed, 0 to remove and 146 not upgraded.\nNeed to get 50.8 kB of archives.\nAfter this operation, 132 kB of additional disk space will be used.\nGet:1 http://deb.debian.org/debian bookworm/main amd64 time amd64 1.9-0.2 [50.8 kB]\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stderr:"debconf: delaying package configuration, since apt-utils is not installed\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Fetched 50.8 kB in 0s (308 kB/s)\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package time.\r\n(Reading database ... \r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 5%\r(Reading database ... 10%\r(Reading database ... 15%\r(Reading database ... 20%\r(Reading database ... 25%\r(Reading database ... 30%\r(Reading database ... 35%\r(Reading database ... 40%\r(Reading database ... 45%\r(Reading database ... 50%\r(Reading database ... 55%\r(Reading database ... 60%\r(Reading database ... 65%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 70%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 75%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 80%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 85%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 90%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 95%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 100%\r(Reading database ... 25971 files and directories currently installed.)\r\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../time_1.9-0.2_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Unpacking time (1.9-0.2) ...\r\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Setting up time (1.9-0.2) ...\r\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{end:{exited:true status:"exit status 0"}}
    sandbox_memory_integrity_test.go:33: Command [bash] completed successfully in sandbox ixj7gtld3akbwiyfk11h6
    sandbox_memory_integrity_test.go:59: Command [bash] output: event:{start:{pid:1396}}
    sandbox_memory_integrity_test.go:59: Command [bash] output: event:{data:{stdout:"Total memory: 985 MB\nUsed memory before tmpfs mount: 226 MB\nFree memory before tmpfs mount: 758 MB\nMemory to use in integrity test (80% of free, min 64MB): 606 MB\n"}}
    sandbox_memory_integrity_test.go:60: 
        	Error Trace:	.../tests/orchestrator/sandbox_memory_integrity_test.go:60
        	Error:      	Received unexpected error:
        	            	failed to execute command bash in sandbox ixj7gtld3akbwiyfk11h6: invalid_argument: protocol error: incomplete envelope: unexpected EOF
        	Test:       	TestSandboxMemoryIntegrity/tmpfs_hash
--- FAIL: TestSandboxMemoryIntegrity/tmpfs_hash (31.82s)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 62d63c2d5f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/envd/internal/services/process/handler/multiplex.go
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The unbuffered channel returned by Fork can cause a deadlock during bootstrap event writes if the consumer goroutine exits early. Providing a buffer of at least 1 ensures the initial write completes without hanging the request handler. Iterating over the channels slice without holding a mutex is unsafe because the remove method modifies the underlying array in-place. This race condition can cause the fan-out loop to skip subscribers or process them multiple times, so the loop should use a shallow copy of the slice.

Comment thread packages/envd/internal/services/process/handler/multiplex.go
Comment thread packages/envd/internal/services/process/handler/multiplex.go
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 62d63c2. Configure here.

Comment thread packages/envd/internal/services/process/handler/multiplex.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants