Skip to content

Instantly share code, notes, and snippets.

@panesofglass
Created June 9, 2011 05:33
Show Gist options
  • Select an option

  • Save panesofglass/1016122 to your computer and use it in GitHub Desktop.

Select an option

Save panesofglass/1016122 to your computer and use it in GitHub Desktop.
Updated ObjectPool from fssnip.net/5H
namespace Fracture
/// Agent alias for MailboxProcessor
type Agent<'a> = MailboxProcessor<'a>
/// One of three messages for our Object Pool agent
type PoolMessage<'a> =
| Get of AsyncReplyChannel<'a>
| Count of AsyncReplyChannel<int>
| Put of 'a
| Clear of AsyncReplyChannel<'a list>
/// Object pool representing a reusable pool of objects
type ObjectPool<'a>(generate: unit -> 'a, initialPoolCount, autoGrow) =
let initial = [ for x in 1..initialPoolCount do yield generate() ]
let agent = Agent.Start(fun inbox ->
let rec loop xs = async {
let! msg = inbox.Receive()
match msg with
| Get(reply) ->
let res = match xs with
| hd::tl -> reply.Reply hd; tl
| [] as empty ->
// TODO: Create a state machine that checks the autoGrow argument and blocks additional access if it's full.
//if autoGrow then
reply.Reply (generate())
empty
return! loop res
| Count(reply) ->
reply.Reply xs.Length
return! loop xs
| Put(x)->
return! loop (x::xs)
| Clear(reply) ->
reply.Reply xs
return! loop List.empty<'a> }
loop initial)
/// Creates an object pool that remains at a constant size
new (generate, count) = ObjectPool<'a>(generate, count, false)
/// Returns the number of items checked into the pool
member this.Count() = agent.PostAndAsyncReply(Count)
/// Gets an item from the pool or if there are none present use the generator
member this.Get(item) = agent.PostAndAsyncReply(Get)
/// Puts an item into the pool
member this.Put(item) = agent.Post(Put item)
/// Clears the object pool, returning all of the data that was in the pool.
member this.ToListAndClear() = agent.PostAndAsyncReply(Clear)
@panesofglass
Copy link
Copy Markdown
Author

I added a Count message/method and fixed Put (you forgot to tell agent.Post what type of message you were sending). I also switched out the list initializer to use list comprehensions, which in this case makes it a bit more readable, imho. Finally, I added an overload that could be used in the future to make a blocking version using a state machine.

I'm currently in the process of pushing this into Fracture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment