barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

вторник, 28 июня 2022 г.

Excel: преобразование времени в миллисекунды

Задача

Есть ячейка со строкой - временем в формате ЧЧ:ММ:СС.млс (например, 18:45:13.785). Необходимо преобразовать это значение в число миллисекунд.

Решение

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

=LEFT(A1; 2)*3600000 + MID(A1; 4; 2) * 60000 + MID(A1; 7; 2)*1000 + RIGHT(A1; 3)

пятница, 13 мая 2022 г.

Gradle: установка переменных окружения

 Читать переменные окружения gradle умеет:

 System.getenv("HOME")

А вот устанавливать - нет, метод а-ля System.setenv() отсутствует. Однако, в задачах, запускающих отдельный процесс, можно установить переменную окружения для этого отдельно стартующего процесса, например:

task('myTask', type:Exec) {
    environment "FOO", "bar"
    workingDir '.'
    commandLine 'cmd', '/c', 'print.bat'
}

вторник, 5 апреля 2022 г.

WSL2: высвобождение места, занимаемого диском гостевой ОС

Проблема

Есть WSL2 и Ubuntu под ним. После некоторых действий в Ubuntu создалось большое количество больших и ненужных файлов, заметил я это по росту файла C:\Users\%USER%\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\ext4.vhdx. Сами ненужные файлы в Ubuntu я почистил, однако, vhdx-файл не уменьшился. Команда df в Ubuntu показывает утилизацию места на основном томе всего в 3%.

Решение

В powershell-консоли, запущенной с правами администратора, переходим в директорию, где лежит  vhdx-файл, выполняем:

wsl --shutdown
optimize-vhd -Path .\ext4.vhdx -Mode full

среда, 23 марта 2022 г.

Проверка сетевой доступности MongoDB Atlas кластера

Берем хостнэйм, указанный в connection string. Делаем:

dig -t SRV _mongodb._tcp.<хостнэйм из connection string>

либо

nslookup -q=SRV  _mongodb._tcp.<хостнэйм из connection string>

В ответ получаем записи вида:

_mongodb._tcp.***.mongodb.net        service = 0 0 1025 ***.mongodb.net.

_mongodb._tcp.***.mongodb.net        service = 0 0 1026 ***.mongodb.net.

_mongodb._tcp.***.mongodb.net        service = 0 0 1024 ***.mongodb.net. 

В правой части указаны хосты и порты фактических серверов. Теперь можно проверять сетевую доступность, например, с помощью nc:

nc -zv -w 5 ***.mongodb.net 1024 

Ограничение объема памяти, используемого WSL2

 Создаем файл %UserProfile%\.wslconfig, и в нем прописываем:

[wsl2]
memory=8GB

среда, 2 февраля 2022 г.

Установка podman на Ubuntu 18.04 / 20.04 под WSL2

Выполняем:

. /etc/os-release
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${NAME}_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list"
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/x${NAME}_${VERSION_ID}/Release.key -O Release.key
sudo apt-key add - < Release.key
sudo apt-get update -qq
sudo apt-get -qq -y install podman
sudo mkdir -p /etc/containers
echo -e "[registries.search]\nregistries = ['docker.io', 'quay.io']" | sudo tee /etc/containers/registries.conf 

Для Ubuntu 18.04 открываем конфигурационный файл

sudo nano /usr/share/containers/containers.conf

, и правим там следующие строки:

cgroup_manager = "cgroupfs"
...
events_logger = "file"

Если при запуске podman возникает ошибка:

cannot clone: Invalid argument
Error: cannot re-exec process

, вероятно, версия используемая версия WSL не 2, а 1. Это можно проверить командой: 

wsl --list -v

В колонке "VERSION" должна быть двойка, иначе нужно сделать апгрейд до версии 2 командой:

 wsl --set-version Ubuntu-20.04 2 

вторник, 25 января 2022 г.

Spring Boot: запуск кода до старта application

Задача

Запустить некий код до того, как начнет запускаться приложение. В моем случае нужно вызвать Security.addProvider().

Решение

Можно, конечно, сделать вызов в методе main() класса, аннотированного как @SpringBootApplication, перед тем, как вызывать SpringApplication.run():

@SpringBootApplication
public class AclImportApplication {
    public static void main(String[] args) {
        Security.addProvider(...);
        SpringApplication.run(AclImportApplication.class);
    }
}

Вот только код main() не вызывается при запуске @SpringBootTest, что создает необходимость создавать какие-то костыли для работоспособности тестов. Более правильный вариант - написать свою имплементацию интерфейса org.springframework.boot.SpringApplicationRunListener, где в методе starting() поместить нужный код. Имплементация должна обязательно иметь конструктор, принимающий SpringApplication app и String[] args, а также ссылку на имплементацию необходимо прописать в META-INF/spring.factories:

org.springframework.boot.SpringApplicationRunListener=my.custom.AppRunListener