Skip to content

Commit

Permalink
[SCRUM-51] StreamListener 개선 (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jihyun247 authored Dec 27, 2024
1 parent 2db5d87 commit 052cc4c
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 53 deletions.
16 changes: 0 additions & 16 deletions Projects/Core/StreamListener/Interface/AnyStreamContinuation.swift

This file was deleted.

25 changes: 25 additions & 0 deletions Projects/Core/StreamListener/Interface/StreamContinuation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Foundation

public class StreamContinuation {
private let _yield: (any StreamType) -> Void
private let _finish: () -> Void

public init<T: StreamType>(_ continuation: AsyncStream<T>.Continuation) {
self._yield = { value in
guard let value = value as? T else { return }
continuation.yield(value)
}

self._finish = {
continuation.finish()
}
}

public func yield(_ value: any StreamType) {
_yield(value)
}

public func finish() {
_finish()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,19 @@ import Foundation
import Dependencies
import DependenciesMacros

// MARK: - Stream releated Protocol

public typealias StreamKey = String

public protocol StreamType: Hashable {
static var key: StreamKey { get }
}

// MARK: - StreamListener

public protocol StreamListenerProtocol {
func send<T: StreamTypeProtocol>(_ state: T) async
func receive<T: StreamTypeProtocol>(_ type: T.Type) -> AsyncStream<T>
func send<T: StreamType>(_ state: T) async
func receive<T: StreamType>(_ type: T.Type) -> AsyncStream<T>
}

@DependencyClient
Expand All @@ -30,8 +40,8 @@ extension StreamListener: TestDependencyKey {
}

private struct StreamListenerTestImpl: StreamListenerProtocol {
func send<T: StreamTypeProtocol>(_ state: T) async {}
func receive<T: StreamTypeProtocol>(_ type: T.Type) -> AsyncStream<T> { .never }
func send<T: StreamType>(_ state: T) async {}
func receive<T: StreamType>(_ type: T.Type) -> AsyncStream<T> { .never }
}

/*
Expand Down
21 changes: 0 additions & 21 deletions Projects/Core/StreamListener/Interface/Streams.swift

This file was deleted.

30 changes: 18 additions & 12 deletions Projects/Core/StreamListener/Sources/StreamListener.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ extension StreamListener: DependencyKey {
final class StreamListenerImpl: StreamListenerProtocol {
private let actor = StreamActor()

func send<T: StreamTypeProtocol>(_ state: T) async {
await actor.yield(type: T.key, value: T.self)
func send<T: StreamType>(_ state: T) async {
await actor.yield(key: T.key, value: state)
}

func receive<T: StreamTypeProtocol>(_ type: T.Type) -> AsyncStream<T> {
func receive<T: StreamType>(_ type: T.Type) -> AsyncStream<T> {
let (stream, continuation) = AsyncStream<T>.makeStream()
Task {
await actor.register(key: T.key, continuation: continuation)
Expand All @@ -36,18 +36,24 @@ final class StreamListenerImpl: StreamListenerProtocol {
}

private actor StreamActor {
private var streams: [StreamType: AnyStreamContinuation] = [:]

func register<T: StreamTypeProtocol>(key: StreamType, continuation: AsyncStream<T>.Continuation) {
streams[key] = AnyStreamContinuation(continuation)
private var streams: [StreamKey: [StreamContinuation]] = [:]

func register<T: StreamType>(key: StreamKey, continuation: AsyncStream<T>.Continuation) {
let newContinuation = StreamContinuation(continuation)
if streams[key] == nil {
streams[key] = [newContinuation]
} else {
streams[key]?.append(newContinuation)
}
}

func yield<T: StreamTypeProtocol>(type: StreamType, value: T.Type) {
guard let continuation = streams[type] else { return }
continuation.yield(value)
func yield<T: StreamType>(key: StreamKey, value: T) {
guard let continuations = streams[key] else { return }
continuations.forEach { $0.yield(value) }
}

func remove(type: StreamType) {
streams[type] = nil
func remove(key: StreamKey) {
streams[key]?.forEach { $0.finish() }
streams[key] = nil
}
}
22 changes: 22 additions & 0 deletions Projects/Domain/AppService/Sources/ServerStateStream.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// ServerStateStream.swift
// AppService
//
// Created by 김지현 on 12/25/24.
// Copyright © 2024 PomoNyang. All rights reserved.
//

import StreamListenerInterface

public enum ServerState: StreamType {
public static var key: StreamKey { "serverState" }
case requestStarted
case requestCompleted
case errorOccured
case networkDisabled
}

public struct RetryState: StreamType {
public static var key: StreamKey { "retryState" }
public var retry: Int?
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import DesignSystem
import UserServiceInterface
import DatabaseClientInterface
import StreamListenerInterface
import AppService

import ComposableArchitecture
import RiveRuntime
Expand Down

0 comments on commit 052cc4c

Please sign in to comment.