readwhilewrite

package module
v0.0.0-...-68a26aa Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 31, 2019 License: MIT Imports: 6 Imported by: 0

README

readwhilewrite GoDoc

readwhilewrite is a Go package which provides a reader and a writer which is used to read a file while the writer is writing to the same file.

Documentation

Overview

Package readwhilewrite provides a reader and a writer which is used to read a file while the writer is writing to the same file.

When readers get an EOF they waits further writes by the writer. The writer notify readers when it writes data.

Example
package main

import (
	"io"
	"io/ioutil"
	"log"
	"os"
	"time"

	"github.com/hnakamur/readwhilewrite"
)

func main() {
	file, err := ioutil.TempFile("", "test")
	if err != nil {
		log.Fatal(err)
	}
	defer os.Remove(file.Name())

	w := readwhilewrite.NewWriter(file)

	done := make(chan struct{})

	go func() {
		defer close(done)

		err := func() error {
			f, err := os.Open(file.Name())
			if err != nil {
				return err
			}
			r := readwhilewrite.NewReader(f, w)
			defer r.Close()
			var buf [4096]byte
			for {
				n, err := r.Read(buf[:])
				if err == io.EOF {
					break
				}
				if err != nil {
					return err
				}
				if n > 0 {
					os.Stdout.Write(buf[:n])
				}
			}
			return nil
		}()
		if err != nil {
			log.Fatalf("Unexpected reader error=%v", err)
		}
	}()

	err = func() error {
		_, err := w.Write([]byte("hello\n"))
		if err != nil {
			return err
		}

		time.Sleep(time.Second)
		_, err = w.Write([]byte("world\n"))
		if err != nil {
			return err
		}

		time.Sleep(time.Second)
		_, err = w.Write([]byte("goodbye\n"))
		if err != nil {
			return err
		}

		time.Sleep(time.Second)
		_, err = w.Write([]byte("see you\n"))
		if err != nil {
			return err
		}

		return nil
	}()
	if err != nil {
		// You should log the error in production here.

		w.Abort()
	}
	w.Close()

	<-done

}
Output:

hello
world
goodbye
see you

Index

Examples

Constants

This section is empty.

Variables

View Source
var WriteAborted = errors.New("write aborted")

WriteAborted is an error which is returned to Read of readers when Abort and then Close is called for a writer.

Functions

func SendFileHTTP

func SendFileHTTP(ctx context.Context, w http.ResponseWriter, file *os.File, fw *Writer) (n int64, err error)

SendFileHTTP serves a file as a HTTP response while fw is writing to the same file.

Once it gets an EOF, it waits more writes by the writer. If the ctx is done while waiting, SendFileHTTP returns. Typically you want to pass r.Context() as ctx for r *http.Request.

If you set the Content-Length header before calling SendFileHTTP, the sendfile system call is used on Linux.

Types

type Reader

type Reader struct {
	io.ReadCloser
	// contains filtered or unexported fields
}

Reader is a reader which waits writes by the writer when the reader gets an EOF. When the reader gets an EOF after Close is called for the writer, then it is treated as a real EOF.

func NewReader

func NewReader(r io.ReadCloser, w *Writer) *Reader

NewReader creates a new reader which waits writes by the writer.

func (*Reader) Close

func (r *Reader) Close() error

Close implements the io.Closer interface.

Close closes the underlying reader.

func (*Reader) Read

func (r *Reader) Read(p []byte) (n int, err error)

Read implements the io.Reader interface.

When Abort and then Close is called for the writer, WriteAborted is returned as err.

When SetWaitContext was called before calling Read and the context is done during waiting writes by the writer, the error from the context is returned as err.

func (*Reader) SetWaitContext

func (r *Reader) SetWaitContext(ctx context.Context)

SetWaitContext sets the context for waiting writes by the writer after the reader received a temporary EOF in Read.

Note SetWaitContext does not set a deadline for Read of the underlying reader. If you want to set a deadline, you need to call an appropriate method for the underlying reader yourself, for example SetReadDeadline of *os.File.

Also note SetReadDeadline of *os.File is not supported for ordinal files on most systems. See document of SetDeadline of *os.File.

type Writer

type Writer struct {
	io.WriteCloser
	// contains filtered or unexported fields
}

Writer is a writer which notifies readers of writes.

func NewWriter

func NewWriter(w io.WriteCloser) *Writer

NewWriter creates a notifying writer.

func (*Writer) Abort

func (w *Writer) Abort()

Abort is used to make readers stop reading when some error happens in the Writer. You must call Close after Abort.

func (*Writer) Close

func (w *Writer) Close() error

Close closes the underlying writer. When readers got EOF after Close is called, it is the real EOF.

func (*Writer) Write

func (w *Writer) Write(p []byte) (n int, err error)

Write implements the io.Writer interface. Write notify readers if n > 0.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL