gopher.Time.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-gopher_3.0.0-RC2 Show documentation
Show all versions of scala-gopher_3.0.0-RC2 Show documentation
scala-gopher: asynchronous implementation of CSP ( go-like channels/selectors ) in scala
The newest version!
package gopher
import cps._
import gopher.impl._
import scala.concurrent._
import scala.concurrent.duration._
import java.util.concurrent.TimeUnit
import scala.language.experimental.macros
import scala.util.Try
import scala.util.Failure
import scala.util.Success
import java.util.concurrent.atomic.AtomicBoolean
import java.util.TimerTask
/**
* Time API, simular to one in golang standard library.
* @see gopherApi#time
*/
abstract class Time[F[_]](gopherAPI: Gopher[F]) {
type after = FiniteDuration
def after(duration: FiniteDuration): ReadChannel[F,FiniteDuration] =
{
val ch = gopherAPI.makeOnceChannel[FiniteDuration]()
schedule( () => {
val now = FiniteDuration(System.currentTimeMillis, TimeUnit.MILLISECONDS)
ch.awrite(now)
},
duration
)
ch
}
def asleep(duration: FiniteDuration): F[FiniteDuration] =
{
var fun: Try[FiniteDuration] => Unit = _ => ()
val retval = gopherAPI.asyncMonad.adoptCallbackStyle[FiniteDuration](listener => fun = listener)
schedule(() => {
val now = FiniteDuration(System.currentTimeMillis, TimeUnit.MILLISECONDS)
fun(Success(now))
},
duration)
retval
}
transparent inline def sleep(duration: FiniteDuration): FiniteDuration =
given CpsSchedulingMonad[F] = gopherAPI.asyncMonad
await(asleep(duration))
/**
* create ticker. When somebody read this ticker, than one receive duration
* messages. When nobody reading - messages are expired.
* @param duration
* @return
*/
def tick(duration: FiniteDuration): ReadChannel[F,FiniteDuration] =
{
newTicker(duration).channel
}
class Ticker(duration: FiniteDuration) {
val channel = gopherAPI.makeChannel[FiniteDuration](0).withExpiration(duration, false)
private val scheduled = schedule(tick, duration)
private val stopped = AtomicBoolean(false)
def stop(): Unit = {
scheduled.cancel()
stopped.set(true)
}
private def tick():Unit = {
if (!stopped.get()) then
channel.addWriter(SimpleWriter(now(),{
case Success(_) => // ok, somebody readed
case Failure(ex) =>
ex match
case ex: ChannelClosedException =>
scheduled.cancel()
stopped.lazySet(true)
case ex: TimeoutException => //
case other => // impossible,
gopherAPI.logImpossible(other)
}))
schedule(tick, duration)
}
}
def newTicker(duration: FiniteDuration): Ticker =
{
new Ticker(duration)
}
def now(): FiniteDuration =
FiniteDuration(System.currentTimeMillis(),TimeUnit.MILLISECONDS)
/**
* Low lwvel interface for scheduler
*/
def schedule(fun: () => Unit, delay: FiniteDuration): Time.Scheduled
}
object Time:
/**
* Used in selector shugar for specyfying tineout.
*```
* select{
* ......
* case t: Time.after if t > expr => doSomething
* }
*```
* is a sugar for to selectGroup.{..}.setTimeout(expr, t=>doSomething)
*@see Select
**/
type after = FiniteDuration
def after[F[_]](duration: FiniteDuration)(using Gopher[F]): ReadChannel[F,FiniteDuration] =
summon[Gopher[F]].time.after(duration)
def asleep[F[_]](duration: FiniteDuration)(using Gopher[F]): F[FiniteDuration] =
summon[Gopher[F]].time.asleep(duration)
transparent inline def sleep[F[_]](duration: FiniteDuration)(using Gopher[F]): FiniteDuration =
summon[Gopher[F]].time.sleep(duration)
/**
* Task, which can be cancelled.
**/
trait Scheduled {
def cancel(): Boolean
def onDone( listener: Try[Boolean]=>Unit ): Unit
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy