-
Notifications
You must be signed in to change notification settings - Fork 6
/
closures.scm
74 lines (63 loc) · 2.05 KB
/
closures.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#lang scheme/base
(require (file "util.scm")
"web-export.ss"
(file "web-support.scm")
(file "settings.scm"))
(provide add-closure!
call-closure
closure-key->url
make-closure-key
body-as-closure-key
body-as-url
handle-closure-in-req
num-closures-in-memory
)
(define-syntax body-as-closure-key
(syntax-rules ()
((_ (req-identifier) body ...)
(add-closure! (lambda (req-identifier) body ...)))
((_ (req-identifier key-identifier) body ...)
(let ((key-identifier (make-closure-key)))
(add-closure! #:key key-identifier
(lambda (req-identifier) body ...))))))
;;
;; body-as-url
;;
;; (body-as-url (req) body ...)
;; or
;; (body-as-url (req fn-key) body ...)
;; In the latter form, fn-key is the key that will be used to map to body.
;; This provides a way for the developer to reuse fns in certain situations.
;;
(define-syntax body-as-url
(syntax-rules ()
((_ (identifiers ...) body ...)
(closure-key->url (body-as-closure-key (identifiers ...) body ...)))))
(define (closure-key->url clos-key)
(format "~A?~A=~A"
(setting *WEB_APP_URL*)
(setting *CLOSURE_URL_KEY*)
clos-key))
(define-syntax handle-closure-in-req
(syntax-rules ()
((_ req no-closure-body ...)
(let ((url-key (setting *CLOSURE_URL_KEY*))
(binds (request-bindings req)))
(if (exists-binding? url-key binds)
(call-closure (extract-binding/single url-key binds) req)
(begin no-closure-body ...))))))
(define CLOSURES (make-hash))
(define (make-closure-key)
(random-key-string 20))
;; returns the key
(define (add-closure! clos #:key (key #f))
(let ((key (or key (make-closure-key))))
(hash-set! CLOSURES key clos)
key))
(define (call-closure key req)
((hash-ref CLOSURES key (lambda ()
(lambda (req)
(format "Expired or missing function '~A'." key))))
req))
(define (num-closures-in-memory)
(hash-count CLOSURES))