setTimeout ведет себя по-разному в Mac OS и Linux при использовании libfaketime - PullRequest
0 голосов
/ 30 мая 2018

При использовании libfaketime для изменения скорости времени процесса время ожидания, установленное setTimout, истекает в соответствии с измененным временем при работе в Linux, но в соответствии с исходным системным временем при работе в Mac OS.

В Mac OS:

DYLD_INSERT_LIBRARIES=src/libfaketime.1.dylib DYLD_FORCE_FLAT_NAMESPACE=y FAKETIME="@2020-12-24 00:00:00 x3600" node

> setTimeout(() => {console.log('hello');}, 3600 * 1000); // Takes an hour

В Linux:

LD_PRELOAD=src/libfaketime.1.so FAKETIME="@2020-12-24 00:00:00 x3600" node

> setTimeout(() => {console.log('hello');}, 3600 * 1000); // Takes a second

При изучении этой проблемы я заметил, что функция libc clock_gettime опрашивается узлом.js (libuv?) в Linux, но эта функция не вызывается при работе в Mac OS.(Я добавил printf s к libfaketime функциям)

В чем разница в реализации node.js (libuv?), Которая вызывает такое несоответствие в поведении между Mac OS и Linux?И почему существует такое различие в реализации?

Другое наблюдение, которое я сделал, заключается в том, что когда время заморожено с использованием libfaketime, поведение setImmediate и setTimeout(cb, 0) отличается в Linux тем, что обратный вызов запускается, когдаиспользуя setImmediate, но не при использовании setTimeout(cb, 0).

1 Ответ

0 голосов
/ 30 мая 2018

Это определенно разница в libuv.Дарвин не поддерживает CLOCK_MONOTONIC*, поэтому mach_absolute_time() необходимо назвать , чтобы узнать текущее время.Это в конечном итоге обходит libfaketime, заставляя код клиента выполняться в реальном времени на OS X.

...