2013-03-13 5 views
3

이 동작이 예상되는지 (예 : Reactive.Banana.Switch를 잘못 사용하고 있는지) 또는 버그인지 확실하지 않습니다.반응식 바나나의 동적 이벤트 전환으로 심각한 누출이 발생합니다.

두 가지 유형의 입력 동작이 있고이를 이벤트에 따라 전환하고 싶다고 가정 해 보겠습니다. 이 함수는 다음과 같이 작성했습니다 :

switchBehaviors :: 
     Behavior t a -- | Behavior to yield initially and after "True" events 
    -> Behavior t a -- | Behavior to yield after "False" events 
    -> Event t Bool -- | Select between behaviors 
    -> Moment t (Behavior t a) 
switchBehaviors t f es = do 
    t' <- trimB t 
    f' <- trimB f 
    return $ switchB t $ (\e -> if e then t' else f') <$> es 

이 코드는 충분하지 않습니다. 간단한 GUI 모형에 임베드 될 때 유형 검사, 컴파일 및 원하는 결과를 제공합니다. (동작에 대한 두 개의 텍스트 입력 필드, 대체 True 및 False 이벤트를 내보내는 버튼, sink을 사용하여 결합 된 동작에 바인딩 된 레이블)

그러나 이벤트를 여러 번 트리거 한 후 재난 어딘가에 누출. 앱은 입력 비헤이비어와 새로운 이벤트의 변경에 모두 반응하는 데 더 오래 걸리기 시작합니다. 그것은 또한 기억을 먹기 시작합니다.

여기에 -hC가있는 힙 프로파일이 있습니다. leaking memory 나는 반복적으로 이벤트를 토글합니다. 가장 큰 두 개의 스파이크는 이벤트의 20 번째 및 21 번째 발사 일 수 있습니다.

trimB를 사용하면 손을 흔들어서 유형을 추가하는 것처럼 느껴집니다. 나는 그것을 올바르게 사용하고 있는지 또는 어떻게 든 그것을 학대하는지 알지 못합니다.

내 하위 질문은 다음과 같습니다

1) 나는 Reactive.Banana.Switch API를 남용하고 있는가, 또는이 버그? API를 악용하는 경우 무엇이 잘못 되었나요?

2) 동적 이벤트 전환을 사용하지 않고이 작업을 수행해야합니까? apply을 사용하면 기본 동작이 변경 될 때 결과 이벤트가 실행되지 않기 때문에 올바른 동작을 제공하지 않습니다. 세 입력을 모두 이벤트에 적용하지 않으면 각 입력 이벤트의 가장 최근 값을 수동으로 누적하여 폴드를 설정할 수 있다고 생각합니다. 이것이 올바른 접근 방법입니까?

+0

반응식 바나나 버전 0.7은 동적 전환 이벤트에 대한 가비지 수집을 아직 구현하지 않으므로 매우 동적 인 모든 항목이 공간을 차지할 수 있습니다. 나는 그것에 대해 연구 중이다. :-) –

+0

@HeinrichApfelmus이 버그가 아직 존재합니까? 나는 동적 인 전환 (키 누름)과 함께 오늘 실험을 시도했다. 그리고 10-20 키 프레스 후에 나의 프로그램이 반응을 보이지 않게되었고 적어도 한 번 스택 오버플로로 인해 충돌했다. –

+1

@JasonDagit 개발 버전에서는이 문제를 일으킬 수있는 몇 가지 추가 공간 누수가 수정되었습니다. 그러나 동적 이벤트 전환을 위해 가비지 수집을 구현하는 일은 아직하지 않았습니다. –

답변

3

이 동작은 선택 입력에 Behavior을 사용하고 BehaviorApplicative의 인스턴스라는 것을 상기하는 경우 실제로 동적 스위칭없이 구현하는 것이 쉽습니다. .

switchBehaviors 
    :: Behavior t a -- | Behavior to yield when it's "True" 
    -> Behavior t a -- | Behavior to yield when it's "False" 
    -> Behavior t Bool -- | Select between behaviors 
    -> Behavior t a 
switchBehaviors t f es = 
    (\e x y -> if e then x else y) <$> es <*> t <*> f 
(하인리히 Apfelmus 코멘트에서 첫 번째 질문을 해결

그는 지적으로, Reactive.Banana.Switch :이 질문을 할 때 내가 정말 그렇게 여기 나 같은 다른 사람에 대한 명시 적 작업 아웃의의 f <$> x <*> y <*> z ... 관용구를 내면화하지 않았다 여전히 실험적이며 성능 특성이 개선되고 있습니다.)