"Promise already completed" exception with GridFS

107 views
Skip to first unread message

Szabo Akos

unread,
Apr 29, 2017, 7:20:08 PM4/29/17
to ReactiveMongo - http://reactivemongo.org
Hi!

I've the following problem: when I upgrade my application from ReactiveMongo 0.12.0 to 0.12.1 or 0.12.2 I get the following exception when serving files from GridFS:

java.lang.IllegalStateException: Promise already completed.
at scala.concurrent.Promise$class.complete(Promise.scala:55)
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:157)

I read the files this way:
  def find(fileId: UUID): Future[Option[FileData]] = {
    gridFS.find[JsObject, JSONReadFile](Json.obj("_id" -> fileId))
      .headOption.map(_.map(r => FileData(FileMetadata(r.id.as[UUID], r.filename.get, r.contentType, r.uploadDate.map(new DateTime(_))), gridFS.enumerate(r))))
  }

And I convert the Enumerator to Stream in order to stream it to the client in HTTP response:
val fileData = Source.fromPublisher(Streams.enumeratorToPublisher(f.content)).map(ByteString(_))

And this conversion leads to the problem. If I replace this conversion to the following, then the problem does not occur:
val content = f.content.run(Iteratee.consume[Array[Byte]]())
val fileData = Source.fromFuture(content).map(ByteString(_))

I guess this is a kind of hack, so it would be fine to solve it with standard streaming. Or am I doing something wrong?

Thanks,
Akos

Cédric Chantepie

unread,
Apr 30, 2017, 7:51:02 AM4/30/17
to ReactiveMongo - http://reactivemongo.org
Please paste the complete stack trace.

Cédric Chantepie

unread,
May 1, 2017, 7:42:55 AM5/1/17
to ReactiveMongo - http://reactivemongo.org
Also, the code from the provided MongoController doesn't raise such issue (see demo app).

Szabó Ákos

unread,
May 2, 2017, 3:43:28 AM5/2/17
to reacti...@googlegroups.com
Hi!

The complete stack trace is the following:
[error] 2017-05-02 08:40:07,499 a.d.Dispatcher - Promise already completed.

java.lang.IllegalStateException: Promise already completed.
    at scala.concurrent.Promise$class.complete(Promise.scala:55)
    at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:157)
    at scala.concurrent.Promise$class.failure(Promise.scala:104)
    at scala.concurrent.impl.Promise$DefaultPromise.failure(Promise.scala:157)
    at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:257)
    at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:251)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:36)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch$$anonfun$run$1.apply$mcV$sp(BatchingExecutor.scala:91)
    at akka.dispatch.BatchingExecutor$BlockableBatch$$anonfun$run$1.apply(BatchingExecutor.scala:91)

The MongoController based solution may be working (although I'm doing very similar things in my code), but I need to handle the "NotModified" HTTP response for the sake of efficiency.

Thanks,
Akos


2017. 04. 30. 13:51 keltezéssel, Cédric Chantepie írta:

Cédric Chantepie

unread,
May 2, 2017, 8:35:41 AM5/2/17
to ReactiveMongo - http://reactivemongo.org
I don't see reason not to used the MongoController, or at least to have a look at its code which seems ok for me.
Reply all
Reply to author
Forward
0 new messages