Skip to content

bufio: preemptive Flush() inside Write*() methods #20943

@gobwas

Description

@gobwas

Hello!

While digging the sources of bufio.Writer I had a question:
Inside Writer.ReadFrom() method exists a "preemptive" Flush(). I think this is made to deal with src.Read() deadlines in subsequent calls of ReadFrom – to not spent time on buffer flush before read attempt.

Could it be useful to make the same "preemptive" flushes inside other Writer.Write*() methods?

I mean that in current implementation test like this will fail:

type snoozeWriter struct {
	delay time.Duration
}

func (w snoozeWriter) Write(p []byte) (int, error) {
	time.Sleep(w.delay)
	return len(p), nil
}

type deadlineReader struct {
	deadline time.Time
}

func (r deadlineReader) Read(p []byte) (int, error) {
	if time.Since(r.deadline) > 0 {
		return 0, fmt.Errorf("deadline exceeded")
	}
	return len(p), io.EOF
}

func TestWriterReadFromTimeout(t *testing.T) {
	const size = 10

	bw := bufio.NewWriterSize(snoozeWriter{time.Second}, 10)

	// Fill buffer, without Flush().
	bw.WriteString("0123456789")

	// Emulate some reader with read deadline set.
	r := deadlineReader{time.Now().Add(500 * time.Millisecond)}

	if n, err := bw.ReadFrom(r); n != size || err != nil {
		t.Fatalf("ReadFrom() = (%v, %v); want (10, nil)", n, err)
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions