|
- ;;;; src/main.lisp
- ;;;;
- ;;;; Main App Definition And Entry Point
- ;;;;
-
- (in-package :cl-user)
-
- (defpackage #:cl-deck-builder2
- (:use #:cl
- #:cl-deck-builder2.db
- #:cl-deck-builder2.draw
- #:cl-deck-builder2.toolkit
- #:cl-deck-builder2.models
- ;;#:cl-deck-builder2-test
- )
- (:local-nicknames
- (#:v #:org.shirakumo.verbose))
- (:import-from :cl-deck-builder2.config
- :config
- :*app-log-file*)
- (:import-from :clack
- :clackup)
- (:export
- :start
- :stop
- :my/start
- :main)
- (:documentation "The main package for the deck builder project.
-
- This package exports the START and STOP functions, as well as the convenience function MY/START."))
-
- (in-package :cl-deck-builder2)
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (defvar *appfile-path*
- (asdf:system-relative-pathname :cl-deck-builder2 #P"app.lisp")
- "The application path we pass to CLACK:CLACKUP.")
-
- (defvar *clack-handler* nil
- "The CLACK handler currently running. NIL if there is no server running.")
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun start (&rest args &key server port debug &allow-other-keys)
- "Start the app. If the app is already running, raise an ERROR."
- (declare (ignore server port debug))
- (when *clack-handler*
- (restart-case (error "Server is already running.")
- (restart-server ()
- :report "Restart the server"
- (stop))))
- (v:info :main "CLACKUP")
- (setf *clack-handler* (apply #'clackup *appfile-path* args)))
-
- (defun stop ()
- "Stop the app, if it is running."
- (v:info :main "CLACK:STOP")
- (prog1
- (clack:stop *clack-handler*)
- (setf *clack-handler* nil)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun my/start (&rest args)
- "Convenience function for invoking RESTART-SERVER in the case that the server is already running."
- (handler-bind
- ((simple-error (lambda (c)
- (format t "~A~&Invoking RESTART-SERVER." c)
- (invoke-restart 'restart-server))))
- ;; TODO Multiple Addresses?
- ;; TODO Put it behind NGINX?
- ;; TODO sslh?
- (apply #'start args)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Loader Customize
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (defmacro start-helper (service-name &body body)
- `(progn
- (v:info :app "~&Starting ~a ...~&" ,service-name)
- (if ,@body
- (v:info :app "~&... started.~&")
- (v:info :app "~&... failed?~&"))))
-
- ;; Initialize Logging
- ;;
- ;; (v:output-here *standard-output*)
- ;;
- (defun main ()
- (v:output-here (open *app-log-file* :direction :output
- :if-does-not-exist :create
- :if-exists :append))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (v:start v:*global-controller*)
-
- (start-helper "slynk server"
- (apply #'slynk:create-server (config :slynk)))
-
- (v:info :app "~&Constructing database...~&")
- ;; (apply #'create-table *class-list*)
- (ensure-tables-exist)
- (v:info :app "~&...complete~%")
-
- (start-helper "web app"
- (apply #'my/start (config :server)))
-
- (start-helper "WebSocket Server Side Client"
- (handler-case
- (apply #'cl-deck-builder2.web::make-chat-client (config :websocket))
- (usocket:connection-refused-error () nil)
- (usocket:connection-reset-error () nil))))
|