Search code examples
scalaakka-http

Send request at regular interval


Hello I am trying to learn akka-http and make a simple client for a rest api. I would like to know how to send a request to a rest server at regular interval.

I have my simple client:

object RestClientApp extends App {
  // set up ActorSystem and other dependencies here
  //#main-class
  //#server-bootstrapping
  implicit val system: ActorSystem = ActorSystem()
  implicit val materializer: ActorMaterializer = ActorMaterializer()
  //#server-bootstrapping

  // needed for the future flatMap/onComplete in the end
  implicit val executionContext = system.dispatcher

  val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://akka.io"))

  responseFuture
    .onComplete {
      case Success(res) => println(res)
      case Failure(_) => sys.error("something wrong")
    }
}

How can I send a request and process the response every x time unit ?


Solution

  • you can define RestClient as an actor and use actorSystem.schedule to schedule the actor.

      final def schedule(
        initialDelay: FiniteDuration,
        interval:     FiniteDuration,
        receiver:     ActorRef,
        message:      Any)(implicit
        executor: ExecutionContext,
                           sender: ActorRef = Actor.noSender): Cancellable =
    

    Example,

    import akka.actor.{Actor, ActorSystem, Props}
    
    class RestClientActor extends Actor {
      import RestClientActor._
      import scala.util.Success
      import scala.util.Failure
      import akka.http.scaladsl.Http
      import akka.http.scaladsl.model.HttpRequest
    
      implicit val actorSystem: ActorSystem = context.system
      import context.dispatcher
    
      override def receive: Receive = {
        case InitiateRequest =>
          Http().singleRequest(HttpRequest(uri = "http://jsonplaceholder.typicode.com/posts")).onComplete {
            case Success(s) => println(s._3)
            case Failure(f) => println(f.getMessage)
          }
      }
    }
    
    object RestClientActor {
      case object InitiateRequest
    }
    
    object RestClientApp {
    
      def main(args: Array[String]): Unit = {
    
        import akka.actor.ActorSystem
        import scala.concurrent.duration._
        import RestClientActor._
        import scala.concurrent.ExecutionContextExecutor
    
        implicit val system: ActorSystem = ActorSystem()
        implicit val executionContext: ExecutionContextExecutor = system.dispatcher
    
        val actor = system.actorOf(Props[RestClientActor], "RestClientActor")
    
        system.scheduler.schedule(1 seconds, 3 seconds, actor, InitiateRequest)
    
      }
    }