【问题标题】:Understanding send/suspend/dispatch in Racket Web Framework了解 Racket Web 框架中的发送/挂起/调度
【发布时间】:2015-03-17 12:41:39
【问题描述】:

我正在尝试理解与 Racket Web 框架教程 http://docs.racket-lang.org/continue/ 中的发送/暂停/调度代码相关的示例。

为了方便起见,这里是让我困惑的代码:

#lang web-server/insta
; start: request -> response
   (define (start request)
      (show-counter 0 request))

; show-counter: number request -> doesn't return
; Displays a number that's hyperlinked: when the link is pressed,
; returns a new page with the incremented number.
(define (show-counter n request)
  (local [(define (response-generator embed/url)
            (response/xexpr
             `(html (head (title "Counting example"))
                    (body
                     (a ((href ,(embed/url next-number-handler)))
                        ,(number->string n))))))

          (define (next-number-handler request)
            (show-counter (+ n 1) request))]

    (send/suspend/dispatch response-generator)))

我有两个问题:

(最重要的)embed/url 定义在哪里?我看不出它是在这段代码中定义的,但我对延续的理解是基本的,所以我可能遗漏了一些东西。

本地化的目的是什么?我可以删除它,代码似乎也能正常工作。

【问题讨论】:

  • 在某些用于 Racket 内部定义的#langs 中是不允许的。所以使用local。它类似于let
  • 正如 Rptx 所写,在这种情况下 local 可以省略。很明显,response-generator 是一个本地函数(因此它可以关闭值 n 和 request。

标签: webserver scheme racket


【解决方案1】:

函数 embed/url 是 response-generator 的参数:

(define (response-generator embed/url) ...)

当评估(send/suspend/dispatch response-generator) 时,会发生以下情况:

1. a procedure `p` given a "continuation" (here next-number-handler)" 
   generates an url
2. the function `response-generator` is called with `p` as argument.
3. the page `(html ... ,(embed-url next-number-handler)) is generated
   (note: (embed-url next-number-handler) calls `p` and the resulting url is inserted into the page)

4. [send]     the page is sent to the client
5. [suspend]  the server suspends the program
6. [dispatch] receives an request generated by clicking link whose url were
              generated in 3.  The handler associated to the url 
              (here next-number-handler) is looked up, and the handler 
              is called.

虽然没有必要使用send/suspend/dispatch,但这里有一个草图:

(define (send/suspend/dispatch response-generator )
  (let/ec escape
    (define (callback->url callback)
      (let/ec return-url
        (escape (callback (send/suspend return-url)))))
    (send/back (response-generator callback->url))))

【讨论】:

  • 所以我想我现在更接近了。如果 embed/url 是 response-generator 的参数,那么当 send/suspend/dispatch 运行时,它会从 send/suspend/dispatch 中提供给 response-generator。也许我不明白发送/暂停/调度是如何运作的。 send/suspend/dispatch 是否捕获延续 - 如果是,它是如何做到的(大致)?
  • 它或多或少使用了 call/cc。在实践中,它捕获了一个定界的延续。它如何捕获它的延续与使用发送/暂停/调度无关。不过这很有趣,所以如果您好奇,请参阅论文 ccs.neu.edu/racket/pubs/hosc07-sk-mf.pdfrepository.readscheme.org/ftp/papers/sw2003/WebUI.pdf
  • 我同意你的观点,我不需要理解这一点就可以使用它。至少现在我对正在发生的事情有了更好的心理形象。谢谢,
猜你喜欢
  • 2020-03-31
  • 1970-01-01
  • 2013-03-19
  • 2021-11-13
  • 1970-01-01
  • 2017-02-10
  • 2021-07-17
  • 1970-01-01
  • 2016-03-22
相关资源
最近更新 更多