gorill

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Nov 13, 2015 License: MIT Imports: 7 Imported by: 0

README

gorill

Small Go library for various stream wrappers. A 'rill' is a small stream.

Usage

Documentation is available via GoDoc.

Description

One of the strengths of Go's interface system is that it allows easy composability of data types. An io.Writer is any data structure that exposes the Write([]byte) (int,error) method.

If a program has an io.Writer but requires one that buffers its output somewhat, the program could use the Go standard library bufio.Writer to wrap the original io.Writer, providing buffering on the data writes. That works great, but the programmer must be willing to allow the buffer to completely fill before flushing data to the final output stream. Instead, the program could use gorill.SpooledWriteCloser which buffers writes, but flushes data at a configurable periodicity.

Supported Use cases
NopWriteCloser

If a program has an io.Writer but requires an io.WriteCloser, the program can imbue the io.Writer with a no-op Close method. The resultant structure can be used anywhere an io.WriteCloser is required.

    iowc := gorill.NopCloseWriter(iow)
    iowc.Close() // does nothing

Alternatively, if you already have an io.WriteCloser, but you want its Close method to do nothing, then wrap it in a NopCloseWriter.

NopReadCloser

If a program has an io.Reader but requires an io.ReadCloser, the program can imbue the io.Reader with a no-op Close method. The resultant structure can be used anywhere an io.ReadCloser is required. The Go standard library provides this exact functionality by the ioutil.NopCloser(io.Reader) io.ReadCloser function. It is also provided by this library for symmetry with the gorill.NopCloseWriter call above.

    iorc := gorill.NopCloseReader(ior)
    iorc.Close() // does nothing

Alternatively, if you already have an io.ReadCloser, but you want its Close method to do nothing, then wrap it in a gorill.NopCloseReader.

SpooledWriteCloser

If a program has an io.WriteCloser but requires one that spools its data over perhaps a slow network connection, the program can use a gorill.SpooledWriteCloser to wrap the original io.WriteCloser, but ensure the data is flushed periodically.

    // uses gorill.DefaultFlushPeriod and gorill.DefaultBufSize
    spooler, err := gorill.NewSpooledWriteCloser(iowc)
    if err != nil {
        return err
    }

You can customize either or both the size of the underlying buffer, and the frequency of buffer flushes, based on your program's requirements. Simply list the required customizations after the underlying io.WriteCloser.

    spooler, err := gorill.NewSpooledWriteCloser(iowc, gorill.BufSize(8192), gorill.Flush(time.Second))
    if err != nil {
        return err
    }

If the program has an io.Writer but needs a spooled writer, it can compose data structures to achieve the required functionality:

    spooler, err := gorill.NewSpooledWriteCloser(gorill.NopCloseWriter(iow), gorill.Flush(time.Second))
    if err != nil {
        return err
    }
TimedReadCloser

If a program has an io.Reader but requires one that has a built in timeout for reads, one can wrap the original io.Reader, but modify the Read method to provide the required timeout handling. The new data structure can be used anywhere the original io.Reader was used, and seemlessly handles reads that take too long.

    timed := gorill.NewTimedReadCloser(iowc, 10*time.Second)
    buf := make([]byte, 1000)
    n, err := timed.Read(buf)
    if err != nil {
        if terr, ok := err.(gorill.ErrTimeout); ok {
            // timeout occurred
        }
        return err
    }
TimedWriteCloser

If a program has an io.Writer but requires one that has a built in timeout for writes, one can wrap the original io.Writer, but modify the Write method to provide the required timeout handling. The new data structure can be used anywhere the original io.Writer was used, and seemlessly handles writes that take too long.

    timed := gorill.NewTimedWriteCloser(iowc, 10*time.Second)
    n, err := timed.Write([]byte("example"))
    if err != nil {
        if terr, ok := err.(gorill.ErrTimeout); ok {
            // timeout occurred
        }
        return err
    }

LockingWriteCloser

If a program needs an io.WriteCloser that can be concurrently used by more than one go-routine, it can use a gorill.LockingWriteCloser. Benchmarks show a 3x performance gain by using sync.Mutex rather than channels for this case. gorill.LockingWriteCloser data structures provide this peformance benefit.

    lwc := gorill.NewLockingWriteCloser(os.Stdout)
    for i := 0; i < 1000; i++ {
        go func(iow io.Writer, i int) {
            for j := 0; j < 100; j++ {
                _, err := iow.Write([]byte("Hello, World, from %d!\n", i))
                if err != nil {
                    return
                }
            }
        }(lwc, i)
    }
MultiWriteCloserFanIn

If a program needs to be able to fan in writes from multiple io.WriteCloser instances to a single io.WriteCloser, the program can use a gorill.MultiWriteCloserFanIn.

    func Example(largeBuf []byte) {
        bb := gorill.NewNopCloseBuffer()
        first := gorill.NewMultiWriteCloserFanIn(bb)
        second := first.Add()
        first.Write(largeBuf)
        first.Close()
        second.Write(largeBuf)
        second.Close()
    }
MultiWriteCloserFanOut

If a program needs to be able to fan out writes to multiple io.WriteCloser instances, the program can use a gorill.MultiWriteCloserFanOut.

    bb1 = gorill.NewNopCloseBuffer()
    bb2 = gorill.NewNopCloseBuffer()
    mw = gorill.NewMultiWriteCloserFanOut(bb1, bb2)
    n, err := mw.Write([]byte("blob"))
    if want := 4; n != want {
        t.Errorf("Actual: %#v; Expected: %#v", n, want)
    }
    if err != nil {
        t.Errorf("Actual: %#v; Expected: %#v", err, nil)
    }
    if want := "blob"; bb1.String() != want {
        t.Errorf("Actual: %#v; Expected: %#v", bb1.String(), want)
    }
    if want := "blob"; bb2.String() != want {
        t.Errorf("Actual: %#v; Expected: %#v", bb2.String(), want)
    }
Supported Use cases for Testing
NopCloseBuffer

If a test needs a bytes.Buffer, but one that has a Close method, the test could simply wrap the bytes.Buffer structure with ioutil.NopClose(), but the resultant data structure would only provide an io.ReadCloser interface, and not all the other convenient bytes.Buffer methods. Instead the test could use gorill.NopCloseBuffer which simply imbues a no-op Close method to a bytes.Buffer instance:

    func TestSomething(t *testing.T) {
        bb := gorill.NopCloseBuffer()
        bb.Write([]byte("example"))
        bb.Close() // does nothing
    }

Custom buffer sizes can also be used:

    func TestSomething(t *testing.T) {
        bb := gorill.NopCloseBufferSize(16384)
        bb.Write([]byte("example"))
        bb.Close() // does nothing
    }
ShortWriter

If a test needs an io.Writer that simulates write errors, the test could wrap an existing io.Writer with a gorill.ShortWriter. Writes to the resultant io.Writer will work as before, unless the length of data to be written exceeds some preset limit. In this case, only the preset limit number of bytes will be written to the underlying io.Writer, but the write will return this limit and an io.ErrShortWrite error.

    func TestShortWrites(t *testing.T) {
        bb := gorill.NopCloseBuffer()
        sw := gorill.ShortWriter(bb, 16)

        n, err := sw.Write([]byte("short write"))
        // n == 11, err == nil

        n, err := sw.Write([]byte("a somewhat longer write"))
        // n == 16, err == io.ErrShortWrite
    }
SlowReader

If a test needs an io.Reader that writes all the data to the underlying io.Reader, but does so after a delay, the test could wrap an existing io.Reader with a gorill.SlowReader.

    bb := gorill.NopCloseBuffer()
    sr := gorill.SlowReader(bb, 10*time.Second)

    buf := make([]byte, 1000)
    n, err := sr.Read(buf) // this call takes at least 10 seconds to return
    // n == 7, err == nil
SlowWriter

If a test needs an io.Writer that writes all the data to the underlying io.Writer, but does so after a delay, the test could wrap an existing io.Writer with a gorill.SlowWriter.

    func TestSlowWrites(t *testing.T) {
        bb := gorill.NopCloseBuffer()
        sw := gorill.SlowWriter(bb, 10*time.Second)

        n, err := sw.Write([]byte("example")) // this call takes at least 10 seconds to return
        // n == 7, err == nil
    }

Documentation

Index

Constants

View Source
const DefaultBufSize = 4096

DefaultBufSize is the default size of the underlying bufio.Writer buffer.

View Source
const DefaultFlushPeriod = 15 * time.Second

DefaultFlushPeriod is the default frequency of buffer flushes.

Variables

This section is empty.

Functions

func NopCloseReader

func NopCloseReader(ior io.Reader) io.ReadCloser

NopCloseReader returns a structure that implements io.ReadCloser, but provides a no-op Close method. It is useful when you have an io.Reader that you must pass to a method that requires an io.ReadCloser. It is the same as ioutil.NopCloser, but for provided here for symmetry with NopCloseWriter.

iorc := gorill.NopCloseReader(ior)
iorc.Close() // does nothing

func NopCloseWriter

func NopCloseWriter(iow io.Writer) io.WriteCloser

NopCloseWriter returns a structure that implements io.WriteCloser, but provides a no-op Close method. It is useful when you have an io.Writer that you must pass to a method that requires an io.WriteCloser. It is the counter-part to ioutil.NopCloser, but for io.Writer.

iowc := gorill.NopCloseWriter(iow)
iowc.Close() // does nothing

func ShortWriteCloser

func ShortWriteCloser(iowc io.WriteCloser, max int) io.WriteCloser

ShortWriteCloser returns a structure that wraps an io.WriteCloser, but returns io.ErrShortWrite when the number of bytes to write exceeds a preset limit.

bb := gorill.NopCloseBuffer()
sw := gorill.ShortWriteCloser(bb, 16)

n, err := sw.Write([]byte("short write"))
// n == 11, err == nil

n, err := sw.Write([]byte("a somewhat longer write"))
// n == 16, err == io.ErrShortWrite

func ShortWriter

func ShortWriter(w io.Writer, max int) io.Writer

ShortWriter returns a structure that wraps an io.Writer, but returns io.ErrShortWrite when the number of bytes to write exceeds a preset limit.

bb := gorill.NopCloseBuffer()
sw := gorill.ShortWriter(bb, 16)

n, err := sw.Write([]byte("short write"))
// n == 11, err == nil

n, err := sw.Write([]byte("a somewhat longer write"))
// n == 16, err == io.ErrShortWrite

func SlowReader

func SlowReader(r io.Reader, d time.Duration) io.Reader

SlowReader returns a structure that wraps an io.Reader, but sleeps prior to writing data to the underlying io.Reader.

bb := gorill.NopCloseBuffer()
sr := gorill.SlowReader(bb, 10*time.Second)

buf := make([]byte, 1000)
n, err := sr.Read(buf) // this call takes at least 10 seconds to return
// n == 7, err == nil

func SlowWriter

func SlowWriter(w io.Writer, d time.Duration) io.Writer

SlowWriter returns a structure that wraps an io.Writer, but sleeps prior to writing data to the underlying io.Writer.

bb := gorill.NopCloseBuffer()
sw := gorill.SlowWriter(bb, 10*time.Second)

n, err := sw.Write([]byte("example")) // this call takes at least 10 seconds to return
// n == 7, err == nil

Types

type ErrList

type ErrList []error

ErrList is a slice of errors, useful when a function must return a single error, but has multiple independent errors to return.

func (*ErrList) Append

func (e *ErrList) Append(b error)

Append appends non-nil errors to the list of errors.

func (ErrList) Count

func (e ErrList) Count() int

Count returns number of non-nil errors accumulated in ErrList.

func (ErrList) Err

func (e ErrList) Err() error

Err returns either a list of non-nil error values, or a single error value if the list only contains one error.

func (ErrList) Error

func (e ErrList) Error() string

Error returns the string version of an error list, which is the list of errors, joined by a comma-space byte sequence.

type ErrReadAfterClose

type ErrReadAfterClose struct{}

ErrReadAfterClose is returned if a Read is attempted after Close called.

func (ErrReadAfterClose) Error

func (e ErrReadAfterClose) Error() string

Error returns a string representation of a ErrReadAfterClose error instance.

type ErrTimeout

type ErrTimeout time.Duration

ErrTimeout error is returned whenever a Write operation exceeds the preset timeout period. Even after a timeout takes place, the write may still independantly complete.

func (ErrTimeout) Error

func (e ErrTimeout) Error() string

Error returns a string representing the ErrTimeout.

type ErrWriteAfterClose

type ErrWriteAfterClose struct{}

ErrWriteAfterClose is returned if a Write is attempted after Close called.

func (ErrWriteAfterClose) Error

func (e ErrWriteAfterClose) Error() string

Error returns a string representation of a ErrWriteAfterClose error instance.

type LockingWriteCloser

type LockingWriteCloser struct {
	// contains filtered or unexported fields
}

LockingWriteCloser is an io.WriteCloser that allows only exclusive access to its Write and Close method.

func NewLockingWriteCloser

func NewLockingWriteCloser(iowc io.WriteCloser) *LockingWriteCloser

NewLockingWriteCloser returns a LockingWriteCloser, that allows only exclusive access to its Write and Close method.

lwc := gorill.NewLockingWriteCloser(os.Stdout)
for i := 0; i < 1000; i++ {
    go func(iow io.Writer, i int) {
        for j := 0; j < 100; j++ {
            _, err := iow.Write([]byte("Hello, World, from %d!\n", i))
            if err != nil {
                return
            }
        }
    }(lwc, i)
}

func (*LockingWriteCloser) Close

func (lwc *LockingWriteCloser) Close() error

Close closes the underlying io.WriteCloser.

func (*LockingWriteCloser) Write

func (lwc *LockingWriteCloser) Write(data []byte) (int, error)

Write writes data to the underlying io.WriteCloser.

type MultiWriteCloserFanIn

type MultiWriteCloserFanIn struct {
	// contains filtered or unexported fields
}

MultiWriteCloserFanIn is a structure that provides multiple io.WriteClosers to write to same underlying io.WriteCloser. When the final io.WriteCloser that MultiWriteCloserFanIn provides is closed, then the underlying io.WriteCloser will be closed.

func NewMultiWriteCloserFanIn

func NewMultiWriteCloserFanIn(iowc io.WriteCloser) *MultiWriteCloserFanIn

NewMultiWriteCloserFanIn creates a MultiWriteCloserFanIn instance where writes to any of the provided io.WriteCloser instances will be funneled to the underlying io.WriteCloser instance. The client ought to call Close on all provided io.WriteCloser instances, after which, MultiWriteCloserFanIn will close the underlying io.WriteCloser.

func Example(largeBuf []byte) {
	bb := NewNopCloseBufferSize(16384)
	first := NewMultiWriteCloserFanIn(bb)
	second := first.Add()
	first.Write(largeBuf)
	first.Close()
	second.Write(largeBuf)
	second.Close()
}

func (*MultiWriteCloserFanIn) Add

Add returns a new MultiWriteCloserFanIn that redirects all writes to the underlying io.WriteCloser. The client ought to call Close on the returned MultiWriteCloserFanIn to signify intent to no longer Write to the MultiWriteCloserFanIn.

func (*MultiWriteCloserFanIn) Close

func (fanin *MultiWriteCloserFanIn) Close() error

Close marks the MultiWriteCloserFanIn as finished. The last Close method invoked for a group of MultiWriteCloserFanIn instances will trigger a close of the underlying io.WriteCloser.

func (*MultiWriteCloserFanIn) Write

func (fanin *MultiWriteCloserFanIn) Write(data []byte) (int, error)

Write copies the entire data slice to the underlying io.WriteCloser, ensuring no other MultiWriteCloserFanIn can interrupt this one's writing.

type MultiWriteCloserFanOut

type MultiWriteCloserFanOut struct {
	// contains filtered or unexported fields
}

MultiWriteCloserFanOut is a structure that allows additions to and removals from the list of io.WriteCloser objects that will be written to.

func NewMultiWriteCloserFanOut

func NewMultiWriteCloserFanOut(writers ...io.WriteCloser) *MultiWriteCloserFanOut

NewMultiWriteCloserFanOut returns a MultiWriteCloserFanOut that is go-routine safe.

bb1 = gorill.NewNopCloseBuffer()
bb2 = gorill.NewNopCloseBuffer()
mw = gorill.NewMultiWriteCloserFanOut(bb1, bb2)
n, err := mw.Write([]byte("blob"))
if want := 4; n != want {
	t.Errorf("Actual: %#v; Expected: %#v", n, want)
}
if err != nil {
	t.Errorf("Actual: %#v; Expected: %#v", err, nil)
}
if want := "blob"; bb1.String() != want {
	t.Errorf("Actual: %#v; Expected: %#v", bb1.String(), want)
}
if want := "blob"; bb2.String() != want {
	t.Errorf("Actual: %#v; Expected: %#v", bb2.String(), want)
}

func (*MultiWriteCloserFanOut) Add

Add adds an io.WriteCloser to the list of writers to be written to whenever this MultiWriteCloserFanOut is written to. It returns the number of io.WriteCloser instances attached to the MultiWriteCloserFanOut instance.

bb1 = gorill.NewNopCloseBuffer()
mw = gorill.NewMultiWriteCloserFanOut(bb1)
bb2 = gorill.NewNopCloseBuffer()
mw.Add(bb2)

func (*MultiWriteCloserFanOut) Close

func (mwc *MultiWriteCloserFanOut) Close() error

Close will close the underlying io.WriteCloser, and releases resources.

func (*MultiWriteCloserFanOut) Count

func (mwc *MultiWriteCloserFanOut) Count() int

Count returns the number of io.WriteCloser instances attached to the MultiWriteCloserFanOut instance.

mw = gorill.NewMultiWriteCloserFanOut()
count := mw.Count() // returns 1
mw.Add(gorill.NewNopCloseBuffer())
count = mw.Count() // returns 2

func (*MultiWriteCloserFanOut) IsEmpty

func (mwc *MultiWriteCloserFanOut) IsEmpty() bool

IsEmpty returns true if and only if there are no writers in the list of writers to be written to.

mw = gorill.NewMultiWriteCloserFanOut()
mw.IsEmpty() // returns true
mw.Add(gorill.NewNopCloseBuffer())
mw.IsEmpty() // returns false

func (*MultiWriteCloserFanOut) Remove

func (mwc *MultiWriteCloserFanOut) Remove(w io.WriteCloser) int

Remove removes an io.WriteCloser from the list of writers to be written to whenever this MultiWriteCloserFanOut is written to. It returns the number of io.WriteCloser instances attached to the MultiWriteCloserFanOut instance.

bb1 = gorill.NewNopCloseBuffer()
bb2 = gorill.NewNopCloseBuffer()
mw = gorill.NewMultiWriteCloserFanOut(bb1, bb2)
remaining := mw.Remove(bb1) // returns 1

func (*MultiWriteCloserFanOut) Write

func (mwc *MultiWriteCloserFanOut) Write(data []byte) (int, error)

Write writes the data to all the writers in the MultiWriteCloserFanOut. It removes and invokes Close method for all io.WriteClosers that returns an error when written to.

bb1 = gorill.NewNopCloseBuffer()
bb2 = gorill.NewNopCloseBuffer()
mw = gorill.NewMultiWriteCloserFanOut(bb1, bb2)
n, err := mw.Write([]byte("blob"))
if want := 4; n != want {
	t.Errorf("Actual: %#v; Expected: %#v", n, want)
}
if err != nil {
	t.Errorf("Actual: %#v; Expected: %#v", err, nil)
}

type NopCloseBuffer

type NopCloseBuffer struct {
	*bytes.Buffer
	// contains filtered or unexported fields
}

NopCloseBuffer is a structure that wraps a buffer, but also provides a no-op Close method.

func NewNopCloseBuffer

func NewNopCloseBuffer() *NopCloseBuffer

NewNopCloseBuffer returns a structure that wraps bytes.Buffer with a no-op Close method. It can be used in tests that need a bytes.Buffer, but need to provide a Close method.

bb := gorill.NopCloseBuffer()
bb.Write([]byte("example"))
bb.Close() // does nothing

func NewNopCloseBufferSize

func NewNopCloseBufferSize(size int) *NopCloseBuffer

NewNopCloseBufferSize returns a structure that wraps bytes.Buffer with a no-op Close method, using a specified buffer size. It can be used in tests that need a bytes.Buffer, but need to provide a Close method.

bb := gorill.NopCloseBufferSize(8192)
bb.Write([]byte("example"))
bb.Close() // does nothing

func (*NopCloseBuffer) Close

func (m *NopCloseBuffer) Close() error

Close returns nil error.

func (*NopCloseBuffer) IsClosed

func (m *NopCloseBuffer) IsClosed() bool

IsClosed returns false, unless NopCloseBuffer's Close method has been invoked

type ShortReadWriteCloser

type ShortReadWriteCloser struct {
	io.Reader
	io.WriteCloser
	MaxRead  int
	MaxWrite int
}

ShortReadWriteCloser wraps a io.ReadWriteCloser, but the Read and Write operations cannot exceed the MaxRead and MaxWrite sizes.

func (ShortReadWriteCloser) Read

func (s ShortReadWriteCloser) Read(buf []byte) (int, error)

Read reads from the wrapped io.Reader, but returns EOF if attempts to read beyond the MaxRead.

func (ShortReadWriteCloser) Write

func (s ShortReadWriteCloser) Write(data []byte) (int, error)

Write writes from the wrapped io.Writer, but returns EOF if attempts to write beyond the MaxWrite.

type ShortReadWriter

type ShortReadWriter struct {
	io.Reader
	io.Writer
	MaxRead  int
	MaxWrite int
}

ShortReadWriter wraps a io.Reader and io.Writer, but the Read and Write operations cannot exceed the MaxRead and MaxWrite sizes.

func (ShortReadWriter) Read

func (s ShortReadWriter) Read(buf []byte) (int, error)

Read reads from the wrapped io.Reader, but returns EOF if attempts to read beyond the MaxRead.

func (ShortReadWriter) Write

func (s ShortReadWriter) Write(data []byte) (int, error)

Write writes from the wrapped io.Writer, but returns EOF if attempts to write beyond the MaxWrite.

type SpooledWriteCloser

type SpooledWriteCloser struct {
	// contains filtered or unexported fields
}

SpooledWriteCloser spools bytes written to it through a bufio.Writer, periodically flushing data written to underlying io.WriteCloser.

func NewSpooledWriteCloser

func NewSpooledWriteCloser(iowc io.WriteCloser, setters ...SpooledWriteCloserSetter) (*SpooledWriteCloser, error)

NewSpooledWriteCloser returns a SpooledWriteCloser that spools bytes written to it through a bufio.Writer, periodically forcing the bufio.Writer to flush its contents.

func (*SpooledWriteCloser) Close

func (w *SpooledWriteCloser) Close() error

Close frees resources when a SpooledWriteCloser is no longer needed.

func (*SpooledWriteCloser) Flush

func (w *SpooledWriteCloser) Flush() error

Flush causes all data not yet written to the output stream to be flushed.

func (*SpooledWriteCloser) Write

func (w *SpooledWriteCloser) Write(data []byte) (int, error)

Write spools a byte slice of data to be written to the SpooledWriteCloser.

type SpooledWriteCloserSetter

type SpooledWriteCloserSetter func(*SpooledWriteCloser) error

SpooledWriteCloserSetter is any function that modifies a SpooledWriteCloser being instantiated.

func BufSize

func BufSize(size int) SpooledWriteCloserSetter

BufSize is used to configure a new SpooledWriteCloser's buffer size.

func Flush

func Flush(periodicity time.Duration) SpooledWriteCloserSetter

Flush is used to configure a new SpooledWriteCloser to periodically flush.

type TimedReadCloser

type TimedReadCloser struct {
	// contains filtered or unexported fields
}

TimedReadCloser is an io.Reader that enforces a preset timeout period on every Read operation.

func NewTimedReadCloser

func NewTimedReadCloser(iowc io.ReadCloser, timeout time.Duration) *TimedReadCloser

NewTimedReadCloser returns a TimedReadCloser that enforces a preset timeout period on every Read operation. It panics when timeout is less than or equal to 0.

func (*TimedReadCloser) Close

func (rc *TimedReadCloser) Close() error

Close frees resources when a SpooledReadCloser is no longer needed.

func (*TimedReadCloser) Read

func (rc *TimedReadCloser) Read(data []byte) (int, error)

Read reads data to the underlying io.Reader, but returns ErrTimeout if the Read operation exceeds a preset timeout duration.

Even after a timeout takes place, the read may still independently complete as reads are queued from a different go-routine. Race condition for the data slice is prevented by reading into a temporary byte slice, and copying the results to the client's slice when the actual read returns.

type TimedWriteCloser

type TimedWriteCloser struct {
	// contains filtered or unexported fields
}

TimedWriteCloser is an io.Writer that enforces a preset timeout period on every Write operation.

func NewTimedWriteCloser

func NewTimedWriteCloser(iowc io.WriteCloser, timeout time.Duration) *TimedWriteCloser

NewTimedWriteCloser returns a TimedWriteCloser that enforces a preset timeout period on every Write operation. It panics when timeout is less than or equal to 0.

func (*TimedWriteCloser) Close

func (wc *TimedWriteCloser) Close() error

Close frees resources when a SpooledWriteCloser is no longer needed.

func (*TimedWriteCloser) Write

func (wc *TimedWriteCloser) Write(data []byte) (int, error)

Write writes data to the underlying io.Writer, but returns ErrTimeout if the Write operation exceeds a preset timeout duration. Even after a timeout takes place, the write may still independantly complete as writes are queued from a different go routine.

Jump to

Keyboard shortcuts

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