Giter VIP home page Giter VIP logo

Comments (5)

luizmb avatar luizmb commented on May 21, 2024

I can have a look this weekend, I'm planning to continue working on the current changes I did and maybe we can have some unit tests to reproduce this problem you faced.
But I was a bit afraid that always doing this "dispatch_async" on main queue could bring some problems eventually. We should check if we're already in the Main Queue and, in that case, instead of dispatching async simply run the block immediately. However, there's a difference between Main Queue and Main Thread, that is very well explained in here: https://blog.krzyzanowskim.com/2016/06/03/queues-are-not-bound-to-any-specific-thread/

In my code I usually have this extension:

extension Thread {
    private static let dispatchSpecificKey = DispatchSpecificKey<UUID>()
    private static let dispatchSpecificValue = UUID()

    public static var isMainQueue: Bool {
        guard let queueUUID = DispatchQueue.getSpecific(key: Thread.dispatchSpecificKey),
            queueUUID == Thread.dispatchSpecificValue,
            Thread.isMainThread else { return false }

        return true
    }

    static func setMainQueueID() {
        DispatchQueue.main.setSpecific(key: Thread.dispatchSpecificKey, value: Thread.dispatchSpecificValue)
    }
}

Then I run Thread.setMainQueueID() in the AppDelegate to collect the queue id and then I can call:

if Thread.isMainQueue {
    doSomething()
} else {
    DispatchQueue.main.async {
        doSomething()
    }
}

I can try to do the same in the Store, but then the creating of the Store must be done in the Main Queue, so we collect the correct Queue ID, or can be dispatched only once if possible.

Can you please try that? Maybe you could open a PR in case this fixes for you and then maybe add some tests.

from swiftrex.

luizmb avatar luizmb commented on May 21, 2024

It's kinda similar to this approach here:
https://github.com/ReactiveX/RxSwift/blob/53cd723d40d05177e790c8c34c36cec7092a6106/Platform/DispatchQueue%2BExtensions.swift

from swiftrex.

luizmb avatar luizmb commented on May 21, 2024

I understand better now your problem, and indeed this behaviour is wrong and should be fixed, so when an event comes through the Store, its way from there to become handled by the reducer (considering that it was translated into an Action synchronously) should always happen in the very same loop of the same queue. So my proposed solution will very likely fix that and improve slightly the overall performance, although we hope no middleware will lock the main thread or whatever thread we choose this to happen, because it's gonna be a serial queue.

Ok, but what about the initial dispatch event? In your example you're dispatching two events in the same loop, one right after another. So the two events will arrive at the "same time" into the Store. If at this point the Store schedules async to the next runloop, the ViewController will finish the function immediately while the state is still outdated. If we also handle the event arrival using same strategy (immediate evaluation if in Main Queue), the ViewController will dispatch the first event, wait for the reducer and state update, then dispatch the second. Anyway they won't race with each other because the Queue is FIFO, but I wonder about the benefits of one or other model.

I currently tend to think that the event arrival should always DispatchQueue.main.async, while the other routings inside the Store should use the immediate evaluation strategy. But I'm open to suggestions.

I'll post the fix tomorrow in the master and write some new tests, release only in the 4th or 5th of October.

from swiftrex.

luizmb avatar luizmb commented on May 21, 2024

@AlexisQapa Hey! The develop branch should fix your problem now, I also included a test that's basically the sample code you sent. Can you please validate that this behaviour now fixes your problem?

from swiftrex.

luizmb avatar luizmb commented on May 21, 2024

Fixed in develop, however the solution won't be necessary anymore in the new (and hopefully final) design, available in this PR: #40

After unifying events and actions, and making the separation of view events and store actions not in the design but as a possibility thanks to the strongly-typed ActionType now, and also allowing lifting either Action or State for Middlewares, Reducers and also Stores (ViewStore is a proxied store limited to View Events and View State), the whole Queue-safety is much more clear. The only time we "bottleneck" actions is when they first enter the Store, coming from either Views or Middlewares. Once in the store, the action will travel through the Middleware pipeline, then through the Reducer pipeline in the very same runloop. That, of course, requires a correct implementation of Middlewares (never, I mean NEVER call next() async), which should not be a hard thing to do.

Anyway, this model should be much safer and easy to implement.

from swiftrex.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.