Ошибка чтения Http в Akka, источник подпотока не может быть материализован более одного раза - PullRequest
1 голос
/ 02 августа 2020

Когда я пытаюсь использовать данные на сервере в памяти, а затем я хочу создать с ним строгий объект, но получаю сообщение об ошибке Substream Source cannot be materialized more than once. данные из запроса более одного раза (из прикладного уровня неизученного уровня библиотеки akka-http). Запросы выполняются с небольшим фрагментом данных, а с большим (около 10 КБ) фрагментом данных - с ошибкой.

Первая попытка:

 if (!entity.isChunked()) {
    entity.dataBytes.runFold(ByteString.empty)(_ ++ _).flatMap { encryptedBody =>
      decrypt(encryptedBody).map { decrypted =>
        HttpEntity(decrypted)
      }
    }
  }

также попробовал следующее (предложение в Akka http -ОШИБКА: Источник подпотока не может быть материализован более одного раза Если размер полезной нагрузки увеличился ), но не повезло

Вторая попытка (со строгим):

entity.toStrict(4.seconds).flatMap { strictEntity =>
  decrypt(strictEntity.data).map { decrypted =>
    HttpEntity(decrypted) 
  }
}

Версия AkkaHttp: 10.0.13 (Мы находимся в процессе перехода на последнюю версию, мы как бы застряли на более старой версии) Версия Akka: 2.4.20

Любая помощь будет отлично.

Трассировка стека:

[info] java.lang.IllegalStateException: Substream Source cannot be materialized more than once
[info]  at akka.stream.impl.fusing.SubSource$$anon$4.setCB(StreamOfStreams.scala:725)
[info]  at akka.stream.impl.fusing.SubSource$$anon$4.preStart(StreamOfStreams.scala:735)
[info]  at akka.stream.impl.fusing.GraphInterpreter.init(GraphInterpreter.scala:520)
[info]  at akka.stream.impl.fusing.GraphInterpreterShell.init(ActorGraphInterpreter.scala:380)
[info]  at akka.stream.impl.fusing.ActorGraphInterpreter.tryInit(ActorGraphInterpreter.scala:538)
[info]  at akka.stream.impl.fusing.ActorGraphInterpreter.preStart(ActorGraphInterpreter.scala:586)
[info]  at akka.actor.Actor$class.aroundPreStart(Actor.scala:510)
[info]  at akka.stream.impl.fusing.ActorGraphInterpreter.aroundPreStart(ActorGraphInterpreter.scala:529)
[info]  at akka.actor.ActorCell.create(ActorCell.scala:590)
[info]  at akka.actor.ActorCell.invokeAll$1_aroundBody2(ActorCell.scala:461)
[info]  at akka.actor.ActorCell$AjcClosure3.run(ActorCell.scala:1)
[info]  at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:149)
[info]  at akka.kamon.instrumentation.ActorSystemMessageInstrumentation$$anonfun$aroundSystemMessageInvoke$1.apply(ActorSystemMessageInstrumentation.scala:34)
[info]  at kamon.trace.Tracer$.withContext(TracerModule.scala:58)
[info]  at akka.kamon.instrumentation.ActorSystemMessageInstrumentation.aroundSystemMessageInvoke(ActorSystemMessageInstrumentation.scala:34)
[info]  at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:1)
[info]  at akka.actor.ActorCell.systemInvoke(ActorCell.scala:483)
[info]  at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:282)
[info]  at akka.dispatch.Mailbox.run(Mailbox.scala:223)
[info]  at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
[info]  at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
[info]  at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
[info]  at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
[info]  at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

1 Ответ

0 голосов
/ 19 августа 2020

Ошибка, потому что объект был прочитан более одного раза.

Вначале я не мог понять это, потому что чтение происходило во время проверки времени, и оно глубоко похоронено в валидациях. (одна из проверок зависит от содержимого тела)

Я пробовал строгое преобразование сущностей после проверок, так что это не сработало.

...