-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: Handle BROKEN_PIPE_ERROR #5386
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
Changes from all commits
b77fc1e
faf5a72
c1cd483
92ba8d0
fbdf8a9
67de9ac
10b124a
ed774d0
3e45f8e
1c34a3f
f04fca1
4248656
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
|
@@ -24,6 +25,8 @@ | |
| from samcli.local.lambdafn.config import FunctionConfig | ||
|
|
||
| LOG = logging.getLogger(__name__) | ||
| # Windows API error returned when attempting to perform I/O on closed pipe | ||
| BROKEN_PIPE_ERROR = 109 | ||
|
|
||
|
|
||
| class ResourceObserver(ABC): | ||
|
|
@@ -243,6 +246,44 @@ class ImageObserverException(ObserverException): | |
| """ | ||
|
|
||
|
|
||
| def broken_pipe_handler(func: Callable) -> Callable: | ||
| """ | ||
| Decorator to handle the Windows API BROKEN_PIPE_ERROR error. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| func: Callable | ||
| The method to wrap around | ||
| """ | ||
|
|
||
| # NOTE: As of right now, this checks for the Windows API error 109 | ||
| # specifically. This could be abstracted to potentially utilize a | ||
| # callback method to further customize this. | ||
|
|
||
| def wrapper(*args, **kwargs): | ||
| try: | ||
| return func(*args, **kwargs) | ||
| 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") | ||
|
|
||
| return wrapper | ||
|
|
||
|
|
||
| class ImageObserver(ResourceObserver): | ||
| """ | ||
| A class that will observe some docker images for any change. | ||
|
|
@@ -263,6 +304,7 @@ def __init__(self, on_change: Callable) -> None: | |
| self._images_observer_thread: Optional[Thread] = None | ||
| self._lock: Lock = threading.Lock() | ||
|
|
||
| @broken_pipe_handler | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not going to block on this. Might be even better if we can inject the behavior into the decorator. @os_exception_handler(platform="windows", exception=BROKEN_PIPE_ERROR)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting idea, though with this it might need a bit more rewriting/logic to be more generic. As of right now it has a pretty specific check for a particular error code vs a more generic callback/handler argument. I'll add a note in the code that this could be abstracted if something like this happens again |
||
| def _watch_images_events(self): | ||
| for event in self.events: | ||
| if event.get("Action", None) != "tag": | ||
|
|
||
There was a problem hiding this comment.
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?