-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Replace NewScanner to NewReader to fix bug #8986 #8999
Conversation
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.
Thanks for the PR, we always appreciate community contributions. I have some suggested feedback. Let me know if you have any questions. Thanks.
CHANGELOG.md
Outdated
@@ -82,6 +82,7 @@ | |||
- [#8822](https://github.com/influxdata/influxdb/issues/8822): Fix data dropped incorrectly during compaction | |||
- [#8780](https://github.com/influxdata/influxdb/issues/8780): Prevent deadlock during collectd, graphite, opentsdb, and udp shutdown. | |||
- [#8983](https://github.com/influxdata/influxdb/issues/8983): Remove the pidfile after the server has exited. | |||
- [#8986](https://github.com/influxdata/influxdb/issues/8986): Replace NewScanner to NewReader in importer.go file. |
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.
How about Add long-line support to client importer
?
importer/v8/importer.go
Outdated
if err := scanner.Err(); err != nil { | ||
return fmt.Errorf("reading standard input: %s", err) | ||
} | ||
//if err := scanner.Err(); err != nil { |
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.
Please remove this commented out code.
importer/v8/importer.go
Outdated
for scanner.Scan() { | ||
line := scanner.Text() | ||
func (i *Importer) processDDL(scanner *bufio.Reader) { | ||
for { |
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.
There are a couple of issues here. (1) you could use ReadString(byte('\n'))
instead of ReadLine()
. That way you don't need to litter string(line)
everywhere. Also, I think ReadLine()
can return short reads, in that it might not return an entire line.
The second thing is you're not checking for errors that are not nil, but also not io.EOF
. Those errors would now need to be returned to the caller too.
How about we go with something like this?
func (i *Importer) processDDL(scanner *bufio.Reader) error {
for {
line, err := scanner.ReadString(byte('\n'))
if err != nil && err != io.EOF {
return err
}
// If we find the DML token, we are done with DDL
if strings.HasPrefix(line, "# DML") {
return nil
}
if strings.HasPrefix(line, "#") {
continue
}
// Skip blank lines
if strings.TrimSpace(line) == "" {
continue
}
i.queryExecutor(string(line))
// Check if this was the final token.
if err == io.EOF {
return nil
}
}
return nil
}
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.
Don't forget you'll need to add error handling to the call to processDDL()
inside of Import()
.
importer/v8/importer.go
Outdated
if strings.HasPrefix(line, "# CONTEXT-DATABASE:") { | ||
i.database = strings.TrimSpace(strings.Split(line, ":")[1]) | ||
for { | ||
line, _, err := scanner.ReadLine() |
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.
You should take a similar approach to the one I suggested previously in the review.
I'm working on the proposed changes. Thank you for the feedback. |
I can confirm @lets00 has signed the CLA. |
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.
Looking better but still a couple of style issues to fix.
importer/v8/importer.go
Outdated
@@ -112,7 +112,10 @@ func (i *Importer) Import() error { | |||
scanner := bufio.NewReader(r) | |||
|
|||
// Process the DDL | |||
i.processDDL(scanner) | |||
ddl_err := i.processDDL(scanner) |
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.
if err := i.processDDL(scanner); err != nil {
importer/v8/importer.go
Outdated
i.processDDL(scanner) | ||
ddl_err := i.processDDL(scanner) | ||
if ddl_err != nil { | ||
return fmt.Errorf("reading standard input: %s", ddl_err) |
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.
err
not ddl_err
importer/v8/importer.go
Outdated
//if err := scanner.Err(); err != nil { | ||
// return fmt.Errorf("reading standard input: %s", err) | ||
//} | ||
dml_err := i.processDML(scanner) |
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.
if err := i.processDML(scanner); err != nil {
importer/v8/importer.go
Outdated
//} | ||
dml_err := i.processDML(scanner) | ||
if dml_err != nil { | ||
return fmt.Errorf("reading standard input: %s", dml_err) |
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.
err
not ddl_err
importer/v8/importer.go
Outdated
//End of File | ||
if err == io.EOF { | ||
return nil | ||
} | ||
} | ||
// Call batchWrite one last time to flush anything out in the batch | ||
i.batchWrite() |
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.
Maybe put i.batchWrite() on if err ==io.EOF statement
I saw a infinite loop scenario when i.batchAccumulator() run after end of file. This not happen before(witch NewScanner), because the "for" statement not execute it. For fix this, I put io.EOF verification before i.batchAccumulator(). I will open a new pull request to fix this. Sorry about that. |
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.
Hi @lets00
When testing this I found that the import will never complete properly. Specifically the influx
process won't exit because the io.EOF
check will never be triggered.
I'm you test this locally you should find the same—all the data will be imported, but the process will hang.
To fix this you need to move the:
//End of File?
if err == io.EOF {
// Call batchWrite one last time to flush anything out in the batch
i.batchWrite()
return nil
}
blocks to be above the:
// Skip blank lines
if strings.TrimSpace(line) == "" {
continue
}
block in both the processDDL
and processDML
methods.
@lets00 no need for a new pull request, just push a commit up to this one 😄 |
@e-dard I fix the problem putting |
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.
Almost there @lets00, just a couple of further style suggestions.
importer/v8/importer.go
Outdated
if strings.HasPrefix(line, "# CONTEXT-DATABASE:") { | ||
i.database = strings.TrimSpace(strings.Split(line, ":")[1]) | ||
i.database = strings.TrimSpace(strings.Split(string(line), ":")[1]) |
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.
You don't need string(line)
since line
is already a string
.
importer/v8/importer.go
Outdated
} | ||
if strings.HasPrefix(line, "# CONTEXT-RETENTION-POLICY:") { | ||
i.retentionPolicy = strings.TrimSpace(strings.Split(line, ":")[1]) | ||
i.retentionPolicy = strings.TrimSpace(strings.Split(string(line), ":")[1]) |
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.
You don't need string(line)
since line
is already a string
.
importer/v8/importer.go
Outdated
line, err := scanner.ReadString(byte('\n')) | ||
if err != nil && err != io.EOF { | ||
return err | ||
} |
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.
This can be an } else if err == io.EOF {
.
importer/v8/importer.go
Outdated
line, err := scanner.ReadString(byte('\n')) | ||
if err != nil && err != io.EOF { | ||
return err | ||
} |
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.
This can be an } else if err == io.EOF {
.
Replace NewScanner to NewReader to fix bug #8986