Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions samcli/lib/utils/file_observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

import logging
import os
import platform
import threading
import uuid
Expand Down Expand Up @@ -183,11 +184,15 @@ def _on_change(self, resources: List[str], package_type: str) -> None:
package_type: str
determine if the changed resource is a source code path or an image name
"""
LOG.debug("Acquiring lock for _on_change to process %s %s resource changes: %s",
len(resources), package_type, resources)
with self._watch_lock:
changed_functions: List[FunctionConfig] = []
for resource in resources:
if self._observed_functions[package_type].get(resource, None):
changed_functions += self._observed_functions[package_type][resource]
LOG.debug("Acquired lock and processing %s changed functions from %s resources",
len(changed_functions), len(resources))
self._input_on_change(changed_functions)

def watch(self, function_config: FunctionConfig) -> None:
Expand All @@ -204,9 +209,13 @@ def watch(self, function_config: FunctionConfig) -> None:
ObserverException:
if not able to observe the input function source path/image
"""
LOG.debug("Acquiring lock for watch to observe %s function: %s",
function_config.packagetype, function_config.name)
with self._watch_lock:
if self.get_resources.get(function_config.packagetype, None):
resources = self.get_resources[function_config.packagetype](function_config)
LOG.debug("Acquired lock for watch, observing %s resources for function %s: %s",
len(resources), function_config.name, resources)
for resource in resources:
functions = self._observed_functions[function_config.packagetype].get(resource, [])
functions += [function_config]
Expand Down Expand Up @@ -415,6 +424,17 @@ class SingletonFileObserver(metaclass=Singleton):
A Singleton class that will observe some file system paths for any change for multiple purposes.
"""

# Ignore patterns for file watching to avoid infinite loops and unnecessary events
DEFAULT_IGNORE_PATTERNS = [
Comment thread
roger-zhangg marked this conversation as resolved.
Outdated
"*/node_modules/*/*", # Ignore changes within packages, but allow new packages
"*.tmp", # Ignore temporary files
"*.temp", # Ignore temporary files
"*/.git/*", # Ignore git directories
"*/__pycache__/*", # Ignore Python cache
"*.pyc", # Ignore Python compiled files
"*.log" # Ignore log files
]

def __init__(self) -> None:
"""
Initialize the file observer
Expand All @@ -424,12 +444,22 @@ def __init__(self) -> None:
self._observed_watches: Dict[str, ObservedWatch] = {}
self._watch_dog_observed_paths: Dict[str, List[str]] = {}
self._observer: BaseObserver = Observer()

# Use environment variable to control ignore patterns (default: enabled)
use_ignore_patterns = os.environ.get("SAM_USE_IGNORE_PATTERN", "true").lower() == "true"
ignore_patterns = self.DEFAULT_IGNORE_PATTERNS if use_ignore_patterns else []

if use_ignore_patterns:
LOG.debug("File observer using ignore patterns: %s", ignore_patterns)
else:
LOG.debug("File observer ignore patterns disabled via SAM_CLI_FILE_OBSERVER_IGNORE_PATTERNS")

self._code_modification_handler: PatternMatchingEventHandler = PatternMatchingEventHandler(
patterns=["*"], ignore_patterns=[], ignore_directories=False
patterns=["*"], ignore_patterns=ignore_patterns, ignore_directories=False
)

self._code_deletion_handler: PatternMatchingEventHandler = PatternMatchingEventHandler(
patterns=["*"], ignore_patterns=[], ignore_directories=False
patterns=["*"], ignore_patterns=ignore_patterns, ignore_directories=False
)

self._code_modification_handler.on_modified = self.on_change # type: ignore
Expand Down