Record items drained from an async sequence and report the consumption state.

async sequence drain A coordination report can record how an async sequence was consumed. An `AsyncStream` yields a fixed run of values and then finishes, and a single `for await` loop drains it to completion, counting each value as it arrives. The whole drain is awaited inside one async function, so the counts are settled before they are reported. With no items the stream is empty, with a short run it is still draining, and with a full run every value is consumed. The status line summarizes the mode while the total confirms the drained values.

Async Sequence Coordination Report

items
async_sequence_coordination_report.swift
Replay: real traced execution (multi-file project)
func drain(_ n: Int) async -> (Int, Int) {
    let stream = AsyncStream<Int> { continuation in
        for i in 0..<n {
            continuation.yield(i + 1)
        }
        continuation.finish()
    }

    var drained = 0
    var total = 0
    for await value in stream {
        drained += 1
        total += value
    }
    return (drained, total)
}

let items = 1
let result = await drain(items)
let drained = result.0
let total = result.1

var status = "draining"
if drained == 0 {
    status = "empty"
}
if drained >= 4 {
    status = "full"
}

let line = "items=\(items) drained=\(drained) total=\(total) \(status)"

print(line)
func drain(_ n: Int) async -> (Int, Int) {
    let stream = AsyncStream<Int> { continuation in
        for i in 0..<n {
            continuation.yield(i + 1)
        }
        continuation.finish()
    }

    var drained = 0
    var total = 0
    for await value in stream {
        drained += 1
        total += value
    }
    return (drained, total)
}

let items = 0
let result = await drain(items)
let drained = result.0
let total = result.1

var status = "draining"
if drained == 0 {
    status = "empty"
}
if drained >= 4 {
    status = "full"
}

let line = "items=\(items) drained=\(drained) total=\(total) \(status)"

print(line)
func drain(_ n: Int) async -> (Int, Int) {
    let stream = AsyncStream<Int> { continuation in
        for i in 0..<n {
            continuation.yield(i + 1)
        }
        continuation.finish()
    }

    var drained = 0
    var total = 0
    for await value in stream {
        drained += 1
        total += value
    }
    return (drained, total)
}

let items = 4
let result = await drain(items)
let drained = result.0
let total = result.1

var status = "draining"
if drained == 0 {
    status = "empty"
}
if drained >= 4 {
    status = "full"
}

let line = "items=\(items) drained=\(drained) total=\(total) \(status)"

print(line)
  1. items ← 1

    18let items→ 1 = 1  //@items=0, 419let result = await drain(items1)20let drained = result.0
  2. stream ← AsyncStream<Int>(context: Swift.AsyncStream<Swift.Int>._Context)

    1func drain(_ n1: Int) async -> (Int, Int) {2    let stream→ AsyncStream<Int>(context: Swift.AsyncStream<Swift.Int>._Context) = AsyncStream<Int> { continuation in3        for i in 0..<n {4            continuation.yield(i + 1)5        }6        continuation.finish()7    }89    var drained→ 0 = 010    var total→ 0 = 011    for await value in stream {
  3. drained ← 1, total ← 1

    10var total = 011for await value1 in streamAsyncStream<Int>(context: Swift.AsyncStream<Swift.Int>._Context) {12    drained→ 1 += 113    total→ 1 += value114}
  4. return (drained, total)

    14    }15    return (drained1, total1)16}
  5. result ← (1, 1), drained ← 1, total ← 1, status ← draining, line ← items=1 drained=1 total=1 draining

    18let items = 1  //@items=0, 419let result→ (1, 1) = await drain(items1)20let drained→ 1 = result.0121let total→ 1 = result.112223var status→ draining = "draining"24if drained == 0 {25    status = "empty"26}27if drained >= 4 {28    status = "full"29}3031let line→ items=1 drained=1 total=1 draining = "items=\(items1) drained=\(drained1) total=\(total1) \(statusdraining)"3233print(lineitems=1 drained=1 total=1 draining)
    outputitems=1 drained=1 total=1 draining
  1. items ← 0

    18let items→ 0 = 019let result = await drain(items0)20let drained = result.0
  2. stream ← AsyncStream<Int>(context: Swift.AsyncStream<Swift.Int>._Context)

    1func drain(_ n0: Int) async -> (Int, Int) {2    let stream→ AsyncStream<Int>(context: Swift.AsyncStream<Swift.Int>._Context) = AsyncStream<Int> { continuation in3        for i in 0..<n {4            continuation.yield(i + 1)5        }6        continuation.finish()7    }89    var drained→ 0 = 010    var total→ 0 = 011    for await value in stream {12        drained += 113        total += value14    }15    return (drained0, total0)16}
  3. result ← (0, 0), drained ← 0, total ← 0, status ← draining

    18let items = 019let result→ (0, 0) = await drain(items0)20let drained→ 0 = result.0021let total→ 0 = result.102223var status→ draining = "draining"24if drained == 0 {
  4. if drained == 0

    23var status = "draining"24if drained0 == 0 {25    status = "empty"26}
  5. line ← items=0 drained=0 total=0 empty

    31let line→ items=0 drained=0 total=0 empty = "items=\(items0) drained=\(drained0) total=\(total0) \(statusempty)"3233print(lineitems=0 drained=0 total=0 empty)
    outputitems=0 drained=0 total=0 empty
  1. items ← 4

    18let items→ 4 = 419let result = await drain(items4)20let drained = result.0
  2. stream ← AsyncStream<Int>(context: Swift.AsyncStream<Swift.Int>._Context)

    1func drain(_ n4: Int) async -> (Int, Int) {2    let stream→ AsyncStream<Int>(context: Swift.AsyncStream<Swift.Int>._Context) = AsyncStream<Int> { continuation in3        for i in 0..<n {4            continuation.yield(i + 1)5        }6        continuation.finish()7    }89    var drained→ 0 = 010    var total→ 0 = 011    for await value in stream {
  3. drained ← 1, total ← 1

    pass 1 of 4
    10var total = 011for await value1 in streamAsyncStream<Int>(context: Swift.AsyncStream<Swift.Int>._Context) {12    drained→ 1 += 113    total→ 1 += value114}
    All 4 passes — pass 1 is the card above
    passvaluedrainedtotal
    110 10 1
    221 21 3
    332 33 6
    443 46 10
  4. return (drained, total)

    14    }15    return (drained4, total10)16}
  5. result ← (4, 10), drained ← 4, total ← 10, status ← draining

    18let items = 419let result→ (4, 10) = await drain(items4)20let drained→ 4 = result.0421let total→ 10 = result.1102223var status→ draining = "draining"24if drained == 0 {
  6. if drained >= 4

    26}27if drained4 >= 4 {28    status = "full"29}
  7. line ← items=4 drained=4 total=10 full

    31let line→ items=4 drained=4 total=10 full = "items=\(items4) drained=\(drained4) total=\(total10) \(statusfull)"3233print(lineitems=4 drained=4 total=10 full)
    outputitems=4 drained=4 total=10 full