Thomvis/BrightFutures

Crash app when execute many times Future objects

oVuTrongThien opened this issue · 5 comments

I call executeNext() more than 500 times, app crash. I tested with physical device
This is my sample code. Please helps me!

class ViewController: UIViewController {
    enum TestError: Error {
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        executeAll(number: 0).onSuccess {
            print("success")
        }
    }

    private func executeAll(number: Int) -> Future<Void, TestError>{
        return executeNext(number: number)
    }

    private func executeNext(number: Int) -> Future<Void, TestError> {
        let promise = Promise<Void, TestError>()
        executeOne(number: number).onSuccess {
            if number == 1000 {
                promise.success({}())
            } else {
                promise.completeWith(self.executeNext(number: number + 1))
            }
        }
        return promise.future
    }

    private func executeOne(number: Int) -> Future<Void, TestError> {
        let promise = Promise<Void, TestError>()
        promise.success({}())
        return promise.future
    }
}

Thank you!

Simulator crash when number >= 20000

Thanks for the code. If it is reproductible I will look at (create a project and commit it on github could help to solve issue more rapidly)

If there is a crash you must have information to give, error code and message, thread dump etc...

Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffee7eeb298)

here in the code ?

extension Async: MutableAsyncType {
    @discardableResult
    func tryComplete(_ value: Value) -> Bool{
        return queue.sync {

on the queue "Internal Async Queue"

I make some monitoring by printing the current label queue before the queue.sync
I use 10000 as "number"

extension DispatchQueue {
    class var currentLabel: String {
        return String(validatingUTF8: __dispatch_queue_get_label(nil))!
    }
}

And main thread is used until 10002

0 com.apple.main-thread
1 com.apple.main-thread
2 com.apple.main-thread
3 com.apple.main-thread
4 com.apple.main-thread
5 com.apple.main-thread
6 com.apple.main-thread
...
9997 com.apple.main-thread
9998 com.apple.main-thread
9999 com.apple.main-thread
10000 com.apple.main-thread
10001 com.apple.main-thread
10002 Internal Async Queue
10003 Internal Async Queue
10004 Internal Async Queue
...
12135 Internal Async Queue
12136 Internal Async Queue

I have the issue with simulator between 2100 and 2200

Maybe a stack size issue, or reeentrance

Thanks for report @oVuTrongThien, thanks @phimage for looking into it. I think this is similar to a stack overflow for deep recursive code. Not much we can do about it, I think. What could work is scheduling some of the work in an asynchronous fashion.