Add Ring.Rpc.Front.to_summary_string to print a quick description of the ring
In the event of an unexpected response ID, log the received and expected IDs
Fix race (leading to corruption and then deadlock) waiting for a free ring slot

For a ring with 'x' slots, it's possible for x + n threads to
 (i) check for a free slot and;
 (ii) return () and block
even though only 'x' slots are available. Each one can then be
scheduled, call 'next_request_id' and write a slot. The 'n' threads
will overwrite slots written by the 'x' threads. Typically this
leads to deadlock since some requests are lost.

To fix, we allocate the 'next_request_id' and return that, instead
of ().