Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a time-based chunking Enumeratee

I want to create a Play 2 Enumeratee that takes in values and outputs them, chunked together, every x seconds/milliseconds. That way, in a multi-user websocket environment with lots of user input, one could limit the number of received frames per second.

I know that it's possible to group a set number of items together like this:

val chunker = Enumeratee.grouped(
  Traversable.take[Array[Double]](5000) &>> Iteratee.consume()
)

Is there a built-in way to do this based on time rather than based on the number of items?

I was thinking about doing this somehow with a scheduled Akka job, but on first sight this seems inefficient, and I'm not sure if concurency issues would arise.

like image 626
Carsten Avatar asked Mar 09 '13 13:03

Carsten


People also ask

What are examples of chunking?

Chunking ExamplesTelephone numbers and credit card numbers are typically chunked in groups of three or four digits. When you encounter a phone number (or other familiar grouping) that's chunked in an unfamiliar way, it can be much harder to remember it.

What are chunking techniques?

Chunking refers to the process of taking individual pieces of information and grouping them into larger units. By grouping each data point into a larger whole, you can improve the amount of information you can remember. Probably the most common example of chunking occurs in phone numbers.

Is chunking a time management strategy?

In terms of personal productivity, time chunking is the realization that we have specific projects and tasks that are expected to be done over the course of your entire work day. But instead of thinking of your work day as eight or ten hours, you create smaller chunks dedicated to specific topics.


1 Answers

How about like this? I hope this is helpful for you.

 package controllers

 import play.api._
 import play.api.Play.current
 import play.api.mvc._
 import play.api.libs.iteratee._
 import play.api.libs.concurrent.Akka
 import play.api.libs.concurrent.Promise

 object Application extends Controller {

   def index = Action {
     val queue = new scala.collection.mutable.Queue[String]
     Akka.future {
       while( true ){
         Logger.info("hogehogehoge")
         queue += System.currentTimeMillis.toString
         Thread.sleep(100)
       }
     }
     val timeStream = Enumerator.fromCallback { () =>
       Promise.timeout(Some(queue), 200)
     }
     Ok.stream(timeStream.through(Enumeratee.map[scala.collection.mutable.Queue[String]]({ queue =>
       var str = ""
       while(queue.nonEmpty){
         str += queue.dequeue + ", "
       }
       str
     })))
   }

 }

And this document is also helpful for you. http://www.playframework.com/documentation/2.0/Enumerators

UPDATE This is for play2.1 version.

 package controllers

 import play.api._
 import play.api.Play.current
 import play.api.mvc._
 import play.api.libs.iteratee._
 import play.api.libs.concurrent.Akka
 import play.api.libs.concurrent.Promise
 import scala.concurrent._
 import ExecutionContext.Implicits.global

 object Application extends Controller {

   def index = Action {
     val queue = new scala.collection.mutable.Queue[String]
     Akka.future {
       while( true ){
         Logger.info("hogehogehoge")
         queue += System.currentTimeMillis.toString
         Thread.sleep(100)
       }
     }
     val timeStream = Enumerator.repeatM{
       Promise.timeout(queue, 200)
     }
     Ok.stream(timeStream.through(Enumeratee.map[scala.collection.mutable.Queue[String]]({ queue =>
       var str = ""
       while(queue.nonEmpty){
         str += queue.dequeue + ", "
       }
       str
     })))
   }

 }
like image 103
buster84 Avatar answered Oct 12 '22 13:10

buster84