开始记开发日志,原因很实在:两周之后我自己都想不起来当时为什么那么改。代码里只有结果,没有当时的判断。这篇是最近几天的记录,做了什么事、卡在哪、结论是什么,没解决的也写在后面。

为什么记这个

不是给谁看的。我自己的项目,功能堆得比文档快,很多时候一个决定做完就忘了理由。后来遇到一次,改回三个月前的一个写法,改完才想起当初就是因为那个写法才出的问题,白改一晚上。从那之后开始记,每天几行,写清楚为什么,不写代码。

三个服务搬进子进程

这几天把三个常驻的东西都挪进了 utilityProcess:一个做数据采集,一个跑流程图引擎,一个调系统 API。原因很直接,它们都是 CPU 密集或者会阻塞的活,放主进程里,用户点按钮的时候整个界面就不动了。

搬的过程比想得简单,麻烦的是搬完之后:子进程崩了,主进程收不到明显信号,界面上那个功能就那么静悄悄地没了,用户以为是软件卡住了。得自己接 exit 事件,判断是正常退出还是异常,异常就重启,还要限制重启次数,不然会进入死循环,一直崩一直重启。

结论:子进程不是拆出去就完事,退出事件和重启策略要一起写。

打包后白屏,查了两轮

第一次是打包完给用户装,打开是白屏。开发模式完全正常,我这台机器上也正常,只有全新安装的机器白。查了两轮才定住。

第一轮我怀疑是路径问题,改了半天没效果。第二轮改了个思路,在主进程里把渲染进程的日志接出来,再看它死前说了什么:

win.webContents.on('console-message', (e, level, message, line, sourceId) => {
  log.write(`[renderer] ${message} (${sourceId}:${line})`);
});
win.webContents.on('render-process-gone', (e, details) => {
  log.write(`[gone] reason=${details.reason} exitCode=${details.exitCode}`);
});

日志里一行就露了:preload 里 require 的一个文件,没被打进包里。开发模式能解析到,打包后路径变了,直接找不到模块,渲染进程起不来。

结论:preload 里只做最小初始化,任何可能失败的 require 都别放顶层,改成用到的时候再加载。

VFD 终于不闪了

那块荧光管一直有轻微闪烁,暗环境下看得出来。这次把参数重新算了一遍:一个时隙 830 微秒,12 位扫一遍,一帧 9.96 毫秒,大概 100Hz。之前的问题不是刷新率不够,是定时器中断里干的活太多,主循环一忙,扫描时序就被拖歪,时长时短,看起来就是闪。

改法是中断里只留三件事:查表取段码、切换位选、输出。运算和按键扫描全部挪回主循环,用标志位传值。

结论:中断里只做非做不可的事,其他都挪出去。

采集器的表越来越大

采集器跑久了,那张 URL 表涨得很快,查询越来越慢。我加了分页,也加了归档,现在只查最近 7 天的数据。但这只是缓解,不是解决。

真正的麻烦是历史数据要不要留、留多久、按什么维度汇总。我现在是原样留着,占空间但还能查。以后可能改成按天聚合,原始记录只留 30 天。这个还没想好,先这么跑着。

改了站点上两处措辞

顺手改的。之前文章里写「切位」和「翻缓冲区」,都是我自己压出来的词。读者看不懂,我自己过两个月再看也要想一下。现在统一成「切换位选」和「读缓冲区」。

写技术文容易犯这个毛病,一个概念在心里很清楚,就随手造个短词,觉得省事。但对第一次看的人,那个词是空的。

还没解决的三件事

就记到这。下篇继续。