Make run loop more resilient to delays in timer actions
Make run loop more resilient to delays in timer actions

The run loop will try to run each timer at it's specified period, even
if the timer's action takes a significant amount of time. The period
is measured from the start of the task, rather than the end.

For example, with an action that takes 1 second to complete, and is
scheduled with a timer that has a period of 2 seconds:

Before:

    ##########                    ##########
    # action #                    # action #
    ##########                    ##########

    <-- 1s --><------- 2s -------><-- 1s -->
    <------------- 3s ----------->

After:

    ##########          ##########
    # action #          # action #
    ##########          ##########

    <-- 1s -->          <-- 1s -->
    <------- 2s ------->

furbrain/tingbot-python