2014-10-31 82 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))))) 
相關問題