Skip to content

Latest commit

 

History

History
139 lines (101 loc) · 4.9 KB

File metadata and controls

139 lines (101 loc) · 4.9 KB

Running the simfarm worker on the Windows PC (WSL2)

The worker runs inside WSL2 Linux, but Tailscale is installed on the Windows host. WSL2 sits behind Windows' internal NAT with its own IP, so by default the client can't reach the worker over your tailnet. Pick one of the two networking fixes below.


Step 1 — install the toolchain inside WSL2

Open your WSL2 distro (Ubuntu) and run:

# uv: the same Python manager as the client, so client/worker versions match
curl -LsSf https://astral.sh/uv/install.sh | sh
exec $SHELL          # reload PATH

# clone/copy the project onto the PC, then:
cd ~/simfarm         # wherever you put it
uv sync              # installs simfarm + deps into .venv (Python 3.13)

# your simulation dependencies must live in the SAME env, e.g.:
uv pip install numpy pandas scipy numba
# for GPU/ML: install the CUDA build of torch that matches your driver
# uv pip install torch --index-url https://download.pytorch.org/whl/cu124

Verify CUDA is visible inside WSL2 (only if you have an NVIDIA GPU):

nvidia-smi           # should list your GPU; simfarm auto-detects it

Step 2 — pick a networking mode

Option A — WSL2 mirrored networking (cleanest, Win11 22H2+)

On the Windows host, edit C:\Users\<you>\.wslconfig (create if absent):

[wsl2]
networkingMode=mirrored

Then from an admin PowerShell: wsl --shutdown and reopen WSL2. Now WSL2 shares the Windows network stack and the host's Tailscale IP — the worker on 0.0.0.0:8765 is reachable at the PC's tailscale hostname directly.

Option B — netsh portproxy (any Windows version)

Find the WSL2 internal IP (run inside WSL2): ip addr show eth0 | grep inet. Then from an admin PowerShell on Windows, forward the port:

netsh interface portproxy add v4tov4 `
  listenaddress=0.0.0.0 listenport=8765 `
  connectaddress=<WSL2_IP> connectport=8765
# allow it through the firewall
New-NetFirewallRule -DisplayName "simfarm" -Direction Inbound `
  -LocalPort 8765 -Protocol TCP -Action Allow

Note: the WSL2 IP changes on reboot, so re-run the add line (or script it) if you use Option B. Option A avoids this entirely.


Step 3 — start the worker

# set a shared secret (any random string); the client must use the same one
export SIMFARM_TOKEN="$(openssl rand -hex 16)"
echo "token: $SIMFARM_TOKEN"        # copy this to the client

uv run simfarm worker               # binds 0.0.0.0:8765

To keep it running after you close the terminal, use tmux, nohup, or a systemd user service inside WSL2.


Step 3b — keeping it up across logons and crashes (optional)

The worker must survive logons, crashes, and terminal closes. Two Windows Scheduled Tasks run scripts/start_worker.sh (idempotent: exits 0 if the worker already answers on :8765, otherwise kills the port and supervises a restart loop). Both launch through a hidden-window VBS wrapper so no console flashes up:

%USERPROFILE%\simfarm-hidden.vbs:

CreateObject("Wscript.Shell").Run "wsl.exe -u $USER -- bash $HOME/simfarm/scripts/start_worker.sh", 0

Created from any user shell on the PC (no admin needed):

schtasks /Create /TN simfarm-worker /SC ONLOGON /TR "wscript.exe %USERPROFILE%\simfarm-hidden.vbs" /F
schtasks /Create /TN simfarm-watchdog /SC MINUTE /MO 15 /TR "wscript.exe %USERPROFILE%\simfarm-hidden.vbs" /F
  • simfarm-worker (ONLOGON): starts the worker at logon.
  • simfarm-watchdog (every 15 min): revives a crashed worker mid-session; a healthy worker makes it a 1-second no-op.

The VBS Run ..., 0 call does not wait, so every task run completes immediately with result 0 while the wsl.exe supervisor loop persists as a detached process. Duplicate protection is in start_worker.sh itself: it exits early when :8765 answers, and kills the port holder before starting fresh when it doesn't.

Known limits (accepted):

  • Both tasks are "Interactive only" — after a cold boot someone must log on before the worker starts. A wake-on-LAN from full power-off boots to the login screen and the worker stays down. Fix = sleep the PC instead of shutting down (session + worker survive S3 sleep/resume, WoL works, draw is a few watts), or store task credentials / enable auto-logon (owner call).
  • Worth monitoring from the client side: GET http://<worker>:8765/info distinguishes the three states cleanly — any HTTP answer (including a 401) means alive, connection refused means the worker is down but the machine is up, and a timeout means the machine itself is off.

Step 4 — from the client, confirm reachability

export SIMFARM_TOKEN="<the token you copied>"
uv run simfarm ping <worker-tailscale-hostname>

You should see the worker's CPU count, GPU(s), and an "environment matches" line. If versions differ, align them — cloudpickle tolerates minor skew but big gaps (especially numpy/torch) can break deserialization.