F # и обработчик почтовых ящиков не работают - PullRequest
1 голос
/ 05 мая 2020

Я использую процессор почтовых ящиков F # для синхронизации обмена данными, поэтому есть некоторые операции и флаги (отправка и завершение) установлены в значение true, но иногда мне нужно сбросить, поэтому я использую api для этого, поэтому мой api имеет специальная команда, которую я назвал системной очисткой, эта операция устанавливает для некоторых системных флагов значение false, но проблема в том, что она не срабатывает.

В качестве механизма API я использую Nancy (но я не думаю, что это источник проблемы), поэтому модуль, который сбрасывает системные флаги, будет выглядеть так:

let purgeHandler = 

    Func<obj, Response> 
        (fun _ -> 
            try
                HandshakeProcessor.Post(HandshakeService.Purge)
                let jsonBytes = System.Text.Encoding.UTF8.GetBytes(""" {} """)
                new Response 
                        (ContentType = "application/json", 
                            StatusCode = HttpStatusCode.OK,
                            Contents = fun s -> s.WriteAsync(jsonBytes, 0, jsonBytes.Length) |> Async.AwaitTask |> Async.RunSynchronously)
            with
                ex -> 
                    let jsonBytes = System.Text.Encoding.UTF8.GetBytes(sprintf """ { "result": "false", "error": "%s" } """ ex.Message)
                    new Response 
                        (ContentType = "application/json", 
                            StatusCode = HttpStatusCode.InternalServerError,
                            Contents = fun s -> s.WriteAsync(jsonBytes, 0, jsonBytes.Length) |> Async.AwaitTask |> Async.RunSynchronously))

this.Put("Purge", purgeHandler)

Это довольно просто, как только я получаю запрос, я отправляю команду очистки в почтовый ящик, чтобы установить флаги в false.

Итак, мой почтовый ящик выглядит так:

    type HandshakeService =
      | Finalized of (bool * bool)
      | Purge
      | Get of AsyncReplyChannel<HandshakePools>

    let HandshakeProcessor : MailboxProcessor<HandshakeService> = 
    let handshake = HandshakePools()
      MailboxProcessor.Start(fun inbox ->
        let rec registerMessagePoint (responseType : ResponseType, message : DatabaseMessage) =
            async{
                let! msg = inbox.Receive()
                match msg with 
                | Finalized (send, finalized) -> 
                    handshake.Finalized <- finalized
                    handshake.Send <- send
                | Purge ->
                    handshake.Send <- false
                    handshake.Finalized <- false
                    return! registerMessagePoint(responseType, message)
                | Get replyChannel ->
                    handshake |> replyChannel.Reply
                    return! registerMessagePoint (responseType, message)  
            }
        registerMessagePoint(ResponseType.Unknown, DatabaseMessage (0us, 0us, String.Empty)))

Кроме того, когда я использую статус флага внутри FUN C например:

let pools = HandshakeProcessor.PostAndReply((fun reply -> HandshakeService.Get reply), timeout = 10000)
printfn "\n\n\n\n  FINALIZED %b  \n\n\n\n" pools.Finalized

Я получаю исключение тайм-аута.

Также, если я перемещаю Post перед Fun c, он запускается, но только один раз во время инициализации модуля, тогда, когда я снова вызываю этот метод, он не будет ошибаться, например:

let purgeHandler (handshakePool : HandshakePools) = 

    HandshakeProcessor.Post(HandshakeService.Purge) 
    Func<obj, Response> 

Итак, пр проблема в том, что когда я запускаю сообщение об очистке метода API, пропускается. Он не вводит метод очистки в почтовом ящике, и флаги остаются прежними, я установил точку останова в части очистки почтового ящика. Кто-нибудь знает, как решить эту проблему?

1 Ответ

1 голос
/ 06 мая 2020

Кажется, что нет простого способа сделать это, все, что я нашел, - это использование SignalR с nancyFx в этом случае. Итак, вышли из MailboxProcessor и вместо этого создаем посредника.

Посредник:

type HttpCommunicationMediator private () =   

  static member val private _instance = lazy HttpCommunicationMediator()
  static member Instance = HttpCommunicationMediator._instance.Value

  member val private purgeSettings = Event<unit>()
  [<CLIEvent>]
  member this.PurgeSetting = this.purgeSettings.Publish
  member this.InvokePurgeSetting = this.purgeSettings.Trigger

Вызов при поступлении запроса API:

HttpCommunicationMediator.Instance.InvokePurgeSetting()

Выполнение события быть зарегистрированным):

HttpCommunicationMediator.Instance.PurgeSetting.AddHandler (fun _ _-> (* resets flags *))  

Ну не идеально, но работает.

...