2013-06-03 32 views
15

Tôi có một diễn viên nhận thư, tìm kiếm hệ thống tệp cho tệp và trả về đường dẫn đầy đủ của Tệp.người gửi bên trong tương lai

Để giữ cho nó không đồng bộ, tôi đã thực hiện:

def receive ={ 
case s:String => { 

    val f = future{ 
     val ans = search(s) 
     println("Input Request: "+s+" output:"+ans+" "+sender.path) 
    } 
    f.onComplete{ 
    case Success(x) => sender ! x 
    case Failure(y) => println("Could not complete it") 
    } 

} 

Nhưng tôi đã quan sát thấy rằng nó sẽ trả về thông điệp tới akka://FileSystem/deadLetters và không phải là sender. Tài liệu nói rằng:

Chỉ hợp lệ trong chính diễn viên, vì vậy đừng đóng nó và * xuất bản lên các chủ đề khác!

Vì vậy, có nghĩa là, tôi sẽ nhất thiết phải đồng bộ hóa nó? Còn cách nào khác không?

+0

Tại sao sử dụng một tương lai? Đó là một hoạt động I/O (và do đó có thể chặn), do đó, hãy đặt diễn viên vào bộ điều phối chặn-io. Nếu bạn cần tìm kiếm nhiều tệp cùng một lúc, hãy chạy nhiều phiên bản. –

Trả lời

32

Bạn đang làm cho một sai lầm rất phổ biến của "đóng trên nhà nước có thể thay đổi". Việc đóng cửa bạn chuyển đến onComplete không tạo bản sao của this.sender, vì vậy khi bạn gọi onComplete, bạn sẽ gửi tin nhắn đến bất cứ điều gì this.sender xảy ra để trỏ đến tại thời điểm đó, chứ không phải những gì nó chỉ ra khi bạn tạo đóng.

Bạn có thể tránh vấn đề này bằng cách tạo địa phương, bản sao bất biến của riêng bạn trong những nội dung hiện tại của this.sender, và tài liệu tham khảo có giá trị trong việc đóng cửa:

val origSender = sender 
f.onComplete { 
    case Successs(x) => origSender ! x 
    ... 
} 
+0

có cần thiết cho 'self' không? –

+1

@GeorgePligor Không, bản thân không thể thay đổi được. – stew

4
import akka.pattern.pipe 

Bí quyết. Thực hiện:

val reply = sender 
future { 
    val ans = searchAndCache(s) 
    println("Input Request: "+s+" output:"+ans+" "+reply.path) 
    ans 
} pipeTo reply 

trả lời lại cho người gửi

+8

Có vẻ như câu trả lời này không chính xác hoặc gây nhầm lẫn tập trung vào pipeTo. Theo như tôi biết, sử dụng pipeTo thay vì! đã không khắc phục được sự cố. Tiết kiệm người gửi trong "trả lời" là những gì sẽ ngăn chặn hành vi mà bạn đã nhìn thấy trước đây, đó là câu trả lời của câu trả lời của stew. – mushroom

Các vấn đề liên quan