長い時間のsetIntervalの件

2018年4月24日 - 未分類

どうも、Raspberry Piだけに該当するようなバグのようです。setIntervalやsetTimeout、node-shceduleで、30分以上の長い時間間隔にすると、指定時間になっても動作しない。30分以下なら、正しく動作する。とんでもないバグです。解決方法は、10分間隔で、ダミーのsetIntervalを入れること。解決策が分かるまで、時間がかかってしまった。

MacOSXでは、1時間以上長いsetIntervalでも動作するので、Raspberry Pi 固有の問題だと言うことになかなか気が付かなかった。

動作する例

setInterval(function(){ console.log((new Date())},10*60*1000);

動作しない例

setInterval(function(){ console.log((new Date())},60*60*1000);

 

こうすれば、1時間以上でも動作する。

setInterval(function(){ console.log((new Date())},10*60*1000); setInterval(function(){ console.log((new Date())},60*60*1000);

10分間隔の何もしないようなダミーインターバルを入れると上手く動作する。

https://github.com/nodejs/node/issues/4262

これは、nodeのバグかと思いましたが、Raspberry PiのOSが32bit版だということに原因があります。

https://github.com/Samsung/libtuv/blob/master/src/unix/linux-core.c

 

void uv__io_poll(uv_loop_t* loop, int timeout) { /* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes * effectively infinite on 32 bits architectures. To avoid blocking * indefinitely, we cap the timeout and poll again if necessary. * * Note that "30 minutes" is a simplification because it depends on * the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200, * that being the largest value I have seen in the wild (and only once.) */ static const int max_safe_timeout = 1789569; : : for (;;) { /* See the comment for max_safe_timeout for an explanation of why * this is necessary. Executive summary: kernel bug workaround. */ if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) timeout = max_safe_timeout; max_safe_timeout = 1789569;なので、29.8分でタイムアウトします。

Raspbian OSが64bit版になれば、改善されると思われます。

Translate »