Share
Embed
Transcript
25 slides
-
"TZOD4USFBN w "TZOD4USFBN"TZOD4FRVFODFʹ४ڌ w ඇಉظΠςϨʔλΛखಈͰ࣮͢Δ͜ͱͳ͘ඇಉظγʔέϯεΛ࡞Ͱ͖Δ w DBMMCBDLEFMFHBUFϕʔεͷ"1*ΛBTZODBXBJUʹରԠͤ͞Δͷʹదͯ͠Δ w "TZOD4USFBN$POUJOVBUJPOΛड͚औΔΫϩʔδϟΛ༻ͯ͠ॳظԽ͢Δ w
$POUJOVBUJPOZJFME @ ϝιουΛݺͼग़ͯ͠ཁૉΛετϦʔϜʹ͢ w $POUJOVBUJPO fi OJTI Ͱऴྃ͢Δ -
let stream = AsyncStream<Int> { continuation in Task { var
count = 1 while !Task.isCancelled { continuation.yield(count) count += 1 try? await Task.sleep(for: .seconds(1)) } } } let taskA = Task { for await value in stream { print("Task A:", value) } } let taskB = Task { for await value in stream { print("Task B:", value) } } try? await Task.sleep(for: .seconds(3)) taskA.cancel() try? await Task.sleep(for: .seconds(3)) -
"TZOD4USFBNϒϩʔυΩϟετͰͳ͍ w ྫ͑$PNCJOFͷ1BTTUISPVHI4VCKFDUʮϒϩʔυΩϟετ͢Δʯͱઆ໌ ͞Ε͍ͯΔ ʮA subject that broadcasts elements to
downstream subscribers.ʯ w Ұํ"TZOD4USFBN"TZOD4FRVFODFΛ࡞͢Δܕͱͯ͠આ໌͞Ε͍ͯΔ ʮAn asynchronous sequence generated from a closure that calls a continuation to produce new elements.ʯ -
private var continuations: [UUID: AsyncStream<Int>.Continuation] = [:] func stream() ->
AsyncStream<Int> { let id = UUID() let (stream, continuation) = AsyncStream<Int>.makeStream( of: Int.self, bufferingPolicy: self.bufferingPolicy ) continuations[id] = continuation continuation.onTermination = { [weak self] _ in Task { await self?.removeContinuation(id) } } return stream } -
continuation.onTermination = { [weak self] _ in Task { await
self?.removeContinuation(id) } } private func removeContinuation(_ id: UUID) { continuations[id] = nil } -
private var task: Task<Void, Never>? func start() { task?.cancel() task
= Task { [weak self] in var count = 1 while !Task.isCancelled { await self?.yield(count) count += 1 try? await Task.sleep(for: .seconds(1)) } } } -
func yield(_ value: Int) { for continuation in continuations.values {
continuation.yield(value) } } func finish() { task?.cancel() task = nil for continuation in continuations.values { continuation.finish() } continuations.removeAll() } -
actor Broadcast { typealias BufferingPolicy = AsyncStream<Int>.Continuation .BufferingPolicy private var
continuations: [UUID: AsyncStream<Int>.Continuation] = [:] private let bufferingPolicy: BufferingPolicy private var task: Task<Void, Never>? init(bufferingPolicy: BufferingPolicy) { self.bufferingPolicy = bufferingPolicy } func stream() -> AsyncStream<Int> { let id = UUID() let (stream, continuation) = AsyncStream<Int>.makeStream( of: Int.self, bufferingPolicy: self.bufferingPolicy ) continuations[id] = continuation continuation.onTermination = { [weak self] _ in Task { await self?.removeContinuation(id) } } return stream } func start() { task?.cancel() task = Task { [weak self] in var count = 1 while !Task.isCancelled { await self?.yield(count) count += 1 try? await Task.sleep(for: .seconds(1)) } } } func yield(_ value: Int) { for continuation in continuations.values { continuation.yield(value) } } func finish() { task?.cancel() task = nil for continuation in continuations.values { continuation.finish() } continuations.removeAll() } private func removeContinuation(_ id: UUID) { continuations[id] = nil } } -
let broadcast = Broadcast(bufferingPolicy: .bufferingNewest(1)) let stream1 = await broadcast.stream()
let stream2 = await broadcast.stream() let taskA = Task { for await value in stream1 { print("Task A:", value) } } let taskB = Task { for await value in stream2 { print("Task B:", value) } } await broadcast.start() try? await Task.sleep(for: .seconds(3)) taskA.cancel() try? await Task.sleep(for: .seconds(3)) -
TXJGUBTZODBMHPSJUINT w όʔδϣϯ ͔Β4IBSFػೳ͕ಋೖ͞ΕͯϚϧνϒϩʔυΩϟ ετʹରԠͨ͠ w ߪಡͯ͠Δ5BTLΛΩϟϯηϧͯ͠ɺͷ"TZOD4USFBNʹΩϟϯηϧ͕ ͠ͳ͍ͨΊҙ w
ߪಡͯ͠Δ5BTL͕ͬͯΔͱDPOUJOVBUJPOPO5FSNJOBUJPOʹྲྀΕͯ͜ͳ͍ -
import AsyncAlgorithms let stream = AsyncStream<Int> { continuation in Task
{ var count = 1 while !Task.isCancelled { continuation.yield(count) count += 1 try? await Task.sleep(for: .seconds(1)) } } }.share() let taskA = Task { for await value in stream { print("Task A:", value) } } let taskB = Task { for await value in stream { print("Task B:", value) } } try? await Task.sleep(for: .seconds(3)) taskA.cancel() try? await Task.sleep(for: .seconds(3)) -
·ͱΊ w ߪಡऀ͝ͱʹ"TZOD4USFBNΛੜ͢Δ w ߪಡऀ͝ͱͷ"TZOD4USFBN$POUJOVBUJPOΛཧΛ͢Δ w J04ະຬͳΒ66*%Ͱཧ w J04Ҏ্ͳΒ4FUͰཧ w
ݩͷΠϕϯτιʔε͕ॏෳ͠ͳ͍Α͏ʹҙ w TXJGUBTZODBMHPSJUINTΛ͓͏