2014-10-31 60 views
2

应用程序交付的所有基本示例都显示了如何用自己的代替顶层函数。一旦该功能完成,应用程序退出。我想知道为长期运行的应用程序创建顶层函数的最佳方法是什么。我的代码是应用程序在Clozure中交付长时间运行的应用程序CL

(ql:quickload :my-app) 

(defun main() 
    (swank:create-server :dont-close t) 
    (my-app:start-server) ; Essentially creates a hunchentoot handler and returns 
    (loop for x = (read-line) 
    when (string= x "q") do (quit) 
    do (format t "Type q to quit~%" x))) 

(save-application "my-app" :toplevel-function #'main :prepend-kernel t) 

有没有更好的方法?我不喜欢循环,但是释放终端的东西也可以。

+1

释放终端必然是平台(OS)特定的。你在哪个平台上运行你的应用程序?另外,请澄清你的“更好的方式”的定义。您认为最佳的主要功能是什么? – jlahd 2014-10-31 07:38:03

+0

“更好的方式”是主观的我猜。我真正的意思是惯用/最佳实践,甚至是改进代码的建议。是否有必要有一个循环做一个阻塞的读线或有其他方式不能退出?我正在OSX上开发,不确定终端是否可用。 – 2014-10-31 16:51:56

回答

1

正如你所说,一旦主要功能完成,应用程序就会退出。 Ergo,你需要保持该功能运行,直到你想退出应用程序。

最简单的解决方法就是离开主回路中的sleep一个无限循环:

(defun main() 
    (swank:create-server :dont-close t) 
    (my-app:start-server) 
    (loop (sleep 60))) 

当你开始一个斯旺克服务器,你可能要包括的功能,通过一个泥干净地退出应用程序连接。你可以,例如,喜欢写东西下面,使用bt-semaphore包:

(defvar *quit-my-app* (bt-semaphore:make-semamphore)) 

(defun main() 
    (swank:create-server :dont-close t) 
    (my-app:start-server) 
    (bt-semaphore:wait-on-semaphore *quit-my-app*) 
    (my-app:clean-up)) ; or whatever you need to do for cleaning up 

(defun quit-my-app() 
    (bt-semaphore:signal-semaphore *quit-my-app*)) 

现在你可以粘液连接上简单地评价(quit-my-app)关闭应用程序。

您也可以使用主线程进行维护工作。在我的服务器上,我执行简单的日志循环:

(defun seconds-until-tomorrow() 
    (multiple-value-bind (second minute hour day month year daylight-p zone) 
     (decode-universal-time (+ (get-universal-time) (* 60 60 26))) ; safely tomorrow 
    (declare (ignore second minute hour daylight-p)) 
    (- (encode-universal-time 0 0 0 day month year zone) 
     (get-universal-time)))) 

(defun main() 
    (swank:create-server :dont-close t) 
    (let (cur-logfile 
     cur-logfile-name 
     ;; assuming that start-server returns the Hunchentoot acceptor 
     (acpt (my-app:start-server))) 
    (loop 
     (let* ((lf-stem (log-file-name)) 
       (logfile-name (merge-pathnames lf-stem *temp-path*)) 
       (new-logfile (open logfile-name :direction :output 
               :if-exists :append 
               :if-does-not-exist :create))) 

     (setf (hunchentoot:acceptor-message-log-destination acpt) new-logfile 
       (hunchentoot:acceptor-access-log-destination acpt) new-logfile) 

     (when cur-logfile 
      (close cur-logfile) 
      (run-program "/usr/bin/xz" (list (princ-to-string cur-logfile-name)))) 

     (setf cur-logfile new-logfile 
       cur-logfile-name logfile-name) 

     (when (bt-semaphore:wait-on-semaphore *quit-my-app* (seconds-until-tomorrow)) 
      (return))))) 
相关问题