Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Handle BROKEN_PIPE_ERROR #5386

Merged
merged 12 commits into from
Jun 28, 2023
38 changes: 29 additions & 9 deletions samcli/lib/utils/file_observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Wraps watchdog to observe file system for any change.
"""
import logging
import platform
import threading
import uuid
from abc import ABC, abstractmethod
Expand All @@ -24,6 +25,7 @@
from samcli.local.lambdafn.config import FunctionConfig

LOG = logging.getLogger(__name__)
BROKEN_PIPE_ERROR = 109
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add some comment around what is this and how it is been used below?



class ResourceObserver(ABC):
Expand Down Expand Up @@ -264,15 +266,33 @@ def __init__(self, on_change: Callable) -> None:
self._lock: Lock = threading.Lock()

def _watch_images_events(self):
lucashuy marked this conversation as resolved.
Show resolved Hide resolved
for event in self.events:
if event.get("Action", None) != "tag":
continue
image_name = event["Actor"]["Attributes"]["name"]
if self._observed_images.get(image_name, None):
new_image_id = event["id"]
if new_image_id != self._observed_images[image_name]:
self._observed_images[image_name] = new_image_id
self._input_on_change([image_name])
try:
for event in self.events:
if event.get("Action", None) != "tag":
continue
image_name = event["Actor"]["Attributes"]["name"]
if self._observed_images.get(image_name, None):
new_image_id = event["id"]
if new_image_id != self._observed_images[image_name]:
self._observed_images[image_name] = new_image_id
self._input_on_change([image_name])
except Exception as exception:
# handle a pywintypes exception that gets thrown when trying to exit
# from a command that utilizes ImageObserver(s) in
# EAGER container mode (start-api, start-lambda)

# all containers would have been stopped, and deleted, however
# the pipes to those containers are still loaded somewhere

if not platform.system() == "Windows":
raise

win_error = getattr(exception, "winerror", None)

if not win_error == BROKEN_PIPE_ERROR:
raise

LOG.debug("Handling BROKEN_PIPE_ERROR pywintypes exception ignored gracefully")

def watch(self, resource: str) -> None:
"""
Expand Down