Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- open System
- open Akka.FSharp
- open Akka.Actor
- let inline (^) f x = f x
- let system = System.create "my-system" (Configuration.load())
- //let sagaActor =
- // spawn system "saga-handler-actor"
- // (fun mailbox ->
- // let rec loop() = actor {
- // let! message = mailbox.Receive()
- // let events = commandHandler message
- // //saga-event-listener
- // //wait
- // //check if events are ok
- // //parent <! Tell
- // return! loop()
- // }
- // loop())
- //let eventHandlerActor =
- // spawn system "command-handler-actor"
- // (fun mailbox ->
- // let rec loop() = actor {
- // let! message = mailbox.Receive()
- // eventHandler message
- // return! loop()
- // }
- // loop())
- let requestHandlerActor =
- spawn system "request-handler-actor"
- (fun mailbox ->
- let rec loop x = actor {
- let! message = mailbox.Receive()
- //sagaActor <! message
- //create child actor for handle command ::commandHandlerActor::
- // handle an incoming message
- return! loop x
- }
- loop 1)
- type Cmd =
- | CreateUser of string
- | RemoveUser of Guid
- type Evt =
- | UserCreated of Guid * string
- | UserRemoved of Guid
- let idGenerator () = Guid.NewGuid()
- let createUser name =
- if not <| String.IsNullOrEmpty name then
- [UserCreated (idGenerator(), name)]
- else
- []
- let commandHandler cmd =
- match cmd with
- | CreateUser name ->
- createUser name
- | RemoveUser id -> []
- let eventHandler evt =
- match evt with
- | CreateUser name -> ()
- | RemoveUser id -> ()
- type Command = unit
- type ForwardCommand = Forward of Command
- type BackwardCommand = Backward of Command
- [<RequireQualifiedAccessAttribute>]
- type SagaState =
- | Empty
- | Fill of ForwardCommand list
- | Forward of Currect: ForwardCommand * Remains: ForwardCommand list * Completed: ForwardCommand list
- | Backward of Currect: BackwardCommand * Remains: BackwardCommand list * Completed: BackwardCommand list
- | BackwardAbort of Remains: BackwardCommand list * Completed: BackwardCommand list
- | ForwardComplete of Completed: ForwardCommand list
- | BackwardComplete of Completed: BackwardCommand list
- | Stop
- [<RequireQualifiedAccessAttribute>]
- type SagaEvent =
- | SagaForwardCommandAdded of ForwardCommand
- | Started
- | Forwarded
- | ForwardFailed
- | Backwarded
- | BackwardFailed
- | ForwardDone
- | BackwardDone
- | Stoped
- let initSaga = SagaState.Empty
- let forwardToBackward (Forward cmd) = Backward cmd
- let applyEvent state event =
- printfn "Current state is: %A and event %A" state event
- match state, event with
- | SagaState.Empty, SagaEvent.SagaForwardCommandAdded cmd ->
- SagaState.Fill ^ [cmd]
- | SagaState.Fill cmds, SagaEvent.SagaForwardCommandAdded cmd ->
- SagaState.Fill ^ (cmd::cmds)
- | SagaState.Fill (_::_ as cmds), SagaEvent.Started ->
- let current, remains = cmds |> List.rev |> (fun (x::xs) -> x, xs)
- SagaState.Forward (current, remains, [])
- | SagaState.Forward (current, next::remains, completed), SagaEvent.Forwarded ->
- SagaState.Forward (next, remains, current::completed)
- | SagaState.Forward (current, [], completed), SagaEvent.Forwarded ->
- SagaState.ForwardComplete (current::completed)
- | SagaState.Forward (_, next::_, completed), SagaEvent.ForwardFailed ->
- SagaState.Backward (next |> forwardToBackward, completed |> List.map forwardToBackward, [])
- | SagaState.Backward (current, next::remains, completed), SagaEvent.Backwarded ->
- SagaState.Backward (next, remains, current::completed)
- | SagaState.Backward (current, [], completed), SagaEvent.Backwarded ->
- SagaState.BackwardComplete (current::completed)
- | SagaState.Backward (current, remains, completed), SagaEvent.BackwardFailed ->
- SagaState.BackwardAbort (remains, current::completed)
- | _, SagaEvent.Stoped ->
- SagaState.Stop
- | state, event -> failwith (sprintf "Wrong state %A %A" state event)
- let playEvents state events = events |> List.fold applyEvent state
- [<RequireQualifiedAccess>]
- type SagaMessage<'a> =
- | ForwardComplete of 'a
- | BackwardComplete of 'a
- | BackwardAbort of string
- | Stop of string
- let runSaga state parent =
- spawn parent "saga-handler-actor"
- (fun mailbox ->
- let rec loop state = actor {
- match state with
- | SagaState.Empty ->
- let! msg = mailbox.Receive()
- if msg = "add" then
- let events = [SagaEvent.SagaForwardCommandAdded ^ Forward ()]
- return! loop (events |> playEvents state)
- else
- return! loop state
- | SagaState.Fill _ ->
- let! msg = mailbox.Receive()
- if msg = "add" then
- let events = [SagaEvent.SagaForwardCommandAdded ^ Forward ()]
- return! loop (events |> playEvents state)
- elif msg = "forward" then
- let events = [SagaEvent.Started]
- return! loop (events |> playEvents state)
- else
- return! loop state
- | SagaState.Forward (current, _, _) ->
- return! loop ([SagaEvent.Forwarded] |> playEvents state)
- | SagaState.Backward (currect, remains, completed) ->
- return! loop ([SagaEvent.Backwarded] |> playEvents state)
- | SagaState.BackwardAbort (remains, completed) ->
- mailbox.Sender() <! SagaMessage.BackwardAbort "ok"
- | SagaState.ForwardComplete completed ->
- mailbox.Sender() <! SagaMessage.ForwardComplete "ok"
- | SagaState.BackwardComplete completed ->
- mailbox.Sender() <! SagaMessage.BackwardComplete "ok"
- | SagaState.Stop ->
- mailbox.Sender() <! SagaMessage.Stop
- }
- loop state)
- [<EntryPoint>]
- let main argv =
- let test1 =
- spawn system "handler-actor"
- (fun mailbox ->
- let sagaActor = runSaga initSaga mailbox
- sagaActor <! "add"
- sagaActor <! "add"
- sagaActor <! "forward"
- let rec loop () = actor {
- let! sagaMsg = mailbox.Receive()
- printf "%A" sagaMsg
- let re =
- match sagaMsg with
- | SagaMessage.ForwardComplete "ok" -> 1
- | SagaMessage.BackwardComplete res -> 2
- | SagaMessage.BackwardAbort reason -> 3
- | SagaMessage.Stop reason-> 4
- | _ -> 5
- //printf "Res is %i" res
- return re
- }
- loop ())
- //System.Threading.Thread.Sleep(100)
- //test1 <! SagaMessage.ForwardComplete 1
- Console.ReadKey() |> ignore
- 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement