I have a socket server that needs to run on a loop accepting clients, so I found out that in funcional programming, a recursive loop is used:
let awaitConnections (wsl:WebSocketListener) =
let rec loop ()=
async {
let! ws = Async.AwaitTask (wsl.AcceptWebSocketAsync(cancellation.Token) )
printfn "Connection from %s" (ws.RemoteEndpoint.Address.ToString())
Async.Start <| awaitMessages ws
do! loop()}
loop()
And this code is invoked by doing:
Async.Start <| awaitConnections listener
Considering that the app runs continuously, should I use a iterative approach instead? Does the rec
approach creates nested execution stacks?
Also, I would like to do something after the loop ends, like:
let awaitConnections (wsl:WebSocketListener) =
let rec loop ()=
async {
let! ws = Async.AwaitTask (wsl.AcceptWebSocketAsync(cancellation.Token) )
printfn "Connection from %s" (ws.RemoteEndpoint.Address.ToString())
Async.Start <| awaitMessages ws
do! loop()}
loop()
printf "The loop ended" // <-- this line
But then it cannot compile because the awaitConnections
return type. How could I do that? Am I doing this right?
You're certainly on the right track! Here is a simple example that demonstrates what you need to do:
// Loop that keeps running forever until an exception happens
let rec loop () = async {
do! Async.Sleep(1000)
printfn "Working"
return! loop () }
// Call the loop in a try .. finally block to run some cleanup code at the end
let main () = async {
try
do! loop ()
finally
printfn "That's it!" }
// Start the work in the background and create a cancellation token
let cts = new System.Threading.CancellationTokenSource()
Async.Start(main (), cts.Token)
// To cancel it, just call: cts.Cancel()
A few important points:
You cannot really run code after an infinite loop finishes (it is infinite!) but you can use try .. finally
to run some code when the block is cancelled
Note that using return!
for recursive looping is better - using do!
creates memory leaks.
You can cancel computation using cancellation token - just pass the token when starting it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With