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

Replace NewScanner to NewReader to fix bug #8986 #8999

Merged
merged 12 commits into from
Oct 30, 2017

Conversation

lets00
Copy link
Contributor

@lets00 lets00 commented Oct 23, 2017

Replace NewScanner to NewReader to fix bug #8986

  • Rebased/mergable
  • Tests pass
  • CHANGELOG.md updated
  • Sign CLA (if not already signed)

Sorry, something went wrong.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
@ghost ghost added the proposed label Oct 23, 2017
Copy link
Contributor

@e-dard e-dard left a 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.
Copy link
Contributor

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 ?

if err := scanner.Err(); err != nil {
return fmt.Errorf("reading standard input: %s", err)
}
//if err := scanner.Err(); err != nil {
Copy link
Contributor

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.

for scanner.Scan() {
line := scanner.Text()
func (i *Importer) processDDL(scanner *bufio.Reader) {
for {
Copy link
Contributor

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
}

Copy link
Contributor

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().

if strings.HasPrefix(line, "# CONTEXT-DATABASE:") {
i.database = strings.TrimSpace(strings.Split(line, ":")[1])
for {
line, _, err := scanner.ReadLine()
Copy link
Contributor

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.

@lets00
Copy link
Contributor Author

lets00 commented Oct 24, 2017

I'm working on the proposed changes. Thank you for the feedback.

@e-dard
Copy link
Contributor

e-dard commented Oct 24, 2017

I can confirm @lets00 has signed the CLA.

Copy link
Contributor

@e-dard e-dard left a 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.

@@ -112,7 +112,10 @@ func (i *Importer) Import() error {
scanner := bufio.NewReader(r)

// Process the DDL
i.processDDL(scanner)
ddl_err := i.processDDL(scanner)
Copy link
Contributor

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 {

i.processDDL(scanner)
ddl_err := i.processDDL(scanner)
if ddl_err != nil {
return fmt.Errorf("reading standard input: %s", ddl_err)
Copy link
Contributor

Choose a reason for hiding this comment

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

err not ddl_err

//if err := scanner.Err(); err != nil {
// return fmt.Errorf("reading standard input: %s", err)
//}
dml_err := i.processDML(scanner)
Copy link
Contributor

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 {

//}
dml_err := i.processDML(scanner)
if dml_err != nil {
return fmt.Errorf("reading standard input: %s", dml_err)
Copy link
Contributor

Choose a reason for hiding this comment

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

err not ddl_err

//End of File
if err == io.EOF {
return nil
}
}
// Call batchWrite one last time to flush anything out in the batch
i.batchWrite()
Copy link
Contributor Author

@lets00 lets00 Oct 24, 2017

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

@ghost ghost assigned e-dard Oct 25, 2017
@ghost ghost added review and removed proposed labels Oct 25, 2017
@lets00
Copy link
Contributor Author

lets00 commented Oct 26, 2017

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.

Copy link
Contributor

@e-dard e-dard left a 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.

@e-dard
Copy link
Contributor

e-dard commented Oct 26, 2017

@lets00 no need for a new pull request, just push a commit up to this one 😄

@lets00
Copy link
Contributor Author

lets00 commented Oct 26, 2017

@e-dard I fix the problem putting if io.EOF... statement below the if err != nil ... statement in both the processDDL and processDML methods. I test in my environment, importing a monasca.dmp database and this solution works for me (not freeze like before).

Copy link
Contributor

@e-dard e-dard left a 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.

if strings.HasPrefix(line, "# CONTEXT-DATABASE:") {
i.database = strings.TrimSpace(strings.Split(line, ":")[1])
i.database = strings.TrimSpace(strings.Split(string(line), ":")[1])
Copy link
Contributor

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.

}
if strings.HasPrefix(line, "# CONTEXT-RETENTION-POLICY:") {
i.retentionPolicy = strings.TrimSpace(strings.Split(line, ":")[1])
i.retentionPolicy = strings.TrimSpace(strings.Split(string(line), ":")[1])
Copy link
Contributor

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.

line, err := scanner.ReadString(byte('\n'))
if err != nil && err != io.EOF {
return err
}
Copy link
Contributor

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 {.

line, err := scanner.ReadString(byte('\n'))
if err != nil && err != io.EOF {
return err
}
Copy link
Contributor

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 {.

@e-dard e-dard merged commit 905945e into influxdata:master Oct 30, 2017
@ghost ghost removed the review label Oct 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants