docs: def schedule_recurring(interval, target=None, maxtimes=0, starting_at=0,
                         args=(), kwargs=None):
      """insert a greenlet into the scheduler to run regularly at an interval
  
      If provided a function, it is wrapped in a new greenlet
  
      :param interval: the number of seconds between invocations
      :type interval: int or float
      :param target: what to schedule
      :type target: function or greenlet
      :param maxtimes: if provided, do not run more than ``maxtimes`` iterations
      :type maxtimes: int
      :param starting_at:
          the unix timestamp of when to schedule it for the first time (defaults
          to the time of the ``schedule_recurring`` call)
      :type starting_at: int or float
      :param args: arguments for the function
      :type args: tuple
      :param kwargs: keyword arguments for the function
      :type kwargs: dict or None
  
      :returns: the ``target`` argument
  
      This function can also be used as a decorator:
  
      >>> @schedule_recurring(30)
      >>> def f():
      ...     print "the regular 'hello' from f"
  
      and args/kwargs can also be preloaded:
  
      >>> @schedule_recurring(30, args=('world',))
      >>> def f(name):
      ...     print 'the regular hello %s' % name
      """
      starting_at = starting_at or time.time()
  
      if target is None:
          def decorator(target):
              return schedule_recurring(
                  interval, target, maxtimes, starting_at, args, kwargs)
          return decorator
  
      func = target
      if isinstance(target, compat.greenlet) or target is compat.main_greenlet:
          if target.dead:
              raise TypeError("can't schedule a dead greenlet")
          func = target.run
  
      def run_and_schedule_one(tstamp, count):
          # pass in the time scheduled instead of just checking
          # time.time() so that delays don't add up
          if not maxtimes or count < maxtimes:
              tstamp += interval
              func(*args, **(kwargs or {}))
              schedule_at(tstamp, run_and_schedule_one,
                          args=(tstamp, count + 1))
  
      firstrun = starting_at + interval
      schedule_at(firstrun, run_and_schedule_one, args=(firstrun, 0))
  
      return target