-
Notifications
You must be signed in to change notification settings - Fork 67
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 a race when StopAtEOF is called #70
Open
tgummerer
wants to merge
1
commit into
nxadm:master
Choose a base branch
from
tgummerer:tg/fix-tail-race
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Currently when StopAtEOF is called, and we previously encountered an EOF already, we stop reading the file immediately. However when tailing a file, new data might have become available in the meantime, before the StopAtEOF is called. The watcher might however not have notified us about that yet. Instead of exiting immediately if that happens, and leaving the data that's already in the file unread, continue iterating until we get the *next* EOF, as we can be reasonably sure that that's the EOF the user meant to stop at, making sure to read all the data that has been written by the time StopAtEOF is called.
@nxadm, any interest in this? Can I do something to help get this landed? |
tgummerer
added a commit
to pulumi/pulumi
that referenced
this pull request
Dec 13, 2024
This fixes a couple of race conditions in the tail library, combining the ideas of nxadm/tail#70 and nxadm/tail#71. - Currently when StopAtEOF is called, and we previously encountered an EOF already, we stop reading the file immediately. However when tailing a file, new data might have become available in the meantime, before the StopAtEOF is called. The watcher might however not have notified us about that yet. Instead of exiting immediately if that happens, and leaving the data that's already in the file unread, continue iterating until we get the next EOF, as we can be reasonably sure that that's the EOF the user meant to stop at, making sure to read all the data that has been written by the time StopAtEOF is called. - When a StopAtEOF() is called the code should continue to send all lines to the Lines channel. The issue here is if the caller is not ready to receive a new line the code blocks as it is using a unbuffered channel. However <-tail.Dying() would return in this case so the line was skipped. This means that the caller did not get all lines until EOF. Now we still want to skip in case any other reason for kill was given therefore add special logic to only not read the Dying channel on the EOF case. The one downside is that StopAtEOF() could block forever if the caller never reads new Lines but this seems logical to me. If the caller wants to wait for EOF but never reads remaining Lines this would be a bug on their end. Co-authored-by: Paul Holzinger <[email protected]>
tgummerer
added a commit
to pulumi/pulumi
that referenced
this pull request
Dec 13, 2024
This fixes a couple of race conditions in the tail library, combining the ideas of nxadm/tail#70 and nxadm/tail#71. - Currently when StopAtEOF is called, and we previously encountered an EOF already, we stop reading the file immediately. However when tailing a file, new data might have become available in the meantime, before the StopAtEOF is called. The watcher might however not have notified us about that yet. Instead of exiting immediately if that happens, and leaving the data that's already in the file unread, continue iterating until we get the next EOF, as we can be reasonably sure that that's the EOF the user meant to stop at, making sure to read all the data that has been written by the time StopAtEOF is called. - When a StopAtEOF() is called the code should continue to send all lines to the Lines channel. The issue here is if the caller is not ready to receive a new line the code blocks as it is using a unbuffered channel. However <-tail.Dying() would return in this case so the line was skipped. This means that the caller did not get all lines until EOF. Now we still want to skip in case any other reason for kill was given therefore add special logic to only not read the Dying channel on the EOF case. The one downside is that StopAtEOF() could block forever if the caller never reads new Lines but this seems logical to me. If the caller wants to wait for EOF but never reads remaining Lines this would be a bug on their end. Co-authored-by: Paul Holzinger <[email protected]>
tgummerer
added a commit
to pulumi/pulumi
that referenced
this pull request
Dec 16, 2024
This fixes a couple of race conditions in the tail library, combining the ideas of nxadm/tail#70 and nxadm/tail#71. - Currently when StopAtEOF is called, and we previously encountered an EOF already, we stop reading the file immediately. However when tailing a file, new data might have become available in the meantime, before the StopAtEOF is called. The watcher might however not have notified us about that yet. Instead of exiting immediately if that happens, and leaving the data that's already in the file unread, continue iterating until we get the next EOF, as we can be reasonably sure that that's the EOF the user meant to stop at, making sure to read all the data that has been written by the time StopAtEOF is called. - When a StopAtEOF() is called the code should continue to send all lines to the Lines channel. The issue here is if the caller is not ready to receive a new line the code blocks as it is using a unbuffered channel. However <-tail.Dying() would return in this case so the line was skipped. This means that the caller did not get all lines until EOF. Now we still want to skip in case any other reason for kill was given therefore add special logic to only not read the Dying channel on the EOF case. The one downside is that StopAtEOF() could block forever if the caller never reads new Lines but this seems logical to me. If the caller wants to wait for EOF but never reads remaining Lines this would be a bug on their end. Co-authored-by: Paul Holzinger <[email protected]>
github-merge-queue bot
pushed a commit
to pulumi/pulumi
that referenced
this pull request
Dec 16, 2024
Note: This PR is probably best read commit by commit. The nxadm/tail library we're using has a couple of race conditions, that may appear when using the automation API. This PR vendors parts of that library, and pulls in a couple of fixes from upstream (in particular nxadm/tail#70 and nxadm/tail#71) to address these race conditions. This also means we can get rid of the hacky workaround we have for these upstream issues. fixes #15235 --------- Co-authored-by: Paul Holzinger <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Currently when StopAtEOF is called, and we previously encountered an EOF already, we stop reading the file immediately. However when tailing a file, new data might have become available in the meantime, before the StopAtEOF is called. The watcher might however not have notified us about that yet.
Instead of exiting immediately if that happens, and leaving the data that's already in the file unread, continue iterating until we get the next EOF, as we can be reasonably sure that that's the EOF the user meant to stop at, making sure to read all the data that has been written by the time StopAtEOF is called.
Fixes #67