-
Notifications
You must be signed in to change notification settings - Fork 85
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
error channel is not consumed #116
Comments
Diagnosis: The stack path causing the issue in #71 comes down to the if !l.inPattern {
l.ErrorfAt(line, col, `invalid escape sequence: \`+string(c))
}
text = append(text, '\\') After this executes, the An elegant solution might be to start a goroutine to consume the channel prior to Item consumption occurs via calling The current control flow does not immediately lend itself to setting up a goroutine to consume the channel, but an elegant approach to that may appear given a little more consideration. The simple approach of exiting Given this issue has existed in the library since release, I'll keep working on a more elegant approach with a goroutine started by the call to |
You can put a select where the message is written and indicate a fatal error if the default case occurs (since it only happens after repeated failures). Just a thought.
…Sent from my iPad
On Apr 18, 2020, at 12:49 AM, Andrew Fort ***@***.***> wrote:
Diagnosis:
The stack path causing the issue in #71 comes down to the lexQString function's inner for {} loop, specifically this code.
if !l.inPattern {
l.ErrorfAt(line, col, `invalid escape sequence: \`+string(c))
}
text = append(text, '\\')
After this executes, the for loop continues, which due to there being no goroutine consuming the items channel, allows for the channel to fill up and the deadlock to occur.
An elegant solution might be to start a goroutine to consume the channel prior to lexQString ever being called.
Item consumption occurs via calling NextToken manually. This is presently called only from within (*parser).next(), itself only called from nextStatement which it called by itself recursively and ultimately from Parse.
The current control flow does not immediately lend itself to setting up a goroutine to consume the channel, but an elegant approach to that may appear given a little more consideration.
The simple approach of exiting NextToken as soon as any error is seen would work, but will make the parser strictly "first error" only, which is less than ideal considering multiple errors are supported today, including up to [size of items channel] consecutive errors between other tokens.
Given this issue has existed in the library since release, I'll keep working on a more elegant approach with a goroutine started by the call to Parse.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Thanks, that's a good idea to replace the deadlock with an explicit crash. I'll do that here. Do you think it's worth looking at cleaning this up? We have a channel (looks like it comes from Rob's lexer/parser example, a pattern I quite like..), plus a stack of items on the receiver side. Since the channel send and receive calls happen in the same stack (frame), we could eliminate the channel itself as there are no goroutines to co-ordinate. Or we could refactor the receiver to properly run in its own goroutine. |
An alternative that fixes #116. This is essentially what @pborman proposed in #117 (comment). I wasn't able to reproduce test failing as mentioned by @andaru in #117 (comment) in the current codebase, so pborman's suggestion now makes more sense. The reason seems to be that error tokens are always skipped, so they don't seem to affect `Location` as Andrew mentioned: https://github.com/openconfig/goyang/blob/1fb7893798e04830b4d7fbbcd6672b95668fcf73/pkg/yang/parse.go#L207-L214
An alternative that fixes #116. This is essentially what @pborman proposed in #117 (comment). I wasn't able to reproduce test failing as mentioned by @andaru in #117 (comment) in the current codebase, so pborman's suggestion now makes more sense. The reason seems to be that error tokens are always skipped, so they don't seem to affect `Location` as Andrew mentioned: https://github.com/openconfig/goyang/blob/1fb7893798e04830b4d7fbbcd6672b95668fcf73/pkg/yang/parse.go#L207-L214
Issue #71 identifies two problems. The first, as that issue describes, is related to escape character handling.
The second, shown in the error message provided in #71 is a deadlock, which occurs due to the lexer's
items
channel overflowing.This issue is opened to address that part of the problem.
At present, errors can be sent to the
items
channel an arbitrary number of times between each call to(*lexer).NextToken()
, which is the only place which receives from theitems
channel. Each call toNextToken
will remove at most one item. When multiple errors are detected (in issue #71) within the same comment, only a singleNextToken
call will occur, allowing theitems
channel to overflow in short order.The text was updated successfully, but these errors were encountered: