简体   繁体   中英

Using akka-http client `entity.discardEntityBytes` with strict Unmarshaller

the akka-http client documentation states the following:

Be sure to consume the response entities dataBytes:Source[ByteString,Unit] by for example connecting it to a Sink (for example response.discardEntityBytes() if you don't care about the response entity), since otherwise Akka HTTP (and the underlying Streams infrastructure) will understand the lack of entity consumption as a back-pressure signal and stop reading from the underlying TCP connection!

When using singleHttpRequest to get a Future[HttpResponse] , I am sometimes using an unmarshaller that was created using Unmarshaller.strict .

When using Unmarhsaller[HttpEntity, T] ,

Looking at the akka source code, it seems that after using marshallers obtained using Unmarshaller.strict , we should call discardEntityBytes , or make sure the unmarshaller calls that method, or consumes the bytes. When using Unmarshaller[HttpEntity, T] , we would need to make sure those bytes are consumed.

Is this a correct assumption?

Update:

This is the implementation of Unmarshaller.strict :

def strict[A, B](f: A ⇒ B): Unmarshaller[A, B] = Unmarshaller(_ => a ⇒ FastFuture.successful(f(a)))

Which calls Unmarshaller.apply , which ends up calling withMaterializer , which creates an anonymous Unmarshaller . See more on github . No where in this implementation does the unmarshaller consumes or verifies the consumption of bytes from the entity, or calls discardBytes .

Unmarshall with or without strict reads the response entity and gives you the option to convert the results into whatever case class you want. By doing so, you don't need to discardEntityBytes .

Akka-Http just like any other Akka based project, is stream based. Hence, it will need the a destination to its results, and otherwise, it will understand the lack of that destination as your client hasn't received the information requested and then it will apply back-pressure. From the docs:

since otherwise Akka HTTP (and the underlying Streams infrastructure) will understand the lack of entity consumption as a back-pressure signal and stop reading from the underlying TCP connection!

Whenever you are using Unmarshall, you are reading the Source bytes and the method discardEntityBytes is nothing more than a Sink like dev/null and you don't need to append it to your calls. Unless you actually don't care about the returned entity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM