Заметки

Мои мысли о жизни, работе и разных интересных штуках вокруг меня.

Показано: 0 · Страница

River City Girls
30 сентября 2019 ·
Семья
Видеоигры

Прошли на пару с мелкой River City Girls (недавно вышедший beat 'em up; это такой жанр игр, где нужно навалять всем, кто тебе не нравится).

На фоточке я наблюдаю за десятилетней Лисой, которая в этот момент уверенно разбрасывает толпу японских мордоворотов.

Control
14 сентября 2019 ·
Видеоигры

К игре у меня две претензии. Во-первых, местные «измененные предметы»: их описания в сравнении с плодами буйной фантазии авторов из фонда SCP выглядят не слишком ярко. Да, есть приятные исключения, но эта часть все равно кажется слабее остальной паранормальщины, которая есть в игре.

Вторая претензия — то, при каких обстоятельствах игрок слышит My Dark Disquet от Poets of The Fall. Черт побери, это слишком крутой трек для такого проходного участка! Ожидал встретить его во время титров или какой-нибудь сумасшедшей схватки.

Я понимаю, что оба пункта звучат мальца несерьёзно, но это правда всё. Control исключительно хороша и внешне, и геймплейно, и сюжетно. Единственная причина, по которой я никому не подарю эту игру на Новый Год — в Epic Games Store пока нет возможности это сделать :-)

Control и Poets of the Fall
23 августа 2019 ·
Видеоигры

Я и так уже не устоял перед рыжей чертовкой из трейлера Control, а этим роликом ребята из Remedy и вовсе зашли с непробиваемых козырей.

Послушайте, это просто неприлично круто! Можно как-нибудь перемотать время на конец августа? :-)

Парадокс Ферми
19 августа 2019 ·
Тем временем
Видеоигры

Твит

Причем, если игра хорошая, это обычно происходит как-то незаметно. Сидишь такой гоняешь в нишевый азиатский хоррор, а потом щелк! И приходишь в себя через пару часов где-нибудь в википедии, на странице про второй кризис в Тайваньском проливе.

Статья про парадокс Ферми, кстати, и правда годная — пусть обзор, но написан живо и человеком, который любит то, о чем пишет.

На, мужик, изоленту
2 августа 2019 ·
Книги
Работа

Начитанные друзья иногда спрашивают — мол, какая у тебя любимая книга? Мне, блин, всегда чутка стыдно отвечать на этот вопрос, потому что при всём том огромном выборе, который есть, это «Марсианин» Энди Вейера.

Если опустить то, что это классный приключенческий роман, то причина проста: как программист, я чувствую необыкновенное духовное родство с человеком, который решил кучу сложных инженерных проблем с помощью изоленты.

Да, разумеется, изолента работает почти в вакууме. Изолента работает почти везде и повсюду. Изолента — это дар богов, ей нужно поклоняться.

― Энди Вейер, «Марсианин»

Observation
28 июля 2019 ·
Видеоигры

За бортом — недалекое будущее, а вы — искусственный интеллект космической станции, на которой произошла катастрофа. Работа ваших систем нарушена, большая часть данных потеряна, а экипаж — чёрт знает где. Во всём этом нужно разобраться и навести порядок.

Это завязка недавней Observation от No Code. Коротко: игра — пушка. Зайдет любителям научной фантастики, особенно классики (Артур Кларк, вот это всё). Из последнего, во что я играл в этом жанре, круче — только SOMA.

Искренне советую не читать никаких обзоров (журналисты без спойлеров двух слов связать не могут) и не смотреть официальный трейлер — в игре крутое интро и его стоит посмотреть внутри истории, а не на ютубе.

Музыку к интро, кстати, написал Робин Финк (Nine Inch Nails). Вижуал в момент просмотра непонятен, но когда догоняешь, что именно там показывают — невольно проникаешься.

Хороший день
9 июля 2019 ·
Семья
Видеоигры

Твит

Дорогой дневник! Сегодня мне заплатили, чтобы я нарисовал думгая, который учит Рапунцель из диснеевской «Запутанной истории» стрельбе из тяжелой штурмовой винтовки. Сегодня был хороший день!

― izra

Обожаю художников. Особенные люди :-)

(а также на рисунке я, обучающий дочку, как рашить зилотами в Starcraft 2)

Мультиязычность в Vue.js
25 июня 2019 ·
Блог
Вебдев
Готово

Я веду этот сайт на русском языке, но есть и зеркало на английском — туда я постепенно перевожу то, что написал здесь. Поддерживать два набора скриптов я не хочу, поэтому оба домена ссылаются на один и тот же сервер, который определяет, с какого домена пришел запрос — и выводит ответ на соответствующем языке.

Звучит просто, но на самом деле эта задача рождает довольно много дополнительных проблем, и одна из них — вывод интерфейса. Сначала я по привычке завел на клиенте два массива с фразами на разных языках, но быстро выкинул этот велосипед и прикрутил Vue I18n.

На нижнем уровне это, правда, всё те же два массива с фразами (их нужно задать при инициализации), однако выгода здесь в другом. Этот плагин сам по себе закрывает еще две проблемы с генерацией интерфейса:

  1. Склонение существительных. Нужно, чтобы правильно выводить слово «страница» в статистике по тегам — одна заметка, две заметки, пять заметок и так далее.
  2. Вывод дат. Например, дата под этой заметкой.

Обе задачи, конечно, можно было закрыть на стороне сервера, силами PHP, но я счел это некрасивым решением. Сервер должен возвращать данные, клиент — строить интерфейс. Нечего их смешивать.

Draugen
10 июня 2019 ·
Видеоигры

Сравнительно короткая, но по-своему яркая история. Проиграть тут нельзя, особого выбора (кроме вариантов реплик) нет. Но то, как тут всё звучит и выглядит, то, как здорово прописаны персонажи — удивляет и трогает. Даже если угадываешь повороты сюжета до того, как с ними столкнешься.

В целом игра напомнила то ли Firewatch, то ли The Vanishing of Ethan Carter. Сюжет, на мой вкус, мог быть немного длиннее и заметно драматичнее, но мне всё равно чертовски понравилось, как всё закончилось. Эмоции от финала можно выразить — осторожно, спойлервот этой картинкой :-)

И приятнее пахнуть
10 июня 2019 ·
Видеоигры
Работа
Битрикс

На днях выпустили очередный релиз FirstBIT ERP (наш программный продукт для автоматизации бизнеса в ОАЭ). Вложен вагон труда, всё работает как надо, есть чем гордиться и всё такое. Я, например, кучу сил потратил на то, чтобы сделать полноценный обмен данными с Битрикс24 и порядком рад, что успел этот механизм зафиналить.

Но в душе всё равно немного завидно коллегам из геймдева: наши патчноуты, конечно, тоже интересные, но такого там всё-таки не встретить.

Сикока сикока?
5 июня 2019 ·
Блог
Вебдев
Node.js
Javascript

Этот сайт почти полностью написан на PHP. JavaScript на клиенте используется ситуативно — редирект сделать, картинку показать и так далее.

Для личного ресурса ничего сложнее и не нужно, но некоторое время назад мне приспичило слегка освежить свои навыки веб-разработки. В качестве платформы для эксперимента я выбрал Vue.js — популярный, быстрый и не слишком сложный фреймворк.

Я, собственно, к чему это всё пишу. Развернул тут Node.js, Vue CLI, создал первый проект — и чуть не поседел. Триста мегабайт джаваскрипта прямо со старта?! Серьёзно?!

Yomawari: Night Alone
30 мая 2019 ·
Видеоигры

Клевая изометрическая бродилка про город, набитый классическими японскими призраками и девочку, которая в этом городе ищет пропавшую сестру. Не слишком страшная — она, скорее, держит в напряжении. Не слишком сложная, хотя требует внимательности и концентрации (привидений много, ведут они себя по-разному, нужно смотреть по сторонам и не считать ворон). Не слишком быстрая, хотя местами всё-таки нужна хорошая реакция (особенно ближе к концу сюжетной линии).

В целом оставила очень приятное ощущение проекта, в который, может, и не были вложены миллионы, но который старались сделать настолько хорошо, насколько это было возможно.

Большая таблица на клиенте
19 мая 2019 ·

Про нюансы работы со здоровенными таблицами на клиенте я уже пару раз писал (раз, два), но в конце прошлой недели коллеги подсказали ещё один любопытный способ оптимизации работы с относительно большими коллекциями данных на клиенте. Вкратце: стандарт советует работать с большими коллекциями только на сервере, однако если сразу обойти всю коллекцию на клиенте (например, в обработчике открытия формы) — она закешируется. В итоге последующие обходы, поиск строк и другая работа с данными не будут требовать дополнительных серверных вызовов. Суммарные расходы при таком подходе получаются ниже.

Погонял сейчас простые тесты — да, похоже, что так и есть. Метод выглядит отчасти костыльно и на серьезных нагрузках я его ещё не проверял — но, вероятно, его вполне можно иметь ввиду.

Close to the Sun
14 мая 2019 ·
Видеоигры

Игрожуры и ютуберы соревнуются, кто задорнее обложит «Close to the Sun» в рецензиях, а мне игра неожиданно понравилась. Конечно, это не шедевр, но атмосфера огромного «летучего голландца» передана просто отлично. Происходящее местами напоминает Биошок, но я очень далек от того, чтобы валять в перьях любую историю, которая чем-то похожа на то, что я уже где-то видел.

А ещё во время финальных титров тут играет очень крутой сингл, который буквально продал мне игру пару дней назад и который можно слушать, к самой игре не прикасаясь.

Задержки PageLatch
22 апреля 2019 ·
MS SQL

Задержки вида PageIOLatch (я про них сегодня писал) легко встретить в любых системах, в том числе небольших. С задержками PageLatch дела обстоят наоборот — их трудно заметить, пока пользователей меньше нескольких тысяч.

Дело в том, что они возникают, когда страница находится в оперативной памяти и её пытаются изменить несколько пользователей. Пока один пользователь не завершит модификацию — прочие должны ждать. Время ожидания обычно ничтожно, однако если конкурирующих за страницу пользователей много — оно становится заметным.

Возможных причин две.

Горячее место в индексе

Такой расклад иногда называют хотспотом. Он возникает, когда мы массово пытаемся писать что-то на последнюю страницу индекса; в первую очередь речь идёт об индексе с монотонно возрастающим ключом — например, любые индексы по полям ссылочного типа (начиная с последних версий 8.2, платформа выдает последовательные GUID — это снижает фрагментацию диска и делает ключ индекса монотонно возрастающим).

Что такое «индекс с монотонно возрастающим ключом»? Для платформы 1С это, например, индексы регистров по периоду. Конечно, они растут не вполне монотонно — однако тут скорее важно, что данные мы всегда будем писать в конец. Сюда же относятся индексы по номеру документа и индексы по коду справочника — в обеих случаях мы выдаем некий новый номер, который пишется в конец индекса.

Решается проблема хотспота только архитектурно — нужно добиться того, чтобы данные записывались в разные места индекса, а не только в конец.

Системные страницы tempdb

Когда мы создаём или удаляем таблицу в базе данных, в ней обновляется ряд служебных страниц — IAM (Index Allocation Map), PFS (Page Free Space), GAM (Global Allocation Map), SGAM (Shared Global Allocation Map) и другие.

Почему это важно для tempdb? Для платформы 1С это база, в которой регулярно создается огромное количество таблиц. Служебные страницы при этом обновляются настолько часто, что при этом возникают задержки семейства PageLatch.

Вообще-то MS SQL Server умеет оптимизировать обновления системных страниц для tempdb, благодаря чему это делается реже, но иногда даже этого не достаточно. Особенно если в tempdb создаются таблицы с индексами — а это очень частый кейс для приложений на 1С.

У проблемы есть несколько возможных решений. Первый — если СУБД старше 2016-й, можно отключить смешанные экстенты через флаг трассировки 1118. При этом исчезнет необходимость сразу в двух служебных страницах — GAM и SGAM. Соответственно, ожиданий на их обновлении не будет. Экстент — это восемь страниц данных, т.е. 64 килобайта; если он содержит страницы одной таблицы — это нормированный экстент, если нескольких — смешанный.

Второй подход — разбивать tempdb (с 2016-й версии СУБД она, кстати, по умолчанию разбивается на восемь файлов). Дело в том, что служебные страницы ведутся в разрезе файлов; если их будет несколько — ожидания на обновлениях служебных страниц будут ниже.

Третий вариант — уменьшать количество временных таблиц с целью снизить нагрузку на tempdb. То есть переписывать наиболее частотные запросы так, чтобы они работали приемлемо быстро без временных таблиц.

Задержки PageIOLatch
22 апреля 2019 ·
MS SQL

Когда мы читаем страницу данных с диска в буферный кэш, она на очень короткое время блокируется (её нельзя писать, а в некоторых случаях — ещё и читать). Ожидание на завершении этого действия — и есть задержка PageIOLatch.

Причиной может быть вымывание буферного кэша — из-за небольшого объёма доступной ОЗУ или не оптимальных запросов, которые читают миллионы строк, а возвращают три. В итоге СУБД регулярно не находит нужных страниц в кэше и вынуждена снова и снова читать их с диска.

В общем, если в системе есть существенные задержки PageIOLatch — их скорее всего можно снизить, используя более быстрые диски, наращивая объём ОЗУ и оптимизируя запросы.

Объектные блокировки
22 апреля 2019 ·

Во-первых, сразу, чтобы не путаться: объектные блокировки платформы никак не связаны с управляемыми блокировками и, тем более, блокировками СУБД. Во-вторых, различают два вида: пессимистические объектные блокировки и оптимистические.

Оба вида неплохо описаны на ИТС; ниже — просто краткая выжимка.

Пессимистические блокировки

Накладываются расширением формы, когда пользователь начинает редактировать объект — например, меняет значение поля. Если тот же объект попробует отредактировать в форме другой пользователь — форма, которую он открыл, тоже попробует наложить пессимистическую блокировку, не сможет этого сделать и пользователь получит ошибку «Не удалось заблокировать запись».

То есть платформа в данном случае делает своего рода пессимистичную оценку ситуации: мол, раз первый пользователь начал редактировать объект — скорее всего, он его запишет. Раз так, второму пользователю разрешать редактировать нельзя.

Пессимистическую блокировку также можно наложить методом объекта Заблокировать() и снять через метод Разблокировать(). Кроме того, можно воспользоваться методом глобального контекста ЗаблокироватьДанныеДляРедактирования() и методом управляемой формы ЗаблокироватьДанныеФормыДляРедактирования().

Оптимистические блокировки

Сперва немного теории: платформа хранит версии объектов ссылочного типа (справочников, документов и так далее). По сути это просто момент времени, в который объект был изменён последний раз. Когда объект считывается расширением формы или кодом — его версия считывается вместе с ним.

Так вот, в момент записи объекта платформа сверяет ту версию, что была получена при чтении объекта из базы данных и ту, что указана в базе данных в момент записи. Если версии различаются — возникает ошибка «Операция не может быть выполнена из-за несоответствия версии или отсутствия записи базы данных».

Это и есть так называемая «оптимистическая блокировка». Называют её так потому, что платформа тянет с проверкой до последнего — пока не произойдет реальной попытки записи.

Наложить оптимистическую блокировку объекта через код нельзя: версия объекта хранится в поле _Version таблицы данных объекта, заполнением которого занимается СУБД. Напрямую изменить это значение средствами платформы нельзя (можно, впрочем, записать объект — тогда его версия изменится).

Растолстевшие роли
18 апреля 2019 ·
Работа

Очень любопытная заметка про неприятности, которые можно нажить командой роли «Снять все права». Нет, никакого криминала, права-то она честно снимает — только вот её вызов может привести к тому, что объект роли на пустом месте сожрёт в несколько раз больше памяти, чем ему реально нужно.

Прочитал, задумался и пошел проверять, как обстоят дела с этим у нас в конфигурации. И что бы вы думали? Накопал десятка два ролей, доверху набитых «снятыми галочками». Выгрузка прав весила около трёхста мегабайт, а после оптимизации — усохла почти втрое.

Любопытно, как это до сих пор оставалось незамеченным. Скорее всего, из-за количества объектов — у нас сравнительно небольшая конфигурация. То есть проблемные роли потребляли не так много ресурсов, чтобы мы что-то заподозрили.

GRIS
14 апреля 2019 ·
Видеоигры

Эту игру сравнительно сложно рекомендовать, но она и правда искусство в прямом смысле слова. Сходу даже не вспомню, когда в последний раз был заворожен настолько, что не мог оторваться.

То ли графикой, то ли музыкой, то ли тем, что авторы очень искренне передали то состояние, о котором хотели рассказать.

Простая галочка
30 марта 2019 ·
Работа

Пару недель назад мы добавили в справочник номенклатуры FirstBIT ERP параметр «Inactive». Задача была простой: если товар больше не нужен пользователю — он ставит галочку и тот исчезает отовсюду (из форм выбора, форм подбора остатков на складах и так далее).

Звучит несложно, правда? Техническая реализация тоже была простой — мы прошлись по всем объектам, в которых предполагается выбор номенклатуры, и добавили дополнительный параметр этого выбора.

Параметры выбора

Но пользователи начали жаловаться, что настройка не работает. Мы полезли разбираться и поняли, что забыли про историю ввода — этот механизм, как оказалось, параметры выбора просто игнорирует. То есть пользователи выбирали в инвойсе какой-то товар, потом делали его неактивным, возвращались и инвойс и… Снова видели в истории товар, который вроде только что отключили.

Мы принялись искать выход. Проблема в том, что история ввода хранится в системном хранилище и повлиять на неё программно нельзя. Можно разве что полностью удалить — но фактическая очистка истории происходит только при перезапуске клиента (и то через раз). Отключить историю вообще? Напоминает лечение простуды отсечением головы.

В какой-то момент мы наткнулись на информацию о том, что история ввода хранится не просто для конкретного поля, а ещё и в разрезе параметров выбора. То есть для каждого сочетания параметров выбора и их значений история выбора своя. Получается, если добавить некий дополнительный параметр выбора ко всем полям, где выбирается номенклатура — изменение значения этого параметра будет «чистить» историю (на самом деле, конечно, создавать новую — но пользователю-то какая разница).

В общем, мы создали такой параметр. Хранится в общем хранилище и транслируется в формы при их открытии через общий модуль, который программно добавляет параметр выбора. Если пользователь снимает или устанавливает флаг Inactive для любой номенклатуры — значение параметра меняется, а уже открытые формы получают его через механизм оповещений.

Минуточку!

А ведь как все невинно начиналось, а?

Однако механизм неплохо работает, хотя его недостатки налицо: во-первых, системное хранилище будет постепенно пухнуть по мере появления всё новых и новых сочетаний реальных параметров выбора и нашего, фиктивного. Во-вторых, запись номенклатуры теперь потенциально узкое место: два пользователя не смогут одновременно записать номенклатуры, у которых изменены флаги Inactive (будет блокировка при записи нового значения нашего скрытого параметра выбора в общее хранилище).

Первую проблему можно решить очисткой хранилища по какому-то триггеру, вторую — записью нашего параметра выбора в разрезе пользователей (например, через регистр сведений). Впрочем, мы искренне надеемся, что 1С даст какой-то доступ к истории ввода до того, как нам придется городить дополнительные костыли к тем, что мы уже наворотили :-)