Skip to content

chore: Simplify shared Roslyn worker builds - #1626

Merged
hatayama merged 2 commits into
v3-betafrom
refactor/hatayama/extract-shared-roslyn-worker-assembly-builder
Jul 8, 2026
Merged

hatayama merged 2 commits into
v3-betafrom
refactor/hatayama/extract-shared-roslyn-worker-assembly-builder

Conversation

@hatayama

@hatayama hatayama commented Jul 8, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Separate shared Roslyn worker assembly construction from process lifecycle orchestration.
  • Keep dynamic-code compilation and fallback behavior unchanged.

User Impact

  • Execute-dynamic-code continues to build, start, retry, and fall back exactly as before.
  • The smaller lifecycle host makes the remaining worker state and shutdown responsibilities easier to review.

Changes

  • Add SharedRoslynCompilerWorkerAssemblyBuilder to own compiler invocation, reference selection, response-file construction, quoting, build timeout/kill behavior, compiler output parsing, and stale assembly deletion.
  • Move the shared .NET invocation environment policy with the builder; both worker startup and compiler startup still set DOTNET_MULTILEVEL_LOOKUP=0.
  • Move the assembly-build result DTO to the builder and retarget the existing environment policy test directly.
  • Keep s_compileWorkerAssemblyForTests and its swap API in the host as mutable lifecycle test state.
  • The only non-move production change is splitting CompileWorkerAssembly into a host seam adapter and the builder implementation: test overrides are still evaluated first, while production delegates with the same four arguments.
  • Keep WorkerPaths, temporary-directory mutation, retry/lifecycle state, protocol handling, and shutdown in the host.
  • Reduce SharedRoslynCompilerWorkerHost from 865 to 677 lines.

Verification

  • dist/darwin-arm64/uloop compile --project-path "$(git rev-parse --show-toplevel)" (0 errors, 0 warnings)
  • SharedRoslynCompilerWorkerHostTests (10 passed)
  • ExternalCompilerPathResolverTests (15 passed, including worker-build fallback through the host seam)
  • StaticFacadeStateGuardTests (20 passed)
  • Confirmed that the builder has no reverse dependency on the host.
  • No IPC wire shape, worker protocol string, CLI/package protocol version, or release input changes.

Review in cubic

Move worker compiler invocation, response-file construction, references,
quoting, cleanup, and .NET process policy out of the lifecycle host. Keep the
mutable test override in the host through a narrow seam adapter.
@coderabbitai

coderabbitai Bot commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Worker assembly build logic (response-file writing, subprocess launch/timeout handling, reference-set construction, environment configuration, and quoting helpers) is extracted from SharedRoslynCompilerWorkerHost into a new SharedRoslynCompilerWorkerAssemblyBuilder class. The host delegates to the new class; related tests are updated accordingly.

Changes

Worker assembly build extraction

Layer / File(s) Summary
New builder: contracts, environment config, and compilation core
Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/DynamicCompilation/SharedRoslynCompilerWorkerAssemblyBuilder.cs
Adds WorkerAssemblyBuildResult type, constants, ConfigureWorkerDotnetRuntimeEnvironment, and CompileWorkerAssembly implementing process launch, 30s timeout, and stdout/stderr parsing.
Builder: reference set, response file, and helper utilities
.../SharedRoslynCompilerWorkerAssemblyBuilder.cs
Adds BuildWorkerReferenceSet, WriteWorkerCompilerResponseFile, DeleteWorkerAssemblyIfPresent, quoting helpers, and AddIfExists.
Host delegation and cleanup
Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/DynamicCompilation/SharedRoslynCompilerWorkerHost.cs
Removes duplicated local types, constants, compilation logic, quoting helpers, and DeleteWorkerAssemblyIfPresent, replacing them with delegated calls to the new builder in EnsureWorkerAssemblyBuilt, CreateWorkerStartInfo, and CompileWorkerAssembly.
Test updates for extracted builder
Assets/Tests/Editor/DynamicCodeToolTests/SharedRoslynCompilerWorkerHostTests.cs
Updates multilevel-lookup test to use SharedRoslynCompilerWorkerAssemblyBuilder constants/method instead of host equivalents.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Host as SharedRoslynCompilerWorkerHost
  participant Builder as SharedRoslynCompilerWorkerAssemblyBuilder
  participant Process as dotnet process

  Host->>Builder: CompileWorkerAssembly(...)
  Builder->>Builder: WriteWorkerCompilerResponseFile(...)
  Builder->>Process: Start dotnet with response file
  Builder->>Process: ConfigureWorkerDotnetRuntimeEnvironment(startInfo)
  Process-->>Builder: stdout/stderr, exit code (or timeout kill)
  Builder-->>Host: WorkerAssemblyBuildResult
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main refactor: simplifying shared Roslyn worker builds by moving assembly construction out of the host.
Description check ✅ Passed The description is directly aligned with the refactor and clearly explains the builder extraction and unchanged behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/hatayama/extract-shared-roslyn-worker-assembly-builder

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 4 files

