2016-04-07 1 views
4

Akka.NET предоставляет API F #, который делает тривиальным определение актеров Akka как функций F # над почтовыми ящиками Akka. И до тех пор, пока все сообщения, обработанные актером, могут быть описаны с использованием единого дискриминационного объединения, ящик с активным типом. Проблема в том, что размещение всех определений сообщений в одном типе (дискриминационный союз) часто делает этот тип грязным: актер часто отвечает на сообщение разных категорий, например. сообщения, отправленные удаленными клиентами и сообщения, используемые во внутренних сообщениях. Например, актер может создавать внутренние задания и получать уведомления от внутренних компонентов. Это имеет смысл, чтобы определить эти внутренние сообщения, используя тип другой (внутренний), но затем chages почтового ящика актера уже не может быть сильным типом, и функция взгляд актера, как это:Как определить функции актера F #, чтобы избежать бокса сообщений?

let rec loop() = 

     actor { 
      let! message = mailbox.Receive() 
      match box message with 
      | :? PublicMessage as msg -> handlePublicMessage msg 
      | :? PrivateMessage as msg -> handlePrivateMessage msg 
      | _ -> raise (InvalidOperationException(sprintf "Invalid message type %A" message)) 

      return! loop() 
     } 

    loop() 

Что мне не нравится в том, что это подход забирает одну из основных сил F #: тип вывода. Вместо этого мы должны вводить сообщения для преобразования их в тип объекта, а затем приводить их к типам, которые мы ожидаем.

Есть два варианта этого подхода:

  1. Всегда перечислить все случаи сообщений в рамках одного типа. Плохо, плохо, плохо.
  2. Определите тип актера для типа сообщения. ИМХО это может оказаться даже достойным, потому что решение о создании нового типа актера не должно быть обусловлено специфическими языковыми ограничениями.

Я проверил код из загрузочного диска Akka.NET, и они используют первый подход - с бокс-сообщением и литьем сообщений. Это лучшее, что можно сделать?

+0

У меня нет опыта работы с Akka.NET. Если единственная проблема заключается в смешивании публичных и частных типов сообщений, разрешено ли вам использовать вложенный дискриминированный союз? то есть. type Message = Public of PublicMsg | Частный PrivateMsg; где PublicMsg и PrivateMsg являются отдельными отдельными профсоюзами. – piaste

ответ

0

Хорошо, мне кажется, есть две проблемы - внутренние сообщения и бокс/тип безопасности.

Как я понимаю, модель актера не содержит личных сообщений. Либо актер может ответить на сообщение, либо не может. Если вы действительно хотите иметь асинхронную личную логику, я предлагаю использовать асинхронную функцию во время обработки публичного сообщения, а не другое сообщение с актером, поскольку оно должно быть общедоступным.

Для безопасности типа, хотя я не пробовал еще, кажется, есть еще один способ избежать выражения вычислений на нерест актеров и использование при условии общего actorOf функции вместо так:

let handleMessage message = 
    match message with 
    | PublicMessage as msg -> handlePublicMessage msg 
    | PrivateMessage as msg -> handlePrivateMessage msg 
    | _ -> raise (InvalidOperationException(sprintf "Invalid message type %A" message)) 

let actorRef = spawn system "my-actor" <| actorOf handleMessage 

Это в основном альтернативой типу безопасности для вашего варианта 1. Я лично не вижу проблемы при перечислении всех поддерживаемых типов сообщений в одном типе объединения. Либо актер знает свои сообщения (предпочтительно с резервным отступлением по умолчанию), либо вы хотите полностью объектно ориентироваться, и нет типов, только динамические сообщения в коробке.

Более подробная информация, например, здесь, в документации: http://getakka.net/docs/FSharp%20API#creating-actors-with-actor-computation-expression

+0

Спасибо. Я знал о actorOf и actorOf2, но на самом деле они не решают пролет сообщения downcast, если актер должен обрабатывать несколько типов сообщений. Я также обсуждал это в чате Akka.NET gitter, и было заключено, что ограничение заключается в возможностях языка F #. –

Смежные вопросы