Skip to content

feat(local): add --no-watch flag to disable hot reload#8196

Open
roger-zhangg wants to merge 14 commits into
aws:developfrom
roger-zhangg:hot-swap-fix
Open

feat(local): add --no-watch flag to disable hot reload#8196
roger-zhangg wants to merge 14 commits into
aws:developfrom
roger-zhangg:hot-swap-fix

Conversation

@roger-zhangg
Copy link
Copy Markdown
Member

@roger-zhangg roger-zhangg commented Jul 30, 2025

Which issue(s) does this change fix?

#8782

Why is this change necessary?

The AWS SAM CLI file watcher caused unstable behavior during local development with --warm-containers:

  • Multiple Lambda functions sharing a CodeUri — a single change in any function falsely invalidated all of them, killing every running warm container and demoting back to LAZY mode. Reproed in LoopBack apps that auto-create temporary .sandbox directories (8+ minute startup times).
  • High-overhead file watching environments — Microsoft Defender on Windows, large monorepos, etc. make the file observer dominate CPU/IO and effectively block local invocation. See Feature request: SAM Local Flag to Disable Hot Reload #8782.

How does it address the issue?

Adds a --no-watch flag to sam local start-api and sam local start-lambda. When supplied with --warm-containers, SAM CLI skips creating any file observers (template watcher and the per-function LambdaFunctionObserver). Local code or template changes will not restart the running container — stop and rerun the command to pick up changes.

The flag is forwarded as a kwarg through RefreshableSamFunctionProvider and WarmLambdaRuntime. With no_watch=True, no observer is constructed, and every watch / unwatch / start / stop call becomes a guarded no-op.

Also adds debug logging around LambdaFunctionObserver lock acquire / resource processing to help triage future watcher issues.

What side effects does this change have?

  • --no-watch only takes effect with --warm-containers. When supplied without warm containers, the flag is ignored and a WARNING is logged. The cold-mode SamFunctionProvider (which doesn't accept no_watch) never receives the flag — addresses the earlier review concern about an uncaught error in that path.
  • New kwarg no_watch: Optional[bool] = False on InvokeContext, RefreshableSamFunctionProvider, and WarmLambdaRuntime. Defaults preserve existing behavior; no caller is required to update.
  • Refreshes a stale WarmLambdaRuntime.__init__ docstring (warm_containers → current parameters) flagged in earlier review.
  • New no_watch entry in schema/samcli.json for both local_start_api and local_start_lambda.

Mandatory Checklist

PRs will only be reviewed after checklist is complete

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@roger-zhangg roger-zhangg requested a review from a team as a code owner July 30, 2025 01:58
vicheey
vicheey previously approved these changes Jul 30, 2025
Comment thread samcli/lib/utils/file_observer.py Outdated
reedham-aws
reedham-aws previously approved these changes Jul 30, 2025
@vicheey
Copy link
Copy Markdown
Contributor

vicheey commented Sep 9, 2025

DO NOT MERGE.

@roger-zhangg roger-zhangg deleted the branch aws:develop September 27, 2025 01:25
@roger-zhangg roger-zhangg reopened this Sep 27, 2025
@roger-zhangg roger-zhangg changed the base branch from hot-swap-fix to develop September 27, 2025 01:33
@roger-zhangg roger-zhangg dismissed stale reviews from reedham-aws and vicheey September 27, 2025 01:33

The base branch was changed.

@roger-zhangg roger-zhangg reopened this Sep 29, 2025
@roger-zhangg
Copy link
Copy Markdown
Member Author

This failing test seems unrelated, but will take a look

@roger-zhangg
Copy link
Copy Markdown
Member Author

also passed on my local

(.venv) ruojiazh@842f577b9ad2 aws-sam-cli % pytest tests/smoke/test_all_commands.py::TestAllCommands -n 4
======== 510 passed in 111.96s (0:01:51) ========

@reedham-aws
Copy link
Copy Markdown
Contributor

What is the reason that we no longer allow customers to provide a list of files/dirs to be ignored? It seems like that was the original intention.

@roger-zhangg
Copy link
Copy Markdown
Member Author

roger-zhangg commented Sep 30, 2025

What is the reason that we no longer allow customers to provide a list of files/dirs to be ignored? It seems like that was the original intention.

The root cause was actually not that. Originally the assumed root cause was few node lib is constantly changing when function is invoking and therefore triggering our file watcher, but then it turns out it's just the file watcher is somehow lagging and it picks up the filechanges way later than it should be. So the lib changes are done in build, which should be a legit change that should be picked up.

For what here is fixing, is in some sam project setup, it might have multiple lambda function sharing a same code dir (like a same file with different function as entrypoint). When we are doing sam local start-api, even only one function changes in code dir, our watcher will think every function has changed. Therefore killing the running container and putting everything into LAZY mode again. So the ignore pattern can't really fix this issue.

Instead, providing the --no-watch flag gives user more control on the scenario above. They can kill and restart the command when a reload is actually required.

reedham-aws
reedham-aws previously approved these changes Sep 30, 2025
Comment thread samcli/local/lambdafn/runtime.py
Comment thread tests/unit/commands/local/cli_common/test_invoke_context.py
Comment thread samcli/commands/local/start_api/cli.py Outdated
Comment thread samcli/commands/local/cli_common/invoke_context.py Outdated
Resolve conflicts and address PR feedback:

- Use kwargs (`function_logical_ids`, `no_watch`) on `RefreshableSamFunctionProvider` instead of brittle positional `args.extend(...)` (addresses valerena's review concern about uncaught errors when --no-watch is used without --warm-containers).
- When --no-watch is supplied without --warm-containers, log a warning, ignore the flag, and never forward `no_watch` to the cold-mode `SamFunctionProvider` (which doesn't accept it).
- Combine the merge-conflicting changes in `WarmLambdaRuntime.create()`: keep develop's threading lock + container_dns refactor and gate observer.watch/start/unwatch behind `self._observer is not None` so --no-watch is safe.
- Update --no-watch help text to clarify the --warm-containers prerequisite and the use case from issue aws#8782 (file watching causes high CPU/IO with Microsoft Defender / large monorepos / .sandbox dirs).
- Regenerate schema/samcli.json.
- Add unit tests covering: provider kwarg routing for warm mode, warning + skip for cold mode, RefreshableSamFunctionProvider observer skipped with no_watch=True, and WarmLambdaRuntime no_watch lifecycle no-ops.
Apply black formatting after merge of develop into hot-swap-fix.
- Add no_watch docstring entry to RefreshableSamFunctionProvider.
- Initialize self._observer = None up front in RefreshableSamFunctionProvider so the
  type annotation is unconditional and the no-watch branch is implied.
- Drop incidental whitespace-only hunks (blank line in invoke_context.__enter__,
  blank line in SingletonFileObserver.__init__) flagged during review.
Copy link
Copy Markdown
Collaborator

@aws-sam-cli-bot aws-sam-cli-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 Results

Reviewed: 1aeab0a..7763e3c
Files: 16
Comments: 1

Comment thread samcli/commands/local/cli_common/options.py
@roger-zhangg roger-zhangg changed the title Fix file watcher infinite loops and improve logging for local invoke feat(local): add --no-watch flag to disable hot reload May 8, 2026
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.

6 participants