You’re at about 92% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/DynamicCompilation/SharedRoslynCompilerWorkerAssemblyBuilder.cs (1)

105-124: 🩺 Stability & Availability | 🔵 Trivial | ⚖️ Poor tradeoff

Optional: bound the post-kill stream drain.

On the timeout path you Kill() then WaitForExit(500), but the subsequent Task.WaitAll(stdoutTask, stderrTask) (Line 113) has no timeout. If the redirected pipes stay open (e.g., kill didn't fully tear down the dotnet exec process within 500ms), this blocks the compilation thread indefinitely while holding SharedCompilerWorkerLock. Consider a bounded Task.WaitAll(new[]{stdoutTask, stderrTask}, someTimeout) so the timeout failure always returns.

Behavior is carried over from the host, so this is not a regression—just a resilience hardening opportunity while the logic is being relocated.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/DynamicCompilation/SharedRoslynCompilerWorkerAssemblyBuilder.cs`
around lines 105 - 124, The timeout handling in
SharedRoslynCompilerWorkerAssemblyBuilder still blocks indefinitely on
Task.WaitAll(stdoutTask, stderrTask) after Kill() and WaitForExit(500), which
can hold SharedCompilerWorkerLock forever if the pipes never close. Update the
timeout path in the worker process wait logic to use a bounded wait for the
stream-drain tasks, and if that wait expires, return the existing
worker_compiler_timeout StartFailure instead of waiting unboundedly. Keep the
fix localized around the process.WaitForExit timeout branch and the
stdoutTask/stderrTask handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/DynamicCompilation/SharedRoslynCompilerWorkerAssemblyBuilder.cs`:
- Around line 105-124: The timeout handling in
SharedRoslynCompilerWorkerAssemblyBuilder still blocks indefinitely on
Task.WaitAll(stdoutTask, stderrTask) after Kill() and WaitForExit(500), which
can hold SharedCompilerWorkerLock forever if the pipes never close. Update the
timeout path in the worker process wait logic to use a bounded wait for the
stream-drain tasks, and if that wait expires, return the existing
worker_compiler_timeout StartFailure instead of waiting unboundedly. Keep the
fix localized around the process.WaitForExit timeout branch and the
stdoutTask/stderrTask handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 777d8811-b210-495f-93be-94d7cae5d96a

📥 Commits

Reviewing files that changed from the base of the PR and between ed61757 and 6fa6a3a.

⛔ Files ignored due to path filters (1)
  • Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/DynamicCompilation/SharedRoslynCompilerWorkerAssemblyBuilder.cs.meta is excluded by none and included by none
📒 Files selected for processing (3)
  • Assets/Tests/Editor/DynamicCodeToolTests/SharedRoslynCompilerWorkerHostTests.cs
  • Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/DynamicCompilation/SharedRoslynCompilerWorkerAssemblyBuilder.cs
  • Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/DynamicCompilation/SharedRoslynCompilerWorkerHost.cs

@hatayama
hatayama merged commit 86d1fde into v3-beta Jul 8, 2026
10 checks passed
@hatayama
hatayama deleted the refactor/hatayama/extract-shared-roslyn-worker-assembly-builder branch July 8, 2026 16:40
RyanXie123 pushed a commit to RyanXie123/unity-cli-loop that referenced this pull request Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant