Наблюдение
Давно заметил, что многие девушки, носящие сумку на одном плече, со временем перестают шевелить той рукой при ходьбе, со стороны которой носят сумку. Даже если сумки на плече нет.
И вот смотрю я на весь из себя такой футуристичный сериал «Звёздный путь: Дискавери», где все ходят в мундирах, живут на своих короблях и никаких сумок через плечо и в помине нет. А посреди этого милитаристского будущего через весь кадр идёт девушка, почти не двигая правой рукой, при энергичном участии левой. Малозаметный анахронизм.
Митохондриальная Ева
Прочистил голову от заблуждения о «митохондриальной Еве» — так СМИ называют женщину от которой мы все получили свою митохондриальную ДНК прекрасным роликом.
Я подозревал, что с публикациями «у человечества единая мать»
Читая СМИ можно сделать вывод, что исследователи
Но в то же время жило ещё множество предков, в том числе и женского пола, от которых им достались другие гены! Просто других прямых женских линий не осталось —
На картинке выше видно в чём тут дело. Митохондриальную ДНК я получил только от своей прабабушки Евдокии Никоноровны, тогда как от других предков я тоже получал гены.
Memcached и persistent connections
В работе с модулем «Мемкешд» есть целая куча подводных камней, которые иногда всплывают
Упомянутый модуль имеет малозаметную возможность, которая помогает экономии ресурсов в проектах с большой нагрузкой — если в конструктор передать строку, то она станет идентификатором для так называемого «персистент коннекта» — соединения, которое открывается процессом интерпретатора ПХП и живёт между запуском обрабатываемым этим процессом программ.
Оказалось у этого функционала есть особенность:
socket(PF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_TCP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(11211), sin_addr=inet_addr("127.0.0.1")}, 16) = -1
poll([{fd=4, events=POLLOUT}], 1, 4000) = 1 ([{fd=4, revents=POLLOUT}])
getsockopt(4, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
sendto(4, "version\r\n", 9, MSG_NOSIGNAL, NULL, 0) = 9
recvfrom(4, "VERSION 1.5.1\r\n", 8196, MSG_NOSIGNAL, NULL, NULL) = 15
sendto(4, "quit\r\n", 6, MSG_NOSIGNAL, NULL, 0) = 6
shutdown(4, SHUT_WR) = 0
shutdown(4, SHUT_RD) = -1 ENOTCONN (Transport endpoint is not connected)
close(4) = 0
socket(PF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_TCP) = 4
setsockopt(4, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(11211), sin_addr=inet_addr("127.0.0.1")}, 16) = -1
poll([{fd=4, events=POLLIN|POLLOUT}], 1, 4000) = 1 ([{fd=4, revents=POLLOUT}])
getsockopt(4, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
sendto(4, "version\r\n", 9, MSG_NOSIGNAL, NULL, 0) = 9
recvfrom(4, "VERSION 1.5.1\r\n", 8196, MSG_NOSIGNAL, NULL, NULL) = 15В логе выше видно, что процесс постоянно устанавливает новые соединения с сервером мемкешда, несмотря на то, что в коде (поверьте) используется один и тот же постоянный идентификатор.
Мы долго были в недоумении, но в конечно счёте выяснилось, что такое поведение воспроизводится, если после создания объекта выставлять любые опции, влияющие на сокет. В этом случае модуль переоткрывает соединение с сервером, причём неважно открывался сокет с теми же настройками или нет.
Решение — любым доступным способ проверять получили ли мы «свежий» объект или имеем дело с уже открытым соединением и выставлять опции только в первом случае:
$mc = new Memcached('persistent');
if (!$mc->getServerList()) {
$mc->setOptions([
Memcached::OPT_NO_BLOCK => true,
]);
$mc->addServer('127.0.0.1', 11211);
}Тогда соединение благополучно переиспользуется.
Тридцать девятый выезд
Давненько закрыл сезон в этом году — примерно с первым снегом, не помню числа, но всё никак руки не доходили сфотографировать. Сейчас, когда предновогодняя лихорадка закрытия контрактов спала, могу послепенно обработать накопленное. На фото — результаты последнего в этом году выезда.
На снимке: стёртая в ноль монета, предположительно «масон»