Advertisement
Guest User

Untitled

a guest
Jun 10th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 8.64 KB | None | 0 0
  1. open System
  2. //open Akka.FSharp
  3. open Akka.FSharp
  4.  
  5. let inline (^) f x = f x
  6.  
  7. let system = System.create "my-system" (Configuration.load())
  8.  
  9.  
  10.  
  11.     //let sagaActor =
  12.     //    spawn system "saga-handler-actor"
  13.     //        (fun mailbox ->
  14.     //            let rec loop() = actor {
  15.  
  16.     //                let! message = mailbox.Receive()
  17.  
  18.     //                let events = commandHandler message
  19.  
  20.     //                //saga-event-listener
  21.                    
  22.     //                //wait
  23.  
  24.     //                //check if events are ok
  25.  
  26.     //                //parent <! Tell
  27.  
  28.     //                return! loop()
  29.     //            }
  30.     //            loop())
  31.    
  32.  
  33.     //let eventHandlerActor =
  34.     //    spawn system "command-handler-actor"
  35.     //        (fun mailbox ->
  36.     //            let rec loop() = actor {
  37.  
  38.     //                let! message = mailbox.Receive()
  39.  
  40.     //                eventHandler message
  41.  
  42.     //                return! loop()
  43.     //            }
  44.     //            loop())
  45.  
  46.     //let requestHandlerActor =
  47.     //    spawn system "request-handler-actor"
  48.     //        (fun mailbox ->
  49.     //            let rec loop() = actor {
  50.  
  51.     //                let! message = mailbox.Receive()
  52.  
  53.     //                //sagaActor <! message
  54.     //                //create child actor for handle command ::commandHandlerActor::
  55.     //                // handle an incoming message
  56.     //                return! loop()
  57.     //            }
  58.     //            loop())
  59.        
  60.  
  61. type Cmd =
  62.     | CreateUser of string
  63.     | RemoveUser of Guid
  64.  
  65. type Evt =
  66.     | UserCreated of Guid * string
  67.     | UserRemoved of Guid
  68.  
  69. let idGenerator () = Guid.NewGuid()
  70.  
  71. let createUser name =
  72.     if not <| String.IsNullOrEmpty name then
  73.         [UserCreated (idGenerator(), name)]
  74.     else
  75.         []
  76.  
  77. let commandHandler cmd =
  78.     match cmd with
  79.     | CreateUser name ->
  80.         createUser name
  81.     | RemoveUser id -> []
  82.  
  83.  
  84. let eventHandler evt =
  85.     match evt with
  86.     | CreateUser name -> ()
  87.     | RemoveUser id -> ()
  88.  
  89. type Command = unit
  90.  
  91. type ForwardCommand = Forward of Command
  92. type BackwardCommand = Backward of Command
  93.  
  94. [<RequireQualifiedAccessAttribute>]
  95. type SagaState =
  96.     | Empty
  97.     | Fill of ForwardCommand list
  98.     | Forward of Currect: ForwardCommand * Remains: ForwardCommand list * Completed: ForwardCommand list
  99.     | Backward of Currect: BackwardCommand * Remains: BackwardCommand list * Completed: BackwardCommand list * ForwardCompleted: ForwardCommand list * ForwardRemains : ForwardCommand list
  100.     | BackwardAbort of FailCommand: BackwardCommand * Remains: BackwardCommand list * Completed: BackwardCommand list * ForwardCompleted: ForwardCommand list * ForwardRemains : ForwardCommand list
  101.     | ForwardComplete of Completed: ForwardCommand list
  102.     | BackwardComplete of Completed: BackwardCommand list * ForwardCompleted: ForwardCommand list * ForwardRemains : ForwardCommand list
  103.  
  104. [<RequireQualifiedAccessAttribute>]
  105. type SagaEvent =
  106.     | SagaForwardCommandAdded of ForwardCommand
  107.     | Started
  108.     | Forwarded
  109.     | ForwardFailed
  110.     | Backwarded
  111.     | BackwardFailed
  112.     | ForwardDone
  113.     | BackwardDone
  114.  
  115. let initSaga = SagaState.Empty
  116.  
  117. let forwardToBackward (Forward cmd) = Backward cmd
  118.  
  119. let applyEvent state event =
  120.     match state, event with
  121.     | SagaState.Empty, SagaEvent.SagaForwardCommandAdded cmd ->
  122.         SagaState.Fill ^ [cmd]
  123.  
  124.     | SagaState.Fill cmds, SagaEvent.SagaForwardCommandAdded cmd ->
  125.         SagaState.Fill ^ (cmd :: cmds)
  126.  
  127.     | SagaState.Fill (c::cs), SagaEvent.Started ->
  128.         SagaState.Forward (c, cs |> List.rev, [])
  129.  
  130.     | SagaState.Forward (current, next::remains, completed), SagaEvent.Forwarded ->
  131.         SagaState.Forward (next, remains, current::completed)
  132.  
  133.     | SagaState.Forward (current, [], completed), SagaEvent.Forwarded ->
  134.         SagaState.ForwardComplete (current::completed)
  135.  
  136.     | SagaState.Forward (current, remains, completed), SagaEvent.ForwardFailed ->
  137.         SagaState.Backward (current |> forwardToBackward, completed |> List.map forwardToBackward, [], completed, current::remains)
  138.  
  139.     | SagaState.Backward (current, next::remains, completed, forwardCompleted, forwardRemains), SagaEvent.Backwarded ->
  140.         SagaState.Backward (next, remains, current::completed, forwardCompleted, forwardRemains)
  141.  
  142.     | SagaState.Backward (current, [], completed, forwardCompleted, forwardRemains), SagaEvent.Backwarded ->
  143.         SagaState.BackwardComplete (current::completed, forwardCompleted, forwardRemains)
  144.  
  145.     | SagaState.Backward (current, remains, completed, forwardCompleted, forwardRemains), SagaEvent.BackwardFailed ->
  146.         SagaState.BackwardAbort (current, remains, completed, forwardCompleted, forwardRemains)
  147.     | state, event -> failwith (sprintf "Wrong state %A %A" state event)
  148.  
  149. let playEvents state events = events |> List.fold applyEvent state
  150.  
  151.  
  152. type NoneEmptyString = private NoneEmptyString of string
  153.  
  154. module NoneEmptyString =
  155.     let create str =
  156.         if str = "" then
  157.             failwith "Must be none-empty"
  158.         else
  159.             NoneEmptyString str
  160.  
  161. type Ticket = {
  162.     Owner: NoneEmptyString
  163.     QRCode: NoneEmptyString
  164.     EventName: NoneEmptyString
  165. }
  166.  
  167. type Event = {
  168.     Name: NoneEmptyString
  169.     StartDate: DateTime
  170.     EndDate: DateTime
  171.     TotalTicketCound: uint32
  172.     SoldTickets: Ticket list
  173. }
  174.  
  175. type PeopleCount = uint32
  176.  
  177. type EventState =
  178.     | SellTicketEvent of Event
  179.     | RunEvent of Event * PeopleCount
  180.  
  181. type EventCommand =
  182.     | AddTicket of Owner: NoneEmptyString
  183.     | RemoveTicket of Owner: NoneEmptyString
  184.     | Scan of QRCode: NoneEmptyString
  185.  
  186. let private createTicket eventName owner =
  187.     { Owner = owner
  188.       QRCode = NoneEmptyString.create "123"
  189.       EventName = eventName }
  190.  
  191. let private addTicket ticket event =
  192.     { event with SoldTickets = ticket::event.SoldTickets }
  193.  
  194. let private removeTicket ticket event =
  195.     { event with SoldTickets = event.SoldTickets |> List.filter(fun x -> x <> ticket) }
  196.  
  197. let private getTicket pred event =
  198.     event.SoldTickets |> List.tryFind pred
  199.  
  200. let addTicketFor user eventState =
  201.     match eventState with
  202.     | SellTicketEvent ({ Name = eventName } as event) ->
  203.         let ticket = createTicket eventName user
  204.  
  205.         Ok (addTicket ticket event)
  206.     | _ ->
  207.         Error "Wrong state"
  208.  
  209. let removeTicketFor owner eventState =
  210.     match eventState with
  211.     | SellTicketEvent event ->
  212.         let ticket = getTicket (fun x -> x.Owner = owner) event
  213.  
  214.         match ticket with
  215.         | Some t -> Ok (removeTicket t event)
  216.         | None -> Error "Alarm! impossible case"
  217.     | _ ->
  218.         Error "Wrong state"
  219.  
  220. let scan qrCode eventState =
  221.     match eventState with    
  222.     | RunEvent (event, peopleCount) ->
  223.         if peopleCount > 1000u then
  224.             Error "to many people"
  225.         else                      
  226.             let ticket = getTicket (fun x -> x.QRCode = qrCode) event
  227.  
  228.             Ok (Option.isSome ticket)
  229.     | _ -> Error "Wrong state"
  230.  
  231. let applyCommand command eventState =
  232.     match eventState, command with
  233.     | SellTicketEvent event, AddTicket owner ->
  234.         let ticket = createTicket event.Name owner
  235.  
  236.         Ok (true, SellTicketEvent (addTicket ticket event))
  237.  
  238.     | SellTicketEvent event, RemoveTicket owner ->
  239.         let ticket = getTicket (fun x -> x.Owner = owner) event
  240.  
  241.         match ticket with
  242.         | Some t -> Ok (true, SellTicketEvent (removeTicket t event))
  243.         | None -> Error "Alarm! impossible case"
  244.  
  245.     | RunEvent (event, peopleCount), Scan qrCode ->
  246.         if peopleCount > 1000u then
  247.             Error "to many people"
  248.         else                      
  249.             let ticket = getTicket (fun x -> x.QRCode = qrCode) event
  250.  
  251.             Ok ((Option.isSome ticket), eventState)
  252.  
  253.     | _ -> failwith "not ok"
  254.  
  255.  
  256. [<EntryPoint>]
  257. let main argv =
  258.     //let testSaga =
  259.     //    [SagaEvent.SagaForwardCommandAdded ^ Forward ()
  260.     //     SagaEvent.SagaForwardCommandAdded ^ Forward ()
  261.     //     SagaEvent.Started
  262.     //     SagaEvent.Forwarded
  263.     //     SagaEvent.ForwardFailed
  264.     //     SagaEvent.Backwarded
  265.     //     SagaEvent.BackwardFailed]
  266.     //    |> playEvents initSaga
  267.    
  268.     //printf "%A" testSaga
  269.  
  270.     let sellTicketEvent =
  271.         SellTicketEvent {
  272.             Name = NoneEmptyString.create "F#"
  273.             StartDate = DateTime.UtcNow
  274.             EndDate = DateTime.UtcNow
  275.             TotalTicketCound = 10u
  276.             SoldTickets = []
  277.         }
  278.  
  279.     let addTicket = applyCommand (EventCommand.AddTicket (NoneEmptyString.create "me")) sellTicketEvent
  280.  
  281.     printf "%A" addTicket
  282.  
  283.     Console.ReadKey() |> ignore
  284.     0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement