emacs+Slime下调用cl-json解析大文件出现远端连接中断问题咨询
错误产生原因
- 该错误和JSON解析逻辑本身无关,是Slime通信层的默认参数限制导致:Slime通过Emacs和后台运行的Swank服务(SBCL进程内运行)跨进程通信完成交互,默认Swank的通信缓冲区大小上限远低于14M JSON解码后生成的Lisp对象的序列化体积,大对象传输时直接触发通信层强制断连,才会抛出
Connection broken by remote peer错误。 - 终端直接运行的SBCL没有跨进程通信回传结果的步骤,所以可以正常执行。
解决方案
方案1:调整Swank通信缓冲区上限
如果你是从Emacs内直接启动Slime,在Emacs配置文件中添加如下配置后重启Emacs生效:(setq slime-net-coding-system 'utf-8-unix slime-contribs '(slime-fancy) swank:*communication-buffer-size* (* 128 1024 1024))如果你是手动启动SBCL的Swank服务再用Emacs连接,在启动Swank前执行如下Common Lisp代码:
(setf swank:*communication-buffer-size* (* 128 1024 1024))上面的配置将缓冲区上限调整为128M,可满足14M JSON文件的解码结果传输需求。
方案2:避免大对象回显到Slime REPL
绝大多数情况下触发该问题是因为直接执行解析代码后,Slime会尝试把整个解析结果序列化后传回Emacs的REPL打印。可以将解析结果绑定到变量后不返回大对象,即可绕过传输限制:(let ((json-result (cl-json:decode-json-from-source (pathname "/path/to/test.json"))) ;; 在这里编写你的业务逻辑处理json-result ) nil) ;; 最终只返回nil到REPL,不会触发大对象传输方案3:使用流式JSON解析
如果需要处理的JSON文件体积会持续增大,建议改用流式解析方案,无需一次性加载全量JSON生成大对象,从根源上避免该问题,可选用yason等支持流式解析的JSON处理库实现。
内容的提问来源于stack exchange,提问作者C-Entropy
相关产品推荐
相关产品推荐

