Я пытаюсь начать работать с агентами на F# через класс MailboxProcessor<'Msg>
и быстро понял, что у меня нет надлежащей обработки исключений. В хаскелевском мире не было бы никаких исключений, поэтому правильным способом решения проблем было бы просто предоставить их в качестве случая ответа; чтобы агент мог ответить что-то вроде:
type AgentResponse =
| HandledData of string
| InvalidData of string
Затем можно вызвать метод .PostAndReply
агента и получить InvalidData
, содержащее сообщение, указывающее, почему данные недействительны. Однако это не Haskell, и иногда случаются исключения. Итак, если я сделаю это:
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
, есть ли хороший способ заставить агент продолжать работать после исключения? В качестве альтернативы, был ли установлен «стандартный» способ справиться с этим, на который кто-то может мне указать?
MailboxProcessor
(агента) заключается в том, что он умирает при неудаче. Может быть, вы могли бы использовать другого агента в качестве очереди, а затем использоватьTryPostAndReply
, где агент очереди запускает нового агента при возникновении ошибки? Если вам нужна высокая производительность, я думаю, чтоtry...catch
, вероятно, лучший вариант. - person N_A   schedule 02.01.2015