Hello
Is there way to trick marshallers to accept my Future[HttpResponse] in withFixedContentType ?
To provide large responses from cursor I'm trying to materialize class that extends Iterator. To do that we created SourceShape[ByteString] that wraps the iterator and corrseponding GraphStageWithMaterializedValue[SinkShape[ByteString], Future[MessageEntity]]
that pools first values from source and decides if HttpEntity.Strict or HttpEntity.Chunked should be creaded.
def httpResponse(iterator: Iterator[Data])(implicit ec: ExecutionContext) = {
Await.result(Source.fromGraph(sourceGrap(iterator)).runWith(entitySink).map(entity => HttpResponse(entity = entity)), 60 seconds)
}
val toResponseIteratorJsonMarshaller: ToResponseMarshaller[Iterator[Data]] =
Marshaller.withFixedContentType(`application/json`) {
result => httpResponse(result)
}
implicit val toResponseIteratorMarshaller: ToResponseMarshaller[Iterator[Data]] =
Marshaller.oneOf(
toResponseIteratorJsonMarshaller,
toResponseIteratorOdsMarshaller,
toResponseIteratorExcelMarshaller
)
As you can probably guess the biggest concern for me is unnecessary Await.result. One of the promising solutions was to drop await and to rewrite marshaller as:
def httpResponse(iterator: Iterator[Data])(implicit ec: ExecutionContext) = {
Source.fromGraph(sourceGrap(iterator)).runWith(entitySink).map(entity => HttpResponse(entity = entity))
}
val toResponseIteratorJsonMarshaller: ToResponseMarshaller[Iterator[Data]] = Marshaller{ implicit ec => result =>
httpResponse(result).map(response => Marshalling.WithFixedContentType(`application/json`, () => response ) :: Nil)
}
Unfortunately project structure is built that way that query is executed and cursor is opened when iterator hasNext or next methods are called. And in this solution it is done before content negotiation is done and causes multiple queries called for each response type at best or multiple queries on one connection at worst.
Thanks.
Muntis