This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
leftparen / closures.scm
| f8a6c87f » | vegashacker | 2008-09-25 | 1 | #lang scheme/base | |
| 2 | |||||
| 3 | (require (file "util.scm") | ||||
| af0a5496 » | vegashacker | 2009-01-08 | 4 | "web-export.ss" | |
| f8a6c87f » | vegashacker | 2008-09-25 | 5 | (file "web-support.scm") | |
| 6 | (file "settings.scm")) | ||||
| 7 | |||||
| 8 | (provide add-closure! | ||||
| 9 | call-closure | ||||
| 10 | closure-key->url | ||||
| 11 | make-closure-key | ||||
| 12 | body-as-closure-key | ||||
| 13 | body-as-url | ||||
| 14 | handle-closure-in-req | ||||
| 15 | num-closures-in-memory | ||||
| 16 | ) | ||||
| 17 | |||||
| 2a332f6d » | vegashacker | 2009-05-13 | 18 | (define-syntax body-as-closure-key-aux | |
| f8a6c87f » | vegashacker | 2008-09-25 | 19 | (syntax-rules () | |
| 2a332f6d » | vegashacker | 2009-05-13 | 20 | ((_ req-iden key-iden is-sticky-expr body ...) | |
| 21 | (let ((is-sticky is-sticky-expr)) | ||||
| 22 | (add-closure! #:key key-iden | ||||
| 23 | (lambda (req-iden) | ||||
| 24 | ;; first cleanup after itself (if not sticky) | ||||
| 25 | (unless is-sticky (hash-remove! CLOSURES key-iden)) | ||||
| 811ac6b9 » | vegashacker | 2009-04-24 | 26 | ;; then run the actual closure... | |
| 27 | body ...)))))) | ||||
| f8a6c87f » | vegashacker | 2008-09-25 | 28 | ||
| 2a332f6d » | vegashacker | 2009-05-13 | 29 | (define-syntax body-as-closure-key | |
| 30 | (syntax-rules () | ||||
| 31 | ((_ (req-iden #:sticky) body ...) | ||||
| 32 | (let ((key-iden (make-closure-key))) | ||||
| 33 | (body-as-closure-key-aux req-iden key-iden #t body ...))) | ||||
| 34 | ((_ (req-iden key-expr #:sticky) body ...) | ||||
| 35 | (let ((key-iden key-expr)) | ||||
| 36 | (body-as-closure-key-aux req-iden key-iden #t body ...))) | ||||
| 37 | ((_ (req-iden) body ...) | ||||
| 38 | (let ((key-iden (make-closure-key))) | ||||
| 39 | (body-as-closure-key-aux req-iden key-iden #f body ...))) | ||||
| 40 | ((_ (req-iden key-expr) body ...) | ||||
| 41 | (let ((key-iden key-expr)) | ||||
| 42 | (let ((key-iden key-expr)) | ||||
| 43 | (body-as-closure-key-aux req-iden key-iden #f body ...)))))) | ||||
| 44 | |||||
| f8a6c87f » | vegashacker | 2008-09-25 | 45 | ;; | |
| 46 | ;; body-as-url | ||||
| 47 | ;; | ||||
| 2a332f6d » | vegashacker | 2009-05-13 | 48 | ;; Forms: | |
| f8a6c87f » | vegashacker | 2008-09-25 | 49 | ;; (body-as-url (req) body ...) | |
| 50 | ;; (body-as-url (req fn-key) body ...) | ||||
| 2a332f6d » | vegashacker | 2009-05-13 | 51 | ;; (body-as-url (req #:sticky) body ...) | |
| 52 | ;; (body-as-url (req fn-key #:sticky) body ...) | ||||
| 53 | ;; | ||||
| 54 | ;; If fn-key is given, it will be the key used to map to the body. | ||||
| 55 | ;; (This provides a way for the developer to reuse fns in certain situations.) | ||||
| 56 | ;; | ||||
| 57 | ;; If #:sticky appears at the end of the first argument, then the closure will not | ||||
| 58 | ;; be removed form memory after it's invoked (on a server restart, however, all closures | ||||
| 59 | ;; --regardless of stickiness--are cleared). | ||||
| f8a6c87f » | vegashacker | 2008-09-25 | 60 | ;; | |
| 61 | (define-syntax body-as-url | ||||
| 62 | (syntax-rules () | ||||
| 126f8489 » | vegashacker | 2009-05-15 | 63 | ((_ (spec ...) body ...) | |
| 64 | (closure-key->url (body-as-closure-key (spec ...) body ...))))) | ||||
| f8a6c87f » | vegashacker | 2008-09-25 | 65 | ||
| 66 | (define (closure-key->url clos-key) | ||||
| 67 | (format "~A?~A=~A" | ||||
| 68 | (setting *WEB_APP_URL*) | ||||
| 69 | (setting *CLOSURE_URL_KEY*) | ||||
| 70 | clos-key)) | ||||
| 71 | |||||
| 72 | (define-syntax handle-closure-in-req | ||||
| 73 | (syntax-rules () | ||||
| 74 | ((_ req no-closure-body ...) | ||||
| 75 | (let ((url-key (setting *CLOSURE_URL_KEY*)) | ||||
| 76 | (binds (request-bindings req))) | ||||
| 77 | (if (exists-binding? url-key binds) | ||||
| 78 | (call-closure (extract-binding/single url-key binds) req) | ||||
| 79 | (begin no-closure-body ...)))))) | ||||
| 80 | |||||
| 81 | (define CLOSURES (make-hash)) | ||||
| 82 | |||||
| 83 | (define (make-closure-key) | ||||
| 84 | (random-key-string 20)) | ||||
| 85 | |||||
| 86 | ;; returns the key | ||||
| 87 | (define (add-closure! clos #:key (key #f)) | ||||
| 88 | (let ((key (or key (make-closure-key)))) | ||||
| 89 | (hash-set! CLOSURES key clos) | ||||
| 90 | key)) | ||||
| 91 | |||||
| 92 | (define (call-closure key req) | ||||
| 93 | ((hash-ref CLOSURES key (lambda () | ||||
| 94 | (lambda (req) | ||||
| 95 | (format "Expired or missing function '~A'." key)))) | ||||
| 96 | req)) | ||||
| 97 | |||||
| 98 | (define (num-closures-in-memory) | ||||
| 99 | (hash-count CLOSURES)) | ||||








