Skip to content

previous request are cancelled by the following request #36

@dqw18037

Description

@dqw18037

I'm using the RxFeedback in my project, and i got a problem that a processing network request will be cancelled by the follwing request.

To describe the question clearly, i made a demo here.

the UI is below, it's simple

screen shot 2018-08-05 at 6 06 32 pm

If 'request 1' button taped, a simulative request will be send, and delay to 2.0s, the button below will show 'response 1 received'.
and if 'request 2' button taped, 'response 2 received' will display the same way.

While, the problem is that if 'request 1' button taped, and before response 1 received, i taped the 'request 2' button, then the response 1 will never come back, it is cancelled.

And if i make debug here:
let event = just.delay(2.0) .debug(query.debugIdentifier, trimOutput: false)
i will got the following log:

---- request 1 ----
-> subscribed
---- request 2 ----
-> subscribed
---- request 1 ----
-> isDisposed
---- request 2 ----
-> Event next(response(RxFeedbackQueryTest.RequestType.second))
---- request 2 ----
-> Event completed
---- request 2 ----
-> isDisposed

we can see that request 1 was disposed once request 2 is subscribed

after reading the source codes of RxFeedback, i think, the codes leading the problem is below:

1

2

3

by using 'flatMapLatest' and 'switchLatest' operators, the previous sequence will be disposed,
why did you design to cancel the previous 'query' if a new 'query' comes?
can i just replace the 'flatMapLatest' with 'flatMap', and remove the operation 'takeUntilWithCompletedAsync'?

and how 'takeUntilWithCompletedAsync' can avoid the reentrancy issues?

The main code is below:
` private func setupBinding() {

    let UIBindings: (Driver<State>) -> Signal<Event> = bind(self) { me, state in
        let subscriptions = [
            state.map { $0.response1 }.drive(me.responseLabel1.rx.text),
            state.map { $0.response2 }.drive(me.responseLabel2.rx.text)
        ]
        
        let events: [Signal<Event>] = [
            me.requestButton1.rx.tap.map { Event.request(.first) }.asSignal(onErrorJustReturn: .none),
            me.requestButton2.rx.tap.map { Event.request(.second) }.asSignal(onErrorJustReturn: .none),
            me.clearButton.rx.tap.map { Event.clear }.asSignal(onErrorJustReturn: .none)
        ]
        return Bindings(subscriptions: subscriptions, events: events)
    }
    
    let nonUIBindings: (Driver<State>) -> Signal<Event> = react(query: { (state) -> Set<RequestType> in
        let querys = Set(state.requestsToSend.all())
        return querys
    }) { (query) -> Signal<Event> in
        let just = Signal.just(Event.response(query))
        let event = just.delay(2.0)
                     .debug(query.debugIdentifier, trimOutput: false)
        return event
    }
    
    Driver
        .system(initialState: State(),
                reduce: State.reduce,
                feedback: UIBindings, nonUIBindings)
        .drive()
        .disposed(by: bag)
}`

`enum Event {
case none
case request(RequestType)
case response(RequestType)
case clear
}

struct State: Mutable {

var requestsToSend = Requests()

var response1: String?
var response2: String?

static func reduce(state: State, event: Event) -> State {
    switch event {
    case .request(let req):
       return state.mutateOne {
            $0.requestsToSend.append(req)
        }
    case .response(let req):
        return state.mutateOne {
            switch req {
            case .first:
                $0.response1 = req.responseString
            case .second:
                $0.response2 = req.responseString
            }
        }
    case .clear:
        return state.mutateOne {
            $0.response1 = nil
            $0.response2 = nil
            _ = $0.requestsToSend.all()
        }
    default: return state
    }
}

}`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions