Add Producer.retry

This implementation allows API consumers the choice of retry strategy without being overly burdensome.

Resolves #1046.
This has to do with the limitations of recursive closures/nested functions. It just seemed simpler to factor it out into a separate method.