Как контролировать версии различных функций в одном веб-приложении?

У нас есть несколько веб-приложений, и теперь эти веб-сайты обновляются не впервые, но становится все сложнее контролировать версию для пользователей и разработчиков.

У нас много клиентов, некоторые из них используют одно и то же приложение, но им нужно платить за обновления. Но не все клиенты платят за обновления, и из-за этого у нас есть клиенты, использующие одну версию, а другие клиенты, использующие другую версию.

У нас есть два пути, и мы ищем третий путь:

  1. Поместите версию в путь, как это: www\project\version\system-files

Но этот способ стал запутанным для некоторых пользователей, потому что для них URL стал: www.website.com/app-versionи при обновлении системы URL-адрес меняется.

  1. Поместите версию в функцию, например так: function V1_functionX()

Когда необходимо обновить функцию, мы создаем новую функцию под названием V2_functionX, Но это создало «толстый» веб-сайт, и команда сделала несколько ошибок во время разработки, потому что у нас не «одна версия для разработки», а «много версий для разработки», а некоторые функции используются более чем на одном веб-сайте.

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

Мы говорили о том, как ведут себя другие компании: они «закрывают» сайт для обновления системы. Это будет, вероятно, наш путь.

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

Примечание: это не о SVN.

2

Решение

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

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

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

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

Ваши основные библиотеки и специфичные для клиента функции могут затем находиться в наборе библиотек, например:

/project/core
/project/versions/1/Class.php
/project/versions/1.1/Class.php
/project/versions/2/Class.php
/project/versions/2.1.1/Class.php
/project/versions/...

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

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

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

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

  • принуждение отстающих клиентов к обновлению до одной из поддерживаемых на данный момент версий
  • бесплатное обновление отстающих клиентов до самой старой из поддерживаемых версий

Некоторые дополнительные мысли, основанные на новой информации. Я размышлял, поможет ли разделение кода на отдельные репозитории, по одному для каждого клиента. Однако мне интересно, если нет гарантии, что они будут; даже если вы используете основные функции при использовании Composer или субмодуля Git, все еще существует вероятность расхождения между вашим последним ядром и вашим самым ранним клиентским кодом. В какой-то момент ваш худший отстающий клиент будет сдерживать разработку ядра.

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

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

Например, предположим, что у вас есть семь клиентов, и у шести из них есть объект User, у которого есть адрес электронной почты, для обработки запросов на изменение пароля (один клиент имеет объект User без этого поля). Это означает, что, если неудобная схема не может измениться, ядро ​​не может предположить, что адрес электронной почты доступен. (В этом тривиальном случае может быть дешевле бесплатно обновить odd-one-out, чтобы в ядро ​​могло уйти больше кода, чем поддерживать такую ​​стандартную вещь, как улучшение версии).

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

0

Другие решения

У нас есть это на моей работе:

  1. Локальный веб-сайт разработчика (SVN)
  2. сервер разработки, где все разработчик тест
  3. Препрод, где все ок
  4. Prod (rsync из preprod)

Rsync между 2 серверами очень быстр, когда мы делаем серьезное обновление менее чем за 5 секунд

0

По вопросам рекламы [email protected]