Angular повторить, когда Scala процесс займет слишком много времени? - PullRequest
1 голос
/ 06 апреля 2020

У меня есть сервис angular:

getAll(): Observable<Role[]> {
    const queryUrl = `${this.baseUrl}/roles/getAll`;

    return this.http
      .get(queryUrl, this.httpOptions)
      .pipe(
        map((result: Role[]) => {
          return result;
        })
      );
  }

и API Scala как:

// Controller
def getAll() = Action.async { request =>
    println("IN CONTROLLER")
    rolesService.getAll().map {
      result => {
        println("IN CONTROLLER RESULT")
        addLog(request.cookies, Roles.GET_ALL)
        Ok(Json.toJson(result))
      }
    }.recover {
      case _ => {
        println("IN CONTROLLER RECOVER")
        InternalServerError
      }
    }
  }

// Service
def getAll(): Future[List[Role]] = {
    try {
      println("CALL GETALL ROLES IN SERVICE")
      val settingsFuture = rolesRepository.getAll
      settingsFuture
    }
    catch {
      case e: Exception => Future.failed(e)
    }
  }

// Repository
def getAll(): Future[List[Role]] = {
 // content

 // a test method
 val startDate = System.currentTimeMillis()
 val list = testMillion()
 val endDate  = System.currentTimeMillis()
 println(s"start date ${startDate}, endDate ${endDate}")
}

def testMillion(): List[(Int, String)] = {
    println("IN TEST MILLION METHOD")
    var roleList: List[(Int, String)] = List.empty
    for (i <- 0 to 100000) {
      if (i % 10000 == 0) {println(i)}
      val row: (Int, String) = (i, getName(i))
      roleList = roleList :+ row
    }
    roleList
}

def getName(i: Int): String = s"Role_${i}"

Я создал хранилище generi c и хотел его протестировать прежде чем применять его для всех моих лиц. Итак, поскольку сейчас я использую несколько итераторов, я хотел проверить, сколько времени занимает простая итерация от 0 до 1 миллиона элементов с двумя параметрами (Id и Name).

Во-первых, я протестировал с миллионом итераций, но мой p c не удался (мой процессор уходит на 100%, а память на ~ 80%). итак, опустился до ста тысяч и снова протестировал:

Шаги: Angular отправьте запрос на мой API. Контроллер -> Сервис -> Репозиторий -> Запуск итераций. Я печатал значение «i» через каждые 10 000 итераций, чтобы наблюдать за ходом процесса. Для каждых 10 КБ это занимало почти 10 секунд (на мой взгляд, это огромное время, если мы думаем, что это не запрос БД, просто прочитайте число и присвойте имя, которое рассчитывается как «Role_» + i).

Случайно, при 70k / 100k (примерно через 60 - 70 секунд после первого запроса клиента), СЮРПРИЗ получает другой запрос. Я думал, что метод testMillion () вызывается снова, потому что итерация не закончена, но нет. Второй запрос пришел от контроллера. В это время услуга Angular находится в состоянии ожидания. Хорошо, первая итерация завершена (первый запрос), это отправляет ответ клиентской стороне, но это не получено, потому что клиент уже ожидает второй запрос. Это происходит снова, второй запрос не завершен, и выполняется еще один запрос до четвертого. Но, поскольку соединение открывается более чем через 2 минуты, Angular выдает ошибку «ERR_CONNECTION_RESET» и запрос не выполняется.

Я знаю, что в Angular Rx js есть метод retry (), но по умолчанию я думаю, что это не называется. Я не уверен, что это ошибка клиента на 100% и повторная отправка запросов, если предыдущие занимают слишком много времени, но, как я понимаю, это мое первое мнение. Или эта проблема может быть из Scala, потому что используются фьючерсы?

Это всего лишь тест, у меня никогда не было ста тысяч ролей, но для другой сущности это может стать реальной проблемой. Спасибо

LE1: Если я установлю retry (0) в моем сервисе angular, запрос не будет выполнен через 60 секунд. Теперь, я уверен, что другой запрос сделан от клиента, если предыдущий занял слишком много времени. И почему изначально у меня было 4 запроса? потому что повтор вызывается 3 раза по умолчанию, не могу понять почему, потому что ( из определения повторения ):

Необязательно. По умолчанию -1.

Количество попыток повторения до сбоя.

getAll(): Observable<Role[]> {
        const queryUrl = `${this.baseUrl}/roles/getAll`;

        return this.http
          .get(queryUrl, this.httpOptions)
          .pipe(
            retry(0),
            map((result: Role[]) => {
              return result;
            })
          );
      }

Это раздражает. Чтобы установить для каждого метода обслуживания, который может занять слишком много времени, повторите попытку (0) или увеличьте время ожидания соединения с сервером (последнее, что я не знаю, является ли это хорошим решением).

LE2: По ответ на этот вопрос, я обнаружил, что повторная попытка вызывается, если превышено время ожидания. Но я не устанавливаю тайм-аут, и я знаю, что соединение между клиентом и API составляет около 120 секунд, поэтому этот случай не может быть возможным (я получаю сброс соединения после четвертой повторной попытки, а не тайм-аут соединения)

...