utils.lisp 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. (in-package #:chatikbot)
  2. (defvar *backoff-start* 1 "Initial back-off")
  3. (defvar *backoff-max* 64 "Maximum back-off delay")
  4. (defun loop-with-error-backoff (func)
  5. (let ((backoff *backoff-start*))
  6. (loop
  7. do
  8. (handler-case
  9. (progn
  10. (funcall func)
  11. (setf backoff *backoff-start*))
  12. (timeout (e)
  13. (log:error e)
  14. (log:info "Backing off for" backoff)
  15. (sleep backoff)
  16. (setf backoff (min *backoff-max*
  17. (* 2 backoff))))))))
  18. (error (e)
  19. (log:error e)
  20. (log:info "Backing off for" backoff)
  21. (sleep backoff)
  22. (setf backoff (min *backoff-max*
  23. (* 2 backoff))))))))
  24. (defun replace-all (string part replacement &key (test #'char=))
  25. "Returns a new string in which all the occurences of the part
  26. is replaced with replacement."
  27. (with-output-to-string (out)
  28. (loop with part-length = (length part)
  29. for old-pos = 0 then (+ pos part-length)
  30. for pos = (search part string
  31. :start2 old-pos
  32. :test test)
  33. do (write-string string out
  34. :start old-pos
  35. :end (or pos (length string)))
  36. when pos do (write-string replacement out)
  37. while pos)))
  38. (defmacro aget (key alist)
  39. `(cdr (assoc ,key ,alist :test #'equal)))