(сейчас предпочитаю регистрироваться как ivan4th, но на мой e-mail на сайте
осталась старая регистрация, как fionbio).
Андрей, я уже писал в письме, что, на мой взгляд, с самой идеей
использовать walker есть некоторые проблемы. Одна из них - то,
что обрабатываться будет только тело маршрута. Допустим, если
я сделаю функцию вроде
(defun load-object (param-name)
(alet ((x (do-something)))
...
(load-something-async (restas:post-parameter param-name)))), а затем вызову её из маршрута, то получу проблемы, т.к. walker
эту функцию не обрабатывает. Можно, конечно, добавить сюда
свой defun, но это, на мой взгляд, уже слишком. Не говоря уже
про прочие проблемы walker'ов - например, в iterate под CCL
не работают assert'ы из-за сложностей со special forms, а для
отладчика блоки iterate являются единым целым, что не слишком
урощает отладку. iterate я всё равно ценю и активно использую,
но не хотелось бы умножения подобного кода с трудностями.
Я в письме тебе предлагал уже альтернативный способ,
связанный с оборачиванием callback'ов для futures (promises
в blackbird). Я форкнул blackbird и реализовал там эту
фичу, отправлю позже pull request автору - https://github.com/ivan4th/blackbird
Ключевой коммит:
https://github.com/ivan4th/blackbird/commit/12b083519273ae79e7563e48ec8463fe1e41bb2b
Пример использования:
(defpackage :blackbird-special-vars
(:use :cl :alexandria))(in-package :blackbird-special-vars)(defun dbg (fmt &rest args)
(let ((*print-readably* nil))
(format *debug-io* "~&;; ~?~%" fmt args)))(defun aprint (future)
(asf:attach future
#'(lambda (&rest values)
(format t "values=~{~a~^ ~}" values))))(defvar *my-var* nil)
(pushnew '*my-var* bb:*promise-keep-specials*)(defun some-db-request ()
(let ((promise (bb:make-promise)))
(as:with-delay (0.1)
(bb:finish promise 100))
promise))(defun get-my-var () *my-var*)(defun some-func ()
(let ((*my-var* 42))
(bb:alet ((x (some-db-request)))
(when x (* *my-var* x)))))В repl (при использовании cl-async-repl) это выглядит так
(тут у меня сломалась вставка кода в сообщении форума):
BLACKBIRD-SPECIAL-VARS> (aprint (some-func))
#<BLACKBIRD:PROMISE callback(s): 0 errback(s): 0 finished: NIL forward: NIL {100F334723}>
values=4200
Caveat - эта штука работает только с promises, для
того же as:with-delay и других не-promise-асинхронных-примитив
она не сработает. Но, насколько я понимю, тут
мы исходим именно из работы с promises (ранее futures).