Giter VIP home page Giter VIP logo

play-iteratees's Introduction

End of Life

The active Playframework contributors consider this repository has reached End of Life and archived it.

This repository is not being used anymore and won't get any further updates.

Thank you to all contributors that worked on this repository!

Play Iteratees Library

This is the Play iteratees library. It has two modules, play-iteratees, which provides the iteratees themselves, as well as play-iteratees-reactive-streams, which provides a reactive streams implementation on top of iteratees.

Library Dependencies

To add play-iteratees to your project:

libraryDependencies += "com.typesafe.play" %% "play-iteratees" % "2.6.1"

To add play-iteratees reactive streams to your project:

libraryDependencies += "com.typesafe.play" %% "play-iteratees-reactive-streams" % "2.6.1"

Documentation

The Play Iteratees implementation is described in the Play 2.5.x documentation on Iteratees. If you are looking to migrate from iteratees to streams, the migration guide has a section:

If you are using Play 2.6.x or higher and are looking for Streams class, you can find it under:

play-iteratees's People

Contributors

cchantep avatar dwijnand avatar ennru avatar gmethvin avatar jroper avatar marcospereira avatar masahitojp avatar wsargent avatar xuwei-k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

play-iteratees's Issues

java.lang.NoClassDefFoundError: play/api/libs/streams/impl/EnumeratorSubscription

I'm getting the following error:

at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:251)
at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:251)
java.lang.NoClassDefFoundError: play/api/libs/streams/impl/EnumeratorSubscription
java.lang.NoClassDefFoundError: play/api/libs/streams/impl/EnumeratorSubscription
at play.api.libs.streams.impl.EnumeratorSubscriptionFactory$class.createSubscription(EnumeratorPublisher.scala:25)
Uncaught error from thread [application-akka.actor.default-dispatcher-1982] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[application]
at play.api.libs.streams.impl.EnumeratorPublisher.createSubscription(EnumeratorPublisher.scala:33)
at play.api.libs.streams.impl.EnumeratorPublisher.createSubscription(EnumeratorPublisher.scala:33)
at akka.stream.impl.MaterializerSession.akka$stream$impl$MaterializerSession$$doSubscribe(StreamLayout.scala:998)
at akka.stream.impl.MaterializerSession.assignPort(StreamLayout.scala:990)
at akka.stream.impl.MaterializerSession$$anonfun$exitScope$2.apply(StreamLayout.scala:872)
at akka.stream.impl.MaterializerSession$$anonfun$exitScope$2.apply(StreamLayout.scala:871)
at scala.collection.Iterator$class.foreach(Iterator.scala:891)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1334)
at akka.stream.impl.MaterializerSession.exitScope(StreamLayout.scala:871)
akka.stream.impl.MaterializerSession$$anonfun$materializeModule$1.apply(StreamLayout.scala:923)
akka.stream.impl.MaterializerSession$$anonfun$materializeModule$1.apply(StreamLayout.scala:915)
at scala.collection.immutable.Set$Set3.foreach(Set.scala:163)
at akka.stream.impl.MaterializerSession.materializeModule(StreamLayout.scala:915)
at akka.stream.impl.MaterializerSession.materialize(StreamLayout.scala:882)
at akka.stream.impl.ActorMaterializerImpl.materialize(ActorMaterializerImpl.scala:240)
at akka.stream.impl.ActorMaterializerImpl.materialize(ActorMaterializerImpl.scala:138)
at akka.stream.impl.ActorMaterializerImpl.materialize(ActorMaterializerImpl.scala:138)
at akka.stream.scaladsl.RunnableGraph.run(Flow.scala:350)
at akka.stream.scaladsl.Source.runWith(Source.scala:81)
play.core.server.netty.NettyModelConversion.play$core$server$netty$NettyModelConversion$$createChunkedResponse(NettyModelConversion.scala:256)
play.core.server.netty.NettyModelConversion$$anonfun$convertResult$1.apply(NettyModelConversion.scala:189)
play.core.server.netty.NettyModelConversion$$anonfun$convertResult$1.apply(NettyModelConversion.scala:166)
play.core.server.common.ServerResultUtils$.resultConversionWithErrorHandling(ServerResultUtils.scala:127)
at play.core.server.netty.NettyModelConversion.convertResult(NettyModelConversion.scala:235)
play.core.server.netty.PlayRequestHandler$$anonfun$play$core$server$netty$PlayRequestHandler$$handleAction$2$$anonfun$apply$4$$anonfun$apply$5.apply(PlayRequestHandler.scala:273)
play.core.server.netty.PlayRequestHandler$$anonfun$play$core$server$netty$PlayRequestHandler$$handleAction$2$$anonfun$apply$4$$anonfun$apply$5.apply(PlayRequestHandler.scala:267)
at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:253)
at play.api.libs.streams.impl.RelaxedPublisher.subscribe(RelaxedPublisher.scala:19)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:36)
at play.api.libs.iteratee.Execution$trampoline$.executeScheduled(Execution.scala:110)
at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:70)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:252)
at scala.concurrent.Promise$class.complete(Promise.scala:55)
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:157)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:347)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:345)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:36)
com.fl.commons.concurrent.MDCPropagatingExecutionContext$$anon$1.com$fl$commons$concurrent$MDCPropagatingExecutionContext$class$$anon$$run$body$1(MDCPropagatingExecutionContext.scala:24)
com.fl.commons.concurrent.MDCPropagatingExecutionContext$$anon$1$$anonfun$1.run(MDCPropagatingExecutionContext.scala:18)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:39)
akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:415)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:44)

Play Iteratees Version 2.6.1

API (Scala / Java / Neither / Both)

Ok.chunked(Source.fromPublisher(IterateeStreams.enumeratorToPublisher(data)))

Operating System (Ubuntu 15.10 / MacOS 10.10 / Windows 10)

ubuntu

JDK OpenJDK 1.8.x

Library Dependencies

val playVer = "2.6.3"

  "com.typesafe.play" % "play_2.11" % playVer,
  "com.typesafe.play" % "play-json_2.11" % playVer,
  "com.typesafe.play" %% "play-ahc-ws-standalone" % "1.0.4",
//  "com.typesafe.play" % "play-ws_2.11" % playVer,
  ("org.reactivemongo" % "play2-reactivemongo_2.11" % "0.12.5-play26").excludeAll(ExclusionRule("com.typesafe.play", "play-iteratees_2.11")),
  "org.reactivemongo" % "reactivemongo_2.11" % "0.12.5",
  "org.reactivemongo" %% "reactivemongo-iteratees" % "0.12.5",
  "com.typesafe.play" % "play-iteratees_2.11" % "2.6.1",
  "com.typesafe.play" % "play-iteratees-reactive-streams_2.11" % "2.6.1",

Expected Behavior

I should be able to have a chunked response from Enumerator of ByteString

Actual Behavior

Process crash while calling the chunk response method with the stack trace shown above.

Iteratee.run swallows root cause for exceptions

We are using ReactiveMongo library, which, in turn, uses iteratees. Sometimes reading a documents from it results pretty puzzling errors like:

java.lang.RuntimeException: Error reading ClientConfig
    at scala.sys.package$.error(package.scala:27) ~[org.scala-lang.scala-library-2.11.7.jar:na]
    at play.api.libs.iteratee.Iteratee$$anonfun$run$1.apply(Iteratee.scala:355) ~[com.typesafe.play.play-iteratees_2.11-2.3.5.jar:2.3.5]
...
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [org.scala-lang.scala-library-2.11.7.jar:na]

Note the lack of root cause. With big document, it is pretty much impossible to understand what is the problem.

In this case, we were able to find the broken document, and reading it in test environments produces following exception chain:

GameLogicSupport.Json.JsonException: Error reading ClientConfig
Caused by: GameLogicSupport.Json.JsonException: Error reading logic
Caused by: GameLogicSupport.Json.JsonException: Error reading LogicConfiguration
Caused by: GameLogicSupport.Json.JsonException: Error reading map
Caused by: GameLogicSupport.Json.JsonException: Error reading MapConfiguration
Caused by: GameLogicSupport.Json.JsonException: Error reading provinces
Caused by: GameLogicSupport.Json.JsonException: Error reading ProvinceConfiguration
Caused by: java.lang.IllegalArgumentException: No value for mandatory field craftingRewardLimit

Which gives plenty of information to pinpoint the problem.

It seems that culprit is the following code in Iteratee.run(2 places):

case Step.Error(msg, e) => sys.error(msg)

Please, fix it to preserve root cause.

Thread-safety of vars in iteratee module

From playframework/playframework#1076:

In the iteratees module we use vars in the iteratees package in what looks like a non-thread-safe way. We need to review each occurrence and possibly update it to be thread-safe, e.g. mark @volatile.

$ grep -n var *
Concurrent.scala:555:    var closeFlag = false
Concurrent.scala:697:      var isClosed: Boolean = false
Enumerator.scala:62:   * A variation on `apply` or `|>>` which returns the state of the iteratee rather
Enumerator.scala:361:      var iteratee: Iteratee[E, A] = it
Enumerator.scala:362:      var promise: scala.concurrent.Promise[Iteratee[E, A]] = Promise[Iteratee[E, A]]()
Enumerator.scala:546:      var iterateeP = Promise[Iteratee[E, A]]()
Enumerator.scala:586:      var iterateeP = Promise[Iteratee[E, A]]()
Enumerator.scala:761:  var iteratee: Iteratee[E, _] = _
Enumerator.scala:762:  var promise: Promise[Iteratee[E, _]] = _

Improve Concurrent.unicast API

From playframework/playframework#3619

At the moment Concurrent.unicast is really hard to use. It should often be used instead of Concurrent.broadcast, but I think it's just too hard to work out. I wanted to suggest updating the docs in #3336 to use Concurrent.unicast but I couldn't write the code succinctly.

Here's the current method signature:

  def unicast[E](
    onStart: Channel[E] => Unit,
    onComplete: => Unit = (),
    onError: (String, Input[E]) => Unit = (_: String, _: Input[E]) => ())(implicit ec: ExecutionContext) = new Enumerator[E] {

What I propose:

  • Make a new Concurrent.unicast method that creates an Enumerator that can only be used once. Only being usable once will simplify the code and make things more efficient..
  • Change the signature to use Futures instead of callbacks. We can do this because we're only using the Enumerator once.
  /**
   * @param channel The Channel to push inputs down.
   * @param completion A future that will be completed when the attached
   * Iteratee is Done or completes with an Error. Will be a failure if the
   * Iterate had an error.
   */
  final case class Unicast[E](channel: Channel[E], completion: Future[Unit])

  def unicast[E]: (Enumerator, Future[Unicast])

IterateeSubscriber feeds EOF into the iteratee onComplete

This shouldn't be done, for example, it breaks the following:

Streams.publisherToEnumerator(somePublisher) >>> Enumerator("foo")

If the IterateeSubscriber (created by the PublisherEnumerator) feeds EOF when the publisher is done, then that means the concatenated enumerator can never be reached because the iteratee it feeds into will go done when it receives the EOF.

Moved from playframework/playframework#4956

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.