F# Server side programming
Dave Thomas
MoiraeSoftware.com
twitter.com/7sharp9
F# Server based programming
Why F#
• Concise succinct code
• Advanced asynchronous support
• Language Orientated Programmi...
Fundamental Concepts
• Pure Functions
– No side effects
– memoization
• Immutability
– No threading issues
• Lambda expres...
Patterns and Practices
C#
• Inheritance
• Polymorphism
F#
• Higher order functions
• Type augmentation
Patterns / similarities
• Discriminated unions -> Small class hierarchies
• Higher Order Functions -> Command Pattern
• Fo...
A comparison of styles
F#
• 1 source file
• 43 lines
• 2 types
C#
• 2 source files
• 166 lines
• 2 type
75% reduction in c...
C# ObjectPool
F# ObjectPool
//Agent alias for MailboxProcessor
type Agent<'T> = MailboxProcessor<'T>
///One of three messages for our Ob...
F# - Fracture IO
Open source high performance
Socket, Pipeline, and agent library
Sockets
2 Models of Operation
• AsyncResult Model
• SocketAsyncEventArgs Model
IAsyncResults Model
Pros
• Well documented API
• Can be simplified with helpers in
Asynchronous workflows in F#
• Fast to ...
F# AsyncResult
SocketAsyncEventArgs Model
Pros
• Less memory allocations
• Better performance
• Closer to the metal
Cons
• Not a well und...
Performance Differences
• 5 minute test
• 50 clients connecting to
the server
• 15ms interval between
each one
• Server se...
CPU & Threads
SocketAsyncEventArgs IAsyncResult
Memory
SocketAsyncEventArgs IAsyncResult
Garbage collection
SocketAsyncEventArgs IAsyncResult
Fracture Socket Implementation
Agents
• Provide a message passing mechanism
• Agents read and respond to a queue of
messages
• Typically a discriminated ...
Introducing Fracture-IO
• High performance Socket library
• Highly compositional pipeline library
Pipelines
• Closed Pipelines
– Tomas Petricek
• Image Processing Pipeline
• Open Pipelines
– Pipelets
Closed Pipelines
Image Processing Pipeline
1: // Phase 1: Load images from disk and put them into a queue
2: letloadImages=async {
3: letcl...
Open Pipelines
Advantages
• Composability
• Reusability
• Can be used at any stage of processing
• Separation of concerns
...
Pipelets Implementation
Pipelets in use
Future Directions
• Distributed Pipelets
– Wave Pipelines
– Synchronous buffered Pipeline
• Advanced agent based programmi...
Upcoming SlideShare
Loading in …5
×

F# Server-side programming

2,195 views

Published on

An F# presentation that I done a few years ago.

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,195
On SlideShare
0
From Embeds
0
Number of Embeds
101
Actions
Shares
0
Downloads
14
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

F# Server-side programming

  1. 1. F# Server side programming Dave Thomas MoiraeSoftware.com twitter.com/7sharp9
  2. 2. F# Server based programming Why F# • Concise succinct code • Advanced asynchronous support • Language Orientated Programming • Generic by default • Immutable by default
  3. 3. Fundamental Concepts • Pure Functions – No side effects – memoization • Immutability – No threading issues • Lambda expressions • Higher order functions • Recursion
  4. 4. Patterns and Practices C# • Inheritance • Polymorphism F# • Higher order functions • Type augmentation
  5. 5. Patterns / similarities • Discriminated unions -> Small class hierarchies • Higher Order Functions -> Command Pattern • Fold -> Visitor pattern
  6. 6. A comparison of styles F# • 1 source file • 43 lines • 2 types C# • 2 source files • 166 lines • 2 type 75% reduction in code
  7. 7. C# ObjectPool
  8. 8. F# ObjectPool //Agent alias for MailboxProcessor type Agent<'T> = MailboxProcessor<'T> ///One of three messages for our Object Pool agent typePoolMessage<'a> = | Get ofAsyncReplyChannel<'a> | Put of 'a | Clear ofAsyncReplyChannel<List<'a>> /// Object pool representing a reusable pool of objects typeObjectPool<'a>(generate: unit -> 'a, initialPoolCount) = let initial = List.initinitialPoolCount (fun (x) -> generate()) let agent = Agent.Start(fun inbox -> letrecloop(x) = async { let!msg = inbox.Receive() matchmsgwith | Get(reply) -> let res = matchxwith | a :: b-> reply.Reply(a);b | [] as empty-> reply.Reply(generate());empty return!loop(res) | Put(value)-> return!loop(value :: x) | Clear(reply) -> reply.Reply(x) return!loop(List.empty<'a>) } loop(initial)) /// Clears the object pool, returning all of the data that was in the pool. memberthis.ToListAndClear() = agent.PostAndAsyncReply(Clear) /// Puts an item into the pool memberthis.Put(item ) = agent.Post(item) /// Gets an item from the pool or if there are none present use the generator memberthis.Get(item) = agent.PostAndAsyncReply(Get)
  9. 9. F# - Fracture IO Open source high performance Socket, Pipeline, and agent library
  10. 10. Sockets 2 Models of Operation • AsyncResult Model • SocketAsyncEventArgs Model
  11. 11. IAsyncResults Model Pros • Well documented API • Can be simplified with helpers in Asynchronous workflows in F# • Fast to get an initial result Cons • Allocation of IAsyncResult on every Operation • Consumes more CPU for each send and receive operation
  12. 12. F# AsyncResult
  13. 13. SocketAsyncEventArgs Model Pros • Less memory allocations • Better performance • Closer to the metal Cons • Not a well understood or documented API • Can be complex to get right
  14. 14. Performance Differences • 5 minute test • 50 clients connecting to the server • 15ms interval between each one • Server sends each client a 128 byte message every 100ms • Total of 500 messages per second Test Harness
  15. 15. CPU & Threads SocketAsyncEventArgs IAsyncResult
  16. 16. Memory SocketAsyncEventArgs IAsyncResult
  17. 17. Garbage collection SocketAsyncEventArgs IAsyncResult
  18. 18. Fracture Socket Implementation
  19. 19. Agents • Provide a message passing mechanism • Agents read and respond to a queue of messages • Typically a discriminated union is used to describe messages
  20. 20. Introducing Fracture-IO • High performance Socket library • Highly compositional pipeline library
  21. 21. Pipelines • Closed Pipelines – Tomas Petricek • Image Processing Pipeline • Open Pipelines – Pipelets
  22. 22. Closed Pipelines
  23. 23. Image Processing Pipeline 1: // Phase 1: Load images from disk and put them into a queue 2: letloadImages=async { 3: letclockOffset=Environment.TickCount 4: letrec numbers n=seq { yieldn; yield! numbers (n+1) } 5: for count, imginfileNames|>Seq.zip (numbers 0) do 6: let info =loadImageimgsourceDir count clockOffset 7: do!loadedImages.AsyncAdd(info) } 8: 9: // Phase 2: Scale to a thumbnail size and add frame 10: letscalePipelinedImages=async { 11: whiletruedo 12: let! info =loadedImages.AsyncGet() 13: scaleImage info 14: do!scaledImages.AsyncAdd(info) } 1: letloadedImages=newBlockingQueueAgent<_>(queueLength) 2: letscaledImages=newBlockingQueueAgent<_>(queueLength) 3: letfilteredImages=newBlockingQueueAgent<_>(queueLength) 1: // Phase 4: Display images as they become available 2: letdisplayPipelinedImages=async { 3: whiletruedo 4: let! info =filteredImages.AsyncGet() 5: info.QueueCount1 <-loadedImages.Count 6: info.QueueCount2 <-scaledImages.Count 7: info.QueueCount3 <-filteredImages.Count 8: displayImage info } 9: 10: // Start workflows that implement pipeline phases 11: Async.Start(loadImages, cts.Token) 12: Async.Start(scalePipelinedImages, cts.Token) 13: Async.Start(filterPipelinedImages, cts.Token) 14: tryAsync.RunSynchronously(displayPipelinedImages, cancellationToken=cts.Token) 15: with:?OperationCanceledException-> ()
  24. 24. Open Pipelines Advantages • Composability • Reusability • Can be used at any stage of processing • Separation of concerns • Flexible routing arrangements i.e. round robin, multicast, content based routing Disadvantages • Pipeline stages need to be balanced • Developers can have trouble debugging and visualizing
  25. 25. Pipelets Implementation
  26. 26. Pipelets in use
  27. 27. Future Directions • Distributed Pipelets – Wave Pipelines – Synchronous buffered Pipeline • Advanced agent based programming - Supervision - Pooling - Control Messages

×