Skip to content

in iOS, If I create multiple instances of Erik and each one loads a URL, it raises an ErikError.timeOutError #54

@limura

Description

@limura

Hello. Thanks for the great library.

It seems that if I create multiple instances of Erik and each one loads a URL, it raises an ErikError.timeOutError.
Running the following code on my iPad mini 4 raises an ErikError.timeOutError in most cases.

    let erikPool:[Erik] = [
        Erik(), Erik(), Erik(), Erik(), Erik(),
        Erik(), Erik(), Erik(), Erik(), Erik(),
    ]
    func testErik() {
        guard let url = URL(string: "https://www.google.com/") else { return }
        func startErik(id:String, url:URL, client:Erik) {
            client.visit(url: url) { (doc, err) in
                if let err = err {
                    print("Erik error.", err.localizedDescription)
                    return
                }
                if let firstLine = doc?.innerHTML?.trimmingCharacters(in: .whitespacesAndNewlines).components(separatedBy: "\n").first {
                    print(id, "request done.", firstLine)
                }else{
                    print(id, "request done. but no content?")
                }
            }
        }
        for (i, erik) in erikPool.enumerated() {
            startErik(id: String(format: "test #%d", i), url: url, client: erik)
        }
    }

Perhaps it's because the handleLoadRequestCompletion in Erik's WebKitLayoutEngine is busy looping, but it looks like the processing isn't up to speed.
As a workaround to this issue, I added Thread.sleep(forTimeInterval: 0.1) to Erik's source code as shown below, and found that each request completed successfully.

    fileprivate func handleLoadRequestCompletion(completionHandler: (Error?) -> Void) {
        // wait load finish
        let condition = pageLoadedPolicy.continueCondition
        let max = Date().timeIntervalSince1970 + pageLoadTimeout
        while(condition(self)) {
            if pageLoadTimeout > 0 && Date().timeIntervalSince1970 > max  {
                completionHandler(ErikError.timeOutError(time: pageLoadTimeout))
                return
            }
        #if os(OSX)
            RunLoop.current.run(mode: RunLoop.Mode.default, before: Date.distantFuture)
        #else
            Thread.sleep(forTimeInterval: 0.1)
        #endif
        }
        completionHandler(nil)
    }

I wasn't sure why I was using a loop to monitor this part of the code, so I decided to use the above workaround. However, you may be able to change this problem to something like a WKWebView.addObserver that monitors changes in "estimatedProgress" or "loading" without using a busy loop.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions