Pull to refresh

Как изменение двух строк кода может занять несколько дней

Reading time 3 min
Views 21K
Интересно верит ли кто-либо еще что работу разработчика можно измерить количеством строк кода? Попробуем вместе развенчать этот старый, как мир, миф своими красными глазами.


Сложно ли изменить две строчки кода?

Герой этой истории — open source проект H2 database популярной реляционной базы данных для тестов, веб консоли для SQL и даже содержит внутри себя аналог LevelDB/Berkeley DB Java Edition/SQLite 3. Отличный проект, много раз использовал за свою практику и не было проблем. До тех пор пока не попытался использовать его совместно с redshift jdbc driver.

Есть такая база данных в AWS, Redshift — форк времен PostgreSQL 8.0.2. Где-то в том же десятилетии появился и его конкурент greenplum-db… Несмотря на то что эта БД имеет массово-параллельную архитектуру, и прочие «плюшки» column-oriented DBMS, при работе с ней не покидает ощущение что ты в музее компьютерной истории. Понял, что это ощущение было неспроста, когда обнаружил что в приложении конфликтуют драйвера современного PostgreSQL 9.6 и Redshift драйвер ископаемого wire протокола postgresql 8.x.

Обнаружил что используется PG wire protocol 8.x, когда подключался к PostgreSQL 9.6 в H2 web консоли. Результаты меня огорчили и я начал разбираться как же такое может происходить. Отладка привела в строчку получения соединения:

 DriverManager.getConnection(url, prop);

Вроде бы все выглядит по спецификации, так как это не JNDI и не javax.sql.DataSource.

Спускаемся глубже в DriverManager. Там все и так известно и ожидаемо. В его блоке статической инициализации используется ServiceLoader для загрузки реализующих java.sql.Driver и заявляющих об этом с помощью записи о реализации META-INF/services/java.sql.Driver в своем jar. Это достаточно давно отменило использование Class.forName(driver) — так все современные драйверы загружаются без этого ископаемого вызова. Ничего нового для меня тут нет.

Драйверы при запросе соединения перебираются в порядке, как они зарегистрировались в поле registeredDrivers. DriverManager для каждого из них по цепочке вызывает driver.connect(url, info). Если конкретный драйвер вернул объект соединения с базой данных, возвращаем его из функции. Первый кто обработал connection URL из цепочки драйверов побеждает!

Драйвер сам анализирует может ли он обработать подпротокол jdbc:subprotocol. На мою беду redshift jdbc драйвер обрабатывал кроме своего «redshift» еще и «postgresql», но с помощью древнего кода эпохи середины 2000х. Ясно, что connection url запрос никогда не дойдет до драйвера postgres 9.6.

Один плюс в карму разработчикам redshift jdbc — спасибо хоть классы древней реализации PG в отдельный пакет спрятали, а не оставили конфликтовать с org.postgresql.Driver в jar hell. Попробовал использовать более «свежий» их драйвер, но он не работал внутри spring boot executable jar, так как в нем зависимости упаковали «матрешкой» — jar'ы зависимостей внутри jar драйвера.

При этом пул соединений HikariCP правильно создает новый драйвер postgresql, в отличии от консоли H2. Раз уж пользователь указал driverClass, то он на нем и вызывает connect не полагаясь на DriverManager. Это работает в аду, учиненном redshift jdbc. Причина была найдена быстро и стало ясно как решать проблему.

Патч был создан в выходной и отправлен как pull request в репозитарий проекта, заодно создал заявку об ошибке. После этого началась переписка и аргументация изменения для контрибьютора, второго по активности в репозитарии h2database. Выполнил все его требования и замечания для этого pull request и изменения приняли в основной код проекта. Ушло много свободного времени из-за двух строчек изменений и драйвера redshift. Но тут уже был азарт и дело принципа — выжить в мире где ископаемый протокол перекрывает современный. Спасибо ему за уделенное время, за то что вник в эту проблему. Верю что дотошность при приеме pull request в популярном open source проекте идет на пользу качеству. Прошло почти два выходных дня, пока две строчки для исправления бага появились в проекте.

Другой pull request на новый функционал в schemaspy висит уже больше недели. Тут виноват сам, проблема что разрабатывал его на linux, а не работало на windows системе. Каюсь, что не дотестировал сразу.

Делитесь про то, как несколько строк кода поглощали время. Есть интригующие истории и рассказы детективного жанра?
Tags:
Hubs:
+29
Comments 44
Comments Comments 44

Articles