MailboxProcessor<'Msg>
클래스를 통해 F #의 상담원과 작업을 시작하려고하는데 예외에 대한 적절한 처리가 없다는 것을 알게되었습니다. 하스켈 세계에서는 어떤 예외도 없으므로 문제를 처리하는 적절한 방법은 단순히 응답 사례로 제공하는 것입니다. 다음 에이전트의 .PostAndReply
메소드를 호출하고 InvalidData
데이터가 유효하지 않은 이유를 나타내는 메시지를 포함 얻을 수실패 후 MailboxProcessor를 다시 시작 하시겠습니까?
type AgentResponse =
| HandledData of string
| InvalidData of string
하나 : 그래서 에이전트는 같은 회신 할 수있다. 그러나 이것은 하스켈이 아니며 때때로 예외가 발생합니다.
let agent =
new MailboxProcessor<string * AsyncReplyChannel<AgentResponse>>(fun inbox ->
async {
while true do
let! (msg, replyChannel) = inbox.Receive()
if msg = "die" then failwith "Unknown exception encountered!"
else replyChannel.Reply(HandledData(msg))
})
agent.Start()
agent.PostAndReply (fun rc -> "die", rc)
agent.PostAndReply (fun rc -> "Test", rc)
두 번째 호출 agent.PostAndReply
에 블록 무기한 :이 이렇게한다면. AsyncReplyChannel
을 사용하지 않고 따라서 agent.Post
을 호출하면 호출이 차단되지 않지만 에이전트에서 예외가 발생하면 새 메시지가 대기열에 남아 있습니다. 다시 호출 할 때 agent.Start
함수가 InvalidOperationException
을 반환하기 때문에이 두 경우 모두에서 에이전트를 다시 시작할 수 없으며이를 처리하는 자연스러운 방법은 깨끗한 상태의 새 에이전트를 만드는 것이지만 대기중인 모든 메시지는 손실됩니다.
상담원의 전체 본문을 try..with
에 배치하는 것 외에도 예외 발생 후 에이전트를 계속 실행하는 좋은 방법이 있습니까? 다른 방법으로, 이것을 다루는 "표준"방법이 누군가가 나를 가리킬 수 있도록 설립 되었습니까? .... ghci에서 Data.List.head []
을 시도
불행하게도 종속 유형의 부족을 의미, 우리가 어떤 계산 의미가 없다 타입 올바른 코드를 쓸 수 있는지, 하스켈 또는 F에 # :
나는 MailboxProcessor (에이전트)의 모든 아이디어가 실패 할 때 죽는다 고 생각한다. 어쩌면 다른 에이전트를 대기열로 사용할 수 있고 오류가있을 때 대기열 에이전트가 새 에이전트를 실행하는 곳에 'TryPostAndReply'를 사용할 수 있습니까? 고성능이 필요하다면'try ... catch'가 아마도 최선의 방법이라고 생각합니다. – mydogisbox
@mydogisbox 모든 것을 잡는 것은 최적이 아닌 아이디어처럼 보입니다. 그러나 나는 또한 이것이 최선의 방법이라고 생각합니다. 내가 피하려고하는 문제는 대기중인 메시지의 복사본 두 개를 유지해야한다는 것입니다. 예를 들어 F #에 메일러 데몬을 작성한 경우 데몬은 에이전트가 잡을 생각이없는 네트워크 예외를 쳤기 때문에 대기중인 전자 메일을 "잃어 버려서는 안됩니다."따라서 메시지는 대기열뿐만 아니라 다른 곳에 보관해야합니다.대기열에있는 모든 항목의 두 번째 사본이 필요하면 대기열이있는 상담원의 목적을 무력화하는 것처럼 느껴집니다. – Amazingant
동의합니다. erlang 에이전트 모델이이 문제를 어떻게 처리하는지 궁금합니다. – mydogisbox