Is this "server loop" actually tail recursive!?

26 views
Skip to first unread message

Tim Watson

unread,
Feb 28, 2016, 5:54:11 PM2/28/16
to cloud-haskel...@googlegroups.com, distribut...@googlegroups.com, parallel-haskell
Hi all,

Possibly the wrong place to ask (as this is quite a general Haskell question), but it's quite specific to Cloud Haskell (and quite important too), so I'm going out on a limb...

I've implemented Erlang's gen_server, generic server behaviour for Cloud Haskell. This is a core Erlang behaviour, used to ensure that processes which reside in supervision trees behave in a consistent manner. You're not forced to only use gen_server processes in supervision trees, but you've got to follow the "contract" or they don't work properly, and using gen_server has a lot of other advantages too....

Anyway, gen_server (or Managed Process, as it's called in Cloud Haskell) is based on a generic "server loop" that deals with the message receiving and replying parts of a process, whilst your code focusses on the "business logic" (if you like), and that server loop is a recursive constant process.

I'm a little concerned that *my* server loop might not be tail recursive, since I've had bug reports of "large message payloads don't get delivered" which could either be a network-transport bug, or simply my code is wrong and runs out of stack space...

This could be quite horrible, since supervisor itself is a gen_server (see https://github.com/haskell-distributed/distributed-process-supervisor/blob/master/src/Control/Distributed/Process/Supervisor.hs#L729), as are most of the other important capabilities built in the platform libraries! 

How do I check to see if my code is tail recursive? Is there some flag I can pass to ghc (cabal, stack, whatever) to look at intermediate code and find out?

Please don't tell me I should be using the monadic `forever $ do' construct instead - whilst this may be true, handling the ongoing state would be problematic, and besides my code has to evaluate to a value eventually, once the server process terminates (in the case where it doesn't crash) so that's not an option afaict.


There's a secondary implementation at https://github.com/haskell-distributed/distributed-process-client-server/blob/master/src/Control/Distributed/Process/ManagedProcess/Internal/GenProcess.hs#L47 which deals with prioritising messages, which is actually what the supervisor code is using... 

Any pointers in the right direction would be hugely appreciated!!!

Cheers,
Tim

Boespflug, Mathieu

unread,
Feb 29, 2016, 2:59:56 AM2/29/16
to Tim Watson, cloud-haskel...@googlegroups.com, distribut...@googlegroups.com, parallel-haskell
recvLoop looks tail recursive to me. Is there any particular part of
the definition that's making you worry it might not be? Regarding the
"large message payloads" issue, I doubt this would be due to blowing
the stack. It's usually fairly obvious to diagnose that, since GHC
will say something to the effect of "stack overflow". Have you made
sure you're not being hit by
https://github.com/kolmodin/binary/pull/76? Make sure you're using at
least binary-0.7.5...
--
Mathieu Boespflug
Founder at http://tweag.io.
> --
> You received this message because you are subscribed to the Google Groups
> "cloud-haskell-developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to cloud-haskell-deve...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Alexander V Vershilov

unread,
Feb 29, 2016, 3:26:50 AM2/29/16
to Tim Watson, cloud-haskel...@googlegroups.com, distribut...@googlegroups.com, parallel-haskell
Hi, Tim.

recvLoop - looks entirely tail recursive for me, and should run in
O(1) stack space,
though it's not obvious for me that process's state will be evaluated
and will not keep
thunks. It may depend on the actual state that user carry around.

Neil Mitchell wrote about nice approach for detecting space leaks that should
work in this example:

http://neilmitchell.blogspot.ru/2015/09/detecting-space-leaks.html
> --
> You received this message because you are subscribed to the Google Groups
> "cloud-haskell-developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to cloud-haskell-deve...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Alexander

Tim Watson

unread,
Feb 29, 2016, 7:28:04 AM2/29/16
to Alexander V Vershilov, cloud-haskel...@googlegroups.com, distribut...@googlegroups.com, parallel-haskell
Awesome, thanks for taking a look Alexander!

Tim Watson

unread,
Feb 29, 2016, 7:28:39 AM2/29/16
to Boespflug, Mathieu, cloud-haskel...@googlegroups.com, distribut...@googlegroups.com, parallel-haskell
Thanks for pointing out the binary issue Mathieu - I'll double check that, and appreciate both you and Alexander taking a look at the code! 

Cheers,
Tim
Reply all
Reply to author
Forward
0 new messages