liveBook · Manning

Streaming

As explained in Go in Practice, Second Edition

An event stream is an ordered flow of discrete event records delivered continuously over time.

Streaming processes data as it arrives or in successive pieces instead of loading it all before doing any work. For an event stream, those pieces are discrete records: a log can contain one JSON record per line, and a network logging service can receive messages continuously. File copying and uploads also use streaming, though their pieces are bytes or multipart parts rather than necessarily events. section 7.1.1 section 7.2.1 section 10.2.6

Choose the unit of work to match the input. For a large newline-separated log, open the file and scan one line at a time, then decode each line as JSON. This avoids the memory cost of reading and splitting the whole file. Repeatedly appending tiny byte reads until they happen to form valid JSON is brittle, especially when input is malformed. section 7.1.1

Listing 7.4 Using bufio to read line by line
package main

import (
    "bufio"
    "encoding/json"
    "log"
    "os"
)

func main() {
    file, err := os.Open("structured.log")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    scan := bufio.NewScanner(file)        #1
    scan.Split(bufio.ScanLines)                 #2
    lineJSON := make(map[string]interface{})
    for scan.Scan() {                          #3
        if err := json.Unmarshal([]byte(scan.Text()), &lineJSON); err != n
        il {
            log.Println(err)
        } else {
            log.Println(lineJSON["level"])
        }
    }
}

The scanner supplies each log line to json.Unmarshal, so records can be handled without first loading the entire file. section 7.1.1

When both ends expose Go’s Reader and Writer interfaces, io.Copy moves data through a buffer without a hand-written read/write loop. For an upload, use Request.MultipartReader to receive parts while the request is in progress and save them toward their destination. Unlike ParseMultipartForm, this need not stage the whole upload in the API server’s temporary-file area—a useful distinction for large or concurrent uploads. section 7.1.2 section 10.2.6

Listing 7.6 Copying buffered data from Reader to Writer
package main

import (
    "io"
    "os"
)

func main() {
    src, err := os.Open("test.txt")      #1
    if err != nil {
        panic(err)
    }
    defer src.Close()

    dest, err := os.Create("test2.txt")
    if err != nil {
        panic(err)
    }
    defer dest.Close()

    _, err = io.Copy(dest, src)      #2
    if err != nil {
        panic(err)
    }

}

A source file and destination file are connected with io.Copy, illustrating buffered transfer through Reader and Writer interfaces. section 7.1.2

Streaming changes failure handling as well as resource use. Network log streams can lose messages when sending fails; channels and buffering can improve reliability. Writing a template directly to an HTTP response can deliver content sooner, but an execution error may leave users with a partial page. Buffer the rendered response first when detecting an error before display matters more than immediate output. section 7.2.1 section 9.1.4

How Go in Practice, Second Edition covers it

How deep it goes
Works through line scanning, buffered copying, and multipart reading; discusses network reliability and response-buffering trade-offs.
Examples
Uses newline-separated JSON logs, file-to-file copying, multipart file uploads, network log messages, and template responses.
What it assumes
Assumes basic Go file and HTTP handling while showing the standard-library calls for incremental reads and writes.
What you can do after
Build it from scratch with bufio.Scanner or MultipartReader, or apply it via io.Copy to move data incrementally.
How it connects
Links streaming to JSON logs, Reader and Writer interfaces, multipart uploads, network logging, and HTTP response buffering.

Also explained in

Compare how 19 books explain streaming →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Practice, Second Edition. The section links point to the parts of the book it draws on.