Vishal
Vishal

Reputation: 1492

Akka http -ERROR :Substream Source cannot be materialized more than once If Payload size increased

I am working with Akka Http, where I have defined a route as

val route = (path(HttpConstants.CreateJob) & post) {
    (entity(as[JobDetailsEntity]) & entity(as[JobEntity])) {
      (jobDetailsEntity: JobDetailsEntity, jobEntity: JobEntity) =>
        val updatedJobEntity = jobEntity.copy(runningSince = DateTime.now().getMillis)
        val updatedJobDetailsEntity = jobDetailsEntity.copy(runningSince = DateTime.now().getMillis).copy(modify_date = DateTime.now().getMillis)
        complete {
          createJobDetails(updatedJobDetailsEntity).map(_.asJson)
          createJob(updatedJobEntity).map(_.asJson)
        }
    }

Here I am trying to unmarshal two entites in the same POST call which works when my json Payload id small i.e few bytes then its works fine , as soon as the payload size increases i.e around 10-20 kb it throws error :

Substream Source cannot be materialized more than once

Upvotes: 2

Views: 5672

Answers (2)

gihanchanuka
gihanchanuka

Reputation: 5051

Note that some directives force an implicit toStrict operation, such as entity(as[String]) and similar ones.

Refer to AKKA docs: Server-Side handling of streaming HTTP Entities

Upvotes: 0

Michal Borowiecki
Michal Borowiecki

Reputation: 4334

Please see https://github.com/akka/akka-http/issues/745#issuecomment-271571342

In short, if you need to unmarshal your entity twice you should use the toStrict first to make sure the entire entity is buffered in memory, otherwise it will be drained by the first unmarshalling process and not available for the second.

Only accidentally it happens to work without toStrict if the entity is small enough that it fits in akka's internal buffer, then there's actually no draining involved.

Upvotes: 9

Related Questions