ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TCA - fireAndForget
    TCA 2022. 10. 27. 09:40

    안녕하세요. 입니다🍏

    이번 포스팅에서는 TCA의 fireAndForget에 대해 학습해보겠습니다🙌

     

    우선 fireAndForget이라는 용어가 생소할 수 있습니다!

    그냥 대충 추측을 해보면 "불지르고 잊어버리기"의 느낌으로 무언가 결과를 신경 쓰지 않을것 같은 느낌이 들어요.

    실제로 군사적인 용어에서는 Fire And Forget이라고 해서 3세대 미사일 유도 방식 중 하나라고 하네요.

    발사 버튼만 누르고 나면 사람이 더 이상은 미사일을 유도하거나 건드리지 않아도 된다는 뜻으로 자동으로 목표물을 찾아가 명중한데요🚀

    https://ko.wikipedia.org/wiki/파이어_앤_포겟

     

    파이어 앤 포겟 - 위키백과, 우리 모두의 백과사전

    위키백과, 우리 모두의 백과사전. 파이어 앤 포겟(영어: fire-and-forget)[1][2]은 3세대 미사일 유도 방식이다. 대전차 미사일[편집] 대전차 미사일의 1세대는 MCLOS(Manual Command to Line of Sight) 방식을 사용

    ko.wikipedia.org

    뭐 이쯤 생각해봤을때는 앞서 우리가 추측한게 맞아 보입니다.

    결국 미사일 발사 후 신경을 끄는것처럼 TCA에서도 무언가를 실행하고 신경끄는걸 뜻하겠네요!

     

    그럼 TCA에서 fireAndForget이 과연 3세대 미사일 유도 방식과 어떤 공통점이 있을지 보시죠🏃🏻

     

    fireAndForget 정의 및 구현

    fireAndForget은 TCA에서 데이터를 저장소 즉 Store에 다시 입력하지 않아도 되는 일부 작업을 실제 환경에서 실행하는 Effect를 만들어 줍니다.

    오류가 발생하더라도 Effect는 완료되고 오류는 무시됩니다.

    즉 이 기능은 다시 에러를 받아 처리할 필요가 없는 일부분의 비동기 작업을 수행하는데 유용하죠.

    자주 사용되는 예시는 GA나 Airbridge와 같은 분석툴을 이용해 현 사용자 액션 등을 분석 및 리포팅할때 자주 쓰입니다.

     

    fireAndForget은 아래 정의를 보면 아시겠지만 EffectPublisher의 static 메서드입니다.

    extension EffectPublisher where Failure == Never {
      public static func fireAndForget(
        priority: TaskPriority? = nil,
        _ work: @escaping @Sendable () async throws -> Void
      ) -> Self {
        Self.run(priority: priority) { _ in try? await work() }
      }
    }

    구현 아주 증말 간단해요..

    우선 EffectPublisher에 제네릭하게 들어오는 두녀석 Action과 Failure가 있죠.

    여기서 Failure의 타입이 Never여야 합니다.

    Never일때 이 fireAndForget을 사용할 수 있죠.

    만약 해당 Effect가 <Action, Error>일 경우 바로 사용할 수 없고 Error 타입을 Never로 변환해줘야합니다.

    저는 주로 이렇게 사용해요.

    case .buttonTapped:
      return env.analyticsService.logEvent
        .catchToEffect()
        .fireAndForget()

    logEvent는 Error 타입을 반환할 수 있기에 catchToEffect로 Error타입을 Never로 변환해줍니다.

    그 다음 fireAndForget을 사용하죠.

     

    말하다보니 다른길로 조금 들어온것 같은데 다시 원점으로 돌아와서 결국 Failure가 Never 타입일때 사용한다를 알아봤구요.

    구현을 보시면 그냥 run 즉 실행하는걸 볼 수 있습니다.

     

    즉 분석 리포팅을 하거나 어떠한 환경 변수를 조작할때 일단 Effect를 통해 무언가를 방출하여 실행합니다.

    그럼 이 실행이 정상적인지 에러를 방출하는지에 대해 기다리고 다른 처리를 확인할 필요가 없고 단순히 실행했으니 내 할일 끝!

    요렇게 가는겁니다.

     

    아래처럼 주로 사용되는 구현을 볼까요?

    case .buttonTapped:
      return .fireAndForget {
        try self.analytics.track("Button Tapped")
    }
    
    let counterReducer = AnyReducer<
      CounterState, CounterAction, CounterEnvironment
    > { state, action, environment in
        switch action {
        case .decrementButtonTapped:
          if state > 0 {
            state.count -= 0
            return .none
          } else {
            return environment.playAlertSound()
              .fireAndForget()
          }
      }
    }

    거의 동일한 두가지 케이스를 보시죠.

    위에 액션은 버튼이 탭되었을때 탭 되었다는 메시지를 담은 track이라는 분석 리포팅을 보내줍니다.

    리포팅하는 과정에서 어떤 에러가 나거나 하더라도 fireAndForget으로 run해줬으니 결과는 신경쓰지 않습니다.

    이미 보냈으니 비동기로 작업을 수행할것입니다.

     

    밑에 counterReducer쪽도 보시면 동일해요.

    감소 버튼을 눌렀을때 else문을 보면 결국 디바이스의 코어단을 건드려 경고음을 재생시킵니다.

    경고음을 재생시키는 Effect만 방출하고 이에 대한 후속 처리는 필요없기에 fireAndForget을 사용할 수 있습니다.

    그렇다면 경고음 재생시켜! 하는 Effect 발사 버튼을 누르게 되고 비동기로 알아서 실패하던 성공하던 처리될테니 사용자는 이에 영향을 받지 않고 다른 작업들을 마음껏 할 수 있습니다.

     

    마무리

    어떤가요? fireAndForget에 대해 감이 오시나요?!

    분명 Error를 처리하기 위해 필요한때에는 당연히 사용을 못하죠.

    그렇지만 그런 경우가 아니고 단순하게 분석 리포팅을 하거나 위의 일련의 예시들과 같은 상황에서는 fireAndForget으로 가볍게 구현하고 넘어갈 수 있습니다.

    이 경우에도 모두 일일히 Error를 catch하거나 하지 않아도 되죠.

    구분지어 조금 유용하게 사용하면 좋을 포인트입니다🙌

     

    [참고 자료]

    https://github.com/pointfreeco/swift-composable-architecture/blob/main/Sources/ComposableArchitecture/Effect.swift

     

    GitHub - pointfreeco/swift-composable-architecture: A library for building applications in a consistent and understandable way,

    A library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind. - GitHub - pointfreeco/swift-composable-architecture: A library for bu...

    github.com

    'TCA' 카테고리의 다른 글

    TCA - ReducerProtocol  (8) 2023.01.31
    TCA - Testing Effects (feat. unimplemented)  (0) 2022.10.31
    TCA - concatenate & merge (여러 Effect를 단일 Effect로 만들기)  (2) 2022.10.25
    TCA - Throttling  (2) 2022.10.20
    TCA - Debouncing  (0) 2022.10.17
Designed by Tistory.