简体   繁体   中英

How to query for the MailboxProcessor state?

What I want to implement is to have an agent responsible for manipulating the Map of items. Thats an easy party, but now Im wondering how can a query on that Map ?

Take a look at this code:

(* APPLIACATION STATE *)
let rec timeTable = Map.empty<string, TimeTableEntry>

let timeTableAgent = new TimeTableAgent(fun inbox -> 
   (* Internal functions *)
    let validateCronExpr task = 
        try
            task.CronExpr |> CrontabSchedule.Parse |> Success
        with | ex -> Failure "Cron expression is invalid."

    let rec schedule (timeTable : Map<string, TimeTableEntry>) (entry : TimeTableEntry) = 
        match validateCronExpr(entry) with
        | Failure err -> Failure err
        | Success _ -> match timeTable.ContainsKey(entry.Name) with
                       | false ->
                            let timeTable = timeTable.Add(entry.Name, entry)
                            Success "Task has been scheduled."
                       | true -> Failure "Task already exists."


   (* message processing *)
    let rec messageLoop (timeTable : Map<string, TimeTableEntry>) = 
        async {
            let! message = inbox.Receive()

            match message with
            | Command.Schedule (entry, reply) ->
                 let timeTable = timeTable.Add(entry.Name, entry)
                 reply.Reply(schedule timeTable entry)
            | Command.RecalculateOccurance (key, reply) -> reply.Reply(Success("OK"))
            | Command.UnSchedule (key, reply) -> reply.Reply(Success("OK"))

            return! messageLoop timeTable
     }

    // start the loop
    messageLoop timeTable
   )
timeTableAgent.Start()

let task = { Name = ""; CronExpr = "* * * * *"; Job = FileName("");    NextOccurance = DateTime.Now }


let messageAsync = timeTableAgent.PostAndAsyncReply(fun replyChannel -> Command.Schedule(task, replyChannel))

so now I would like to do something like this:

printf "%i" timeTable.Count

timeTable |> Map.iter (fun k v -> printf "%s" v.Name) 

but the item count is 0 and the query does not return anything :(

I know that the state of the timetable is immutable, but I remember it is possible to just replace the immutable vars with the new instances....

Could someone help me on this, please ?

Taking your example above you could do the following.

In the agents message handler look add another command

(** Previous match clauses **)
| Command.GetCount(reply) -> 
    reply.Reply(timeTable.Count)

you can then use the command to query for that view of the agents state

let timeTableCount = timeTableAgent.PostandReply(Command.GetCount)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM