2012-03-15 31 views

Trả lời

54

Bạn không thực sự cần một diễn viên để làm điều này trong Akka 1.3.1 bạn có thể sắp xếp một hàm được gọi mỗi 5 phút như thế này:

Scheduler.schedule(() => println("Do something"), 0L, 5L, TimeUnit.MINUTES) 

Tuy nhiên, nếu bạn muốn nó được một diễn viên vì những lý do khác mà bạn sẽ gọi nó là như thế này

case class Message() 

val actor = actorOf(new Actor { 
    def receive = { 
    case Message() => println("Do something in actor") 
    } 
}).start() 

Scheduler.schedule(actor, Message(), 0L, 5L, TimeUnit.MINUTES) 

Nếu bạn đang sử dụng Akka 2.0 sau đó nó sẽ được thực hiện như thế này

val system = ActorSystem("MySystem") 
system.scheduler.schedule(0 seconds, 5 minutes)(println("do something")) 

Hoặc gửi một thông điệp tới một diễn viên mỗi 5 phút như

case class Message() 
class MyActor extends Actor { 
    def receive = { case Message() => println("Do something in actor") } 
} 

val system = ActorSystem("MySystem") 
val actor = system.actorOf(Props(new MyActor), name = "actor") 
system.scheduler.schedule(0 seconds, 5 minutes, actor, Message()) 
+3

Scheduler.schedule không xuất hiện để tồn tại nữa – Phil

+0

ghi nhớ mà bạn có thể muốn biết rằng lời gọi trước đó kết thúc khóa học của nó trước khi cái mới cháy sau 5 phút, trong một số trường hợp ít nhất. Bạn có thể sử dụng 'scheduleOnce' với một số logic bổ sung, cho điều đó. – matanster

19

Phương pháp này sử dụng lịch là một trong những cách tiếp cận tốt, mặc dù có một tiềm năng cho các thông điệp để xếp hàng lên nếu công việc được thực hiện đúng tiến độ là rất lớn có thể mất nhiều thời gian hơn khoảng thời gian đã lên lịch. Nếu bạn muốn khoảng thời gian xảy ra giữa cuối của một lần lặp và bắt đầu tiếp theo, sau đó sử dụng scheduleOnce với mẫu sau:

import akka.actor.Actor 
import scala.concurrent.duration._ 

class SchedulingActor extends Actor { 

    override def preStart(): Unit = { 
    self ! "Do Some Work" 
    } 

    def receive = { 
    case "Do Some Work" => 
     doWork 
     context.system.scheduler.scheduleOnce(5 minutes, self, "Do Some Work") 
    } 

    def doWork = ??? 
} 
+2

Đây là câu trả lời phù hợp kể từ năm 2016. Scheduler.schedule không còn là phương thức hợp lệ nữa. – Zee

+0

Bạn không thể sử dụng 'context.system.scheduler.schedule (...)' để gửi thư đến 'self' cứ 5 phút một lần? Nó sẽ trông sạch sẽ hơn và loại bỏ nhu cầu ghi đè 'preStart'. –

+0

@BranislavLazic Không, toàn bộ điểm không đặt lịch biểu định kỳ là tránh gửi một thông báo khác đến diễn viên nếu có tình huống trong đó logic xử lý yêu cầu thời gian vượt quá khoảng thời gian giữa mỗi thông báo được lên lịch. Với scheduleOnce(), các diễn viên có thể mất miễn là nó cần để hoàn thành bất cứ công việc là cần thiết, và sau đó khi nó được an toàn, thiết lập một lịch trình để gửi một thông điệp tương lai cho chính nó. Đối với một số trường hợp, điều này có thể tránh được các sự cố và các vấn đề tương tranh khác. – speby

0

Nếu bất cứ ai muốn mã java sau đó họ có thể làm như thế này

Cancellable cancellable = system.scheduler().schedule(Duration.Zero(), Duration.create(5, TimeUnit.MINUTES), cronActor, "tick", system.dispatcher(), null); 
Các vấn đề liên quan