Тонны HTTP-запросов Node.js приводят к тому, что компьютер не подключается к Интернету, пока я не перезапущу процесс - PullRequest
1 голос
/ 15 мая 2019

У меня есть этот основной код:

const cookie = require('cookie')
const https = require('https')
const http = require('http')

const proto = { https, http }

// Use connect method to connect to the server
MongoClient.connect(url, function(err, client) {
  console.log("Connected successfully to server")

  const db = client.db(dbName)
  const foos = db.collection('foos')
  perform(foos, function(){
    console.log('done')
  })
})

function perform(a, done) {
  const stream = a.find({ url: null })

  // emits each line as a buffer or as a string representing an array of fields
  stream.on('data', function(doc){
    stream.pause()

    request(doc.url, function(){
      stream.resume()
    })

    function request(url, fn, redirect, cookies) {
      cookies = cookies || {}
      console.log(redirect ? 'redirect' : 'start', url)
      const val = url.match(/^https/) ? 'https' : 'http'
      var headers = {}
      if (Object.keys(cookies).length) {
        var ck = []
        Object.keys(cookies).forEach(key => {
          ck.push(cookie.serialize(key, cookies[key]))
        })
        headers.Cookie = ck.join('; ')
      }

      proto[val].get(url, { headers }, function(response) {
        // console.log(response.headers)
        console.log(response.statusCode, url)
        if (response.statusCode == 302 || response.statusCode == 301 || response.statusCode == 307 || response.statusCode == 303) {
          if (response.headers['set-cookie']) {
            response.headers['set-cookie'].forEach(function(str){
              var cks = cookie.parse(str)
              for (var key in cks) {
                switch (key) {
                  case 'expires':
                  case 'path':
                  case 'domain':
                    break
                  default:
                    cookies[key] = cks[key]
                }
              }
            })
          }

          var newUrl = response.headers.location

          if (!newUrl.match(/^https?:\/\//)) {
            if (newUrl.match(/\/\//)) {
              newUrl = 'http:' + newUrl
            } else if (newUrl.match(/\//)) {
              newUrl = domain + newUrl
            } else {
              newUrl = domain + '/' + newUrl
            }
          }

          request(newUrl, fn, true, cookies)
        } else {
          // do something
          fn()
        }
      }).on('error', function(err) { // Handle errors
        console.log(err.message)
        fn()
      })
    }
  })

  // now pipe some data into it
  stream.on('end', function(){
    done()
  })
}

По сути, он просто загружает кучу URL-адресов из базы данных и выполняет вызов для каждого из них. Он использует функцию потоковой передачи коллекций MongoDB, поэтому выполняет только один запрос за раз, а когда запрос завершается, запускается следующий. Однако примерно через 3-5 минут запуска этого сценария процесс зависает. Не только это, браузер, который я использую, тоже зависает! Я запускаю его как скрипт Node.js, но по какой-то причине он блокирует весь трафик моего компьютера через 3-5 минут.

Дело в том, что когда я перезапускаю процесс (который занимает всего мгновение / секунду), все снова в порядке, и запросы проходят. Другой аспект, скажем, я пытаюсь перейти по URL-адресу в браузере (любой URL, например stackoverflow.com), и он зависает из-за сценария. Если я перезапущу процесс, окно браузера завершит свой запрос! Я понятия не имею, почему это так.

Интересно, знаете ли вы, почему это может происходить, и как я могу это исправить.

...