Skip to content

Instantly share code, notes, and snippets.

@longshorej
Created April 4, 2024 22:44
Show Gist options
  • Save longshorej/ed939ca0ad6218139b20719bc56fd517 to your computer and use it in GitHub Desktop.
Save longshorej/ed939ca0ad6218139b20719bc56fd517 to your computer and use it in GitHub Desktop.
akka-streams only occasionally call an expensive function via expand
// suppose that isEnabled is expensive, so we want to call it only once, but otherwise reuse the results
// of the previous call. we can use Akka Streams expand operator to effectively repeat the previous
// value, and Source.tick to ensure we call only once per second
import akka.actor.ActorSystem
import akka.stream.scaladsl.{Sink, Source}
import scala.concurrent.duration._
import java.util.concurrent.ThreadLocalRandom
class Test {
implicit val system: ActorSystem = ActorSystem("test")
Source
.repeat(1)
.throttle(4, 1.second)
.scan(0)(_ + _)
.zip(
Source
.tick(0.seconds, 5.second, ())
.map(_ => isEnabled())
.expand(Iterator.continually(_))
)
.takeWithin(20.seconds)
.runWith(Sink.foreach(println))
// an expensive function - only want to call it once per second
private def isEnabled(): Boolean = {
val result = ThreadLocalRandom.current().nextBoolean()
println(s"calculated isEnabled=$result")
result
}
}
@longshorej
Copy link
Author

longshorej commented Apr 4, 2024

scala> new Test
calculated isEnabled=false
(0,false)
(1,false)
val res0: com.tubitv.adserver.Test = com.tubitv.adserver.Test@ac511d8

scala> (2,false)
(3,false)
(4,false)
(5,false)
(6,false)
(7,false)
(8,false)
(9,false)
(10,false)
(11,false)
(12,false)
(13,false)
(14,false)
(15,false)
(16,false)
(17,false)
(18,false)
(19,false)
(20,false)
calculated isEnabled=true
(21,false)
(22,true)
(23,true)
(24,true)
(25,true)
(26,true)
(27,true)
(28,true)
(29,true)
(30,true)
(31,true)
(32,true)
(33,true)
(34,true)
(35,true)
(36,true)
(37,true)
(38,true)
(39,true)
(40,true)
(41,true)
calculated isEnabled=true
(42,true)
(43,true)
(44,true)
(45,true)
(46,true)
(47,true)
(48,true)
(49,true)
(50,true)
(51,true)
(52,true)
(53,true)
(54,true)
(55,true)
(56,true)
(57,true)
(58,true)
(59,true)
(60,true)
(61,true)
calculated isEnabled=true
(62,true)
(63,true)
(64,true)
(65,true)
(66,true)
(67,true)
(68,true)
(69,true)
(70,true)
(71,true)
(72,true)
(73,true)
(74,true)
(75,true)
(76,true)
(77,true)
(78,true)
(79,true)
(80,true)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment