Http-запрос не выполняется с кодом состояния ответа: 502 - PullRequest
0 голосов
/ 10 июля 2020

В al oop я получаю примерно 1000 запросов GET. Поскольку запросов слишком много, и шлюз не может их обработать, он выдает ошибку с кодом 502. Как лучше всего решить эту проблему. Мой код, как показано ниже.

 //In the array there are about 10000 ids 
 for id in Array {

  Network.shared.getData(accountId: id ?? "", successBlock: {(result) in

    //Save results to coredata

    }) {(errorCode:Int, error:String) in
        print(errorCode, error)
        
    }


 }

Моя одиночная сеть позже, я буду вызывать в приведенном выше методе, как показано ниже.

 class Network: NSObject {

 //These blocks catches success & failures
    typealias SuccessBlock = (Any) -> Void
    typealias FailureBlock = (_ errorCode: Int, _ error: String) -> Void
 

private static var networkCalls: Network?
private override init() {}

public static var shared: Network {

    if networkCalls == nil {
        networkCalls = Network()
    }
    return networkCalls!

 }

private lazy var configurationManager: URLSession = {
   let configuration = URLSessionConfiguration.default
    configuration.allowsExpensiveNetworkAccess = true
    configuration.allowsConstrainedNetworkAccess = true
    configuration.allowsCellularAccess = true
    configuration.timeoutIntervalForRequest = 60
    configuration.timeoutIntervalForResource = 60
    configuration.httpMaximumConnectionsPerHost = 2
    
    
    let manager = URLSession(configuration: configuration)
    return manager
   
}()

Внутри указанного выше класса я использую метод generi c для вызова HTTP-запроса (здесь я не показываю полный метод со всеми параметрами, но вы можете понять, как он выглядит)

   private func performWebServiceRequest(with url: URL, contentType: CONTENT_TYPE? = nil, requestOptions: [String: String]?,successBlock: @escaping SuccessBlock, failureBlock: @escaping FailureBlock) {

    let request = NSMutableURLRequest(url: url)
    request.httpMethod = requestType // As in "POST", "GET", "PUT" or "DELETE"
    request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData

  let task = configurationManager.dataTask(with: request as URLRequest) { (data, response, error) in
        guard let data: Data = data, let response: URLResponse = response, error == nil else 
    {return}

           do {
              let result = try JSONDecoder().decode(type, from: data)
                    successBlock(result)

            } catch {
                    failureBlock(0,errorMessage)
            }

  }

  task.resume()

 }

1 Ответ

0 голосов
/ 10 июля 2020

Вы можете использовать DispatchSemaphore, чтобы ограничить количество параллельно выполняемых задач, например:

var countedSemaphore = DispatchSemaphore(value:500)  // Allow 500 parallel network calls
var queue = DispatchQueue(label: "runner", qos: .background, attributes: .concurrent)

//In the array there are about 10000 ids
for id in Array {
    queue.async {  //(1)
        countedSemaphore.wait()  // (2)

        Network.shared.getData(accountId: id ?? "", successBlock: {(result) in
            countedSemaphore.signal() // (3a)

            //Save results to coredata

       }) {(errorCode:Int, error:String) in
           countedSemaphore.signal()  // (3b)
           print(errorCode, error)
       }
    }
}

В примере используется настраиваемая параллельная очередь (1) для создания задач, которые будут запускать загрузку по сети. В задаче мы сначала wait (2) для семафора. Этот вызов просто уменьшает счетчик семафора до тех пор, пока счетчик больше нуля. Если счетчик равен нулю, вызовы wait блокируются.

После возврата wait мы вызываем getData.

В обработчиках успеха (3a) и ошибки (3b), мы вызываем signal на семафоре, чтобы указать, что мы завершили сетевой вызов. signal увеличит счетчик или разбудит любой ожидающий вызов.

Эта конструкция гарантирует, что максимум 500 getData вызовов будут выполняться параллельно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...