contextio

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2022 License: Apache-2.0 Imports: 2 Imported by: 9

README

contextio - Context-aware I/O streams for Go

GoDoc codecov Travis-CI Go Report Card

Author: @dolmen (Olivier Mengué).

Example

go test -run ExampleWriter

func main() {
	// interrupt context after 500ms
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()
	// interrupt context with SIGTERM (CTRL+C)
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, os.Interrupt)
	go func() {
		<-sigs
		cancel()
	}()

	f, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	// Writer that fails when context is canceled
	out := contextio.NewWriter(ctx, f)

	// Infinite loop. Will only be interrupted once write fails.
	for {
		if _, err := out.Write([]byte{'a', 'b', 'c'}); err != nil {
			fmt.Println("Err:", err)
			break
		}
	}

	fmt.Println("Closing.")
}

See Also

Documentation

Overview

Package contextio provides io.Writer and io.Reader that stop accepting/providing data when an attached context is canceled.

Example (Copy)
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"os"
	"os/signal"
	"time"

	"github.com/dolmen-go/contextio"
)

func main() {
	// interrupt context after 500ms
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()
	// interrupt context with SIGTERM (CTRL+C)
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, os.Interrupt)
	go func() {
		<-sigs
		cancel()
	}()

	fIn, err := os.Open("/dev/zero")
	if err != nil {
		log.Fatal(err)
	}
	defer fIn.Close()

	fOut, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0)
	if err != nil {
		log.Fatal(err)
	}
	defer fOut.Close()

	// Reader that fails when context is canceled
	in := contextio.NewReader(ctx, fIn)
	// Writer that fails when context is canceled
	out := contextio.NewWriter(ctx, fOut)

	n, err := io.Copy(out, in)
	log.Println(n, "bytes copied.")
	if err != nil {
		fmt.Println("Err:", err)
	}

	fmt.Println("Closing.")

}
Output:

Err: context deadline exceeded
Closing.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewCloser

func NewCloser(ctx context.Context, c io.Closer) io.Closer

NewCloser wraps an io.Reader to handle context cancellation.

Context state is checked BEFORE any Close.

func NewReader

func NewReader(ctx context.Context, r io.Reader) io.Reader

NewReader wraps an io.Reader to handle context cancellation.

Context state is checked BEFORE every Read.

func NewWriter

func NewWriter(ctx context.Context, w io.Writer) io.Writer

NewWriter wraps an io.Writer to handle context cancellation.

Context state is checked BEFORE every Write.

The returned Writer also implements io.ReaderFrom to allow io.Copy to select the best strategy while still checking the context state before every chunk transfer.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
	"time"

	"github.com/dolmen-go/contextio"
)

func main() {
	// interrupt context after 500ms
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()
	// interrupt context with SIGTERM (CTRL+C)
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, os.Interrupt)
	go func() {
		<-sigs
		cancel()
	}()

	f, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	// Writer that fails when context is canceled
	out := contextio.NewWriter(ctx, f)

	// Infinite loop. Will only be interrupted once write fails.
	for {
		if _, err := out.Write([]byte{'a', 'b', 'c'}); err != nil {
			fmt.Println("Err:", err)
			break
		}
	}

	fmt.Println("Closing.")

}
Output:

Err: context deadline exceeded
Closing.

Types

This section is empty.

Jump to

Keyboard shortcuts

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