Common lisp 在CL系统运行时重新编译该系统

Common lisp 在CL系统运行时重新编译该系统,common-lisp,read-eval-print-loop,sbcl,Common Lisp,Read Eval Print Loop,Sbcl,我正在运行一个公共lisp项目,它每5秒获取一次市场数据。我对代码做了一些调整,希望在生产环境中对其进行更新。事件循环实际上是标准的: (loop (fetch-data) (sleep 5)) 由于循环的阻塞性质我没有REPL供我使用 我的问题:我可以动态更新正在运行的代码吗? 我知道我可以使用(asdf:compile system:system name) 我也知道我可以。(并非我在实现中使用类) 然而,现在我不能使用REPL,我必须以某种方式将环境加载到另一个REPL中。有

我正在运行一个公共lisp项目,它每5秒获取一次市场数据。我对代码做了一些调整,希望在生产环境中对其进行更新。事件循环实际上是标准的:

(loop
   (fetch-data)
   (sleep 5))
由于
循环的阻塞性质
我没有REPL供我使用

我的问题:我可以动态更新正在运行的代码吗?

我知道我可以使用
(asdf:compile system:system name)

我也知道我可以。(并非我在实现中使用类)

然而,现在我不能使用REPL,我必须以某种方式将环境加载到另一个REPL中。有办法吗?(我正在使用SBCL)

在我看来,最干净的方法就是实现异步数据获取

由于循环的阻塞性质,我没有REPL供我使用

有很多方法可以解决这个问题:

  • 以自己的方式启动循环
  • 或者在Lisp中连接类似的内容
  • 或者,您的循环可以定期检查代码更新
我也不会在程序内部编译代码,除非您知道代码实际上是编译的,或者您可以处理编译错误。编译和加载通常也比仅仅加载慢

请注意,将代码加载到正在运行的程序中是不标准的。使用SBCL,不仅可以有线程,而且线程可以并发运行。有些更改可能是线程不安全的,或者会导致正在运行的程序出现问题。因此,你需要计划你想要做什么样的改变

有一件事可以简化代码的更改:在循环休眠时加载更新,如果可能的话,在5秒钟的时间内加载更新

有些程序可能需要更多的架构,比如在更新这些部分时关闭部分程序的能力

由于循环的阻塞性质,我没有REPL供我使用

有很多方法可以解决这个问题:

  • 以自己的方式启动循环
  • 或者在Lisp中连接类似的内容
  • 或者,您的循环可以定期检查代码更新
我也不会在程序内部编译代码,除非您知道代码实际上是编译的,或者您可以处理编译错误。编译和加载通常也比仅仅加载慢

请注意,将代码加载到正在运行的程序中是不标准的。使用SBCL,不仅可以有线程,而且线程可以并发运行。有些更改可能是线程不安全的,或者会导致正在运行的程序出现问题。因此,你需要计划你想要做什么样的改变

有一件事可以简化代码的更改:在循环休眠时加载更新,如果可能的话,在5秒钟的时间内加载更新


有些程序可能需要更多的体系结构,比如在程序更新这些部分时关闭部分程序的功能。

不确定这在您的情况下是否会起作用,但我已经非常成功地使用了swank::handle请求在循环中调用,以便使用正在运行的交互式应用程序进行应答:

(defun handle-swank-requests ()
  (let ((connection (or swank::*emacs-connection* 
                        (swank::default-connection))))    
    (when connection      
      (swank::handle-requests connection t))))

(defun main-cycle () 
  (loop
     (restart-case
         (progn
           (handle-swank-requests)
           (fetch-data)
           (sleep  5))
       (continue () :report "Continue" (print "Continued after error from SWANK")))))
重新启动案例构造允许在出现错误时不中断循环,并在修复错误后继续

我不确定这种方法是否可靠,AFAIK swank默认情况下使用线程处理请求,因此可能存在一些同步问题,因此可能不适用于生产使用,也不适用于开发/调试


AFAIK使用了类似的东西,可能是更复杂、更健壮的版本。也很好。

不确定这在您的情况下是否有效,但我已经非常成功地使用了循环中的swank::handle请求调用,用于使用运行的交互式应用程序进行应答:

(defun handle-swank-requests ()
  (let ((connection (or swank::*emacs-connection* 
                        (swank::default-connection))))    
    (when connection      
      (swank::handle-requests connection t))))

(defun main-cycle () 
  (loop
     (restart-case
         (progn
           (handle-swank-requests)
           (fetch-data)
           (sleep  5))
       (continue () :report "Continue" (print "Continued after error from SWANK")))))
重新启动案例构造允许在出现错误时不中断循环,并在修复错误后继续

我不确定这种方法是否可靠,AFAIK swank默认情况下使用线程处理请求,因此可能存在一些同步问题,因此可能不适用于生产使用,也不适用于开发/调试


AFAIK使用了类似的东西,可能是更复杂、更健壮的版本。还不错。

您在哪个平台上运行?你能用Control+C中断并重新编译吗?我用的是SBCL。我知道我可以中断,但这样我的数据会有一个间隙。你是在自己的线程中运行循环吗?我不会在运行的程序中编译代码。我会在其他地方编译它,然后加载编译后的代码。@coredump nope。但我想这是一个解决办法你在哪个站台上跑步?你能用Control+C中断并重新编译吗?我用的是SBCL。我知道我可以中断,但这样我的数据会有一个间隙。你是在自己的线程中运行循环吗?我不会在运行的程序中编译代码。我会在其他地方编译它,然后加载编译后的代码。@coredump nope。但我想这是一个解决办法谢谢请举例说明运行中的程序如何检查自身的更新。可以是非常高级的代码示例。@tsikov:primitive:只需检查某个目录中是否存在fasl文件,如果存在,请加载该文件,然后将其移开……谢谢。请举例说明运行中的程序如何检查自身的更新。可以是非常高级的代码示例。@tsikov:primitive:只需检查某个目录中是否存在fasl文件,如果存在,请加载该文件,然后将其移走。。。