Как формировалась основная технология и как развивался технологический стек/архитектура.

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

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

Проблемы

  1. Автоматизация всего конвейера от клиентского ввода/вывода, создания задач, решения проблем, управления данными. Это поможет оптимизировать проект
  2. Причудливое управление проектами не будет типичным управлением процессами, поскольку каждый проект был уникален сам по себе, и процесс рабочего процесса должен был быть адаптирован в соответствии со спецификациями и целями клиента.
  3. Песочница — где менеджеры проектов могут экспериментировать с различными идеями рабочего процесса.
  4. Компоненты Plug and Play. Эта функция предоставит нам огромную гибкость и мощность для быстрой доставки, экспериментов с компонентами ИИ, а для менеджеров по проектам иметь подключаемые компоненты в своем рабочем процессе, которые они могут редактировать, удалять или создавать любые комбинированные комбинации/потоки. Но каждый шаг рабочего процесса должен масштабироваться индивидуально.

Подход

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

У нас было много идей, и мы были на пути к созданию очень сложной идеи.

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

Решение

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

Итак, разбивая вышеизложенное на 2 части

1)Выбор языка

Эти моменты были очень важны для нас, чтобы сузить выбор наиболее премиального для нас, которым был GOLANGсреди прочих были Java, Rust, Scala, Kotlin, Ruby. Для этого было много факторов, но наиболее важными были одобрение отрасли, производительность и отсутствие зависимости от JVM (поскольку это требует множества ненужных настроек). Язык унаследовал много хороших принципов проектирования, которые нам нравились, хотя схема обработки ошибок, отсутствие универсальных шаблонов были немного болезненными на раннем этапе внедрения. Но голанг был тем, что нам было нужно. Каналы и горутины (высокопроизводительные [CSP и горутины] с малым объемом памяти, оптимизированным сборщиком мусора и встроенными библиотеками, такими как net/HTTP) были серьезными улучшениями дизайна для программирования. язык. Произошло резкое улучшение системы как с точки зрения памяти, так и скорости (по сравнению с нашим существующим стеком JAVA и NODE)

2) Архитектура кода

RabbitMq (необходимый ингредиент).Наша цель создать бесшовный, хорошо масштабируемый, постоянный, динамический конвейер управления данными стала проще после того, как мы добавили Rabbitmq в наш технический стек. Это дало нам возможность дросселировать трафик в соответствии с различными подключаемыми службами и их ограничениями, например, если служба краудсорсинга может обрабатывать только 30 входных данных в секунду, тогда эта подключаемая служба будет иметь это ограничение, установленное оркестратором. сервис, который ограничит скорость до 30.

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

// Setting autoAck parameter (3rd param) to false which means we have to manualy Ack it 
deliveries, err := rabbitmq.Consume(queueName, "", false, false, false, false, nil)
if err != nil {
   return
}
...
...
...
// Here we are manual ack the input received from the queue after we are done with the processing
err := input.delivery.Ack(false)
if err != nil {
   panic(err)
}

Создание границ. Начав с прочного прототипа, мы убедились, что разработка будет легкой и несложной. Мы разработали его, чтобы позволить новому разработчику тратить меньше времени и ресурсов на новый подключаемый модуль, над которым он работал. Затем мы работали над нашими интерфейсами вместе с четко определенными границами, чтобы этот продукт просуществовал как можно дольше. Код содержит множество интерфейсов, которые очень помогли нам в слабой связи зависимостей. И, в свою очередь, это помогло в тестировании кода, имитировании и лучшей читабельности кода. см. этот пример для расширенного тестирования golang.

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