src/middleware/session.lisp @ 743c0a981785
Oh boy, here we go...
Finally getting back to poking at this. Apparently my Common Lisp has gotten
better in the past six months because good lord this code looks bad now.
Anyway, a few changes:
* Make it run on CCL by working around a usocket bug.
* Remove the workaround hacks. It's never gonna work with Fireplace anyway.
* Make the socket stream once instead of on every read/write so the GC doesn't hate us.
author |
Steve Losh <steve@stevelosh.com> |
date |
Sat, 09 Apr 2016 20:42:34 +0000 |
parents |
15af562c7bca |
children |
9d3d9514dbd8 |
(in-package #:nrepl)
(defvar *sessions* (make-hash-table :test #'equal))
(defvar *session* nil)
(defun clear-sessions! ()
(setf *sessions* (make-hash-table :test #'equal)))
(defun create-session ()
(fset:empty-map))
(defun register-session! (id session)
(setf (gethash id *sessions*) session))
(defun remove-session! (id)
(remhash id *sessions*))
(defun get-session (id)
(gethash id *sessions*))
(defun get-sessions ()
(hash-keys *sessions*))
(defun wrap-session (h)
"Handle wrapping incoming messages in sessions.
If a message contains a session key, look up that session in the list of
registered sessions and bind it into *session*.
If a message comes in without a session id, create a new session for it and
patch the session id into the message before continuing on down the
middleware stack. Also binds the session into *session*. Note that this
will NOT register the session into the main map of sessions.
"
(lambda (message)
(let* ((session-id (fset:lookup message "session"))
(session (if session-id
(get-session session-id)
(create-session)))
(session-id (or session-id (random-uuid)))
(*session* session))
(funcall h (fset:with message "session" session-id)))))
(define-middleware wrap-session-ls "ls-sessions" message
(respond message
(make-map "status" '("done")
"sessions" (get-sessions))))
(define-middleware wrap-session-close "close" message
(remove-session! (fset:lookup message "session"))
(respond message (make-map "status" '("session-closed"))))
(define-middleware wrap-session-clone "clone" message
(let ((new-id (register-session! (random-uuid)
(fset:lookup message "session"))))
(respond message (make-map "status" '("done") "new-session" new-id))))