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

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

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

Проблема

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

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

  • Модулизация. Разделение проекта на небольшие полуавтономные задачи и их соответствующая упаковка жизненно важны для простоты, надежности и тестируемости. Если нет, то у вас большие проблемы, а вы оцениваете по наиболее рациональным критериям?
  • Интерфейс. Решить, как эти коробки будут взаимодействовать друг с другом, нужно быстро, когда вы начинаете собирать свои компоненты. Если модульность выполнена правильно, то у вашего компонента мало точек входа, но это решение важнее, чем кажется. Рефакторинг и многократное расширение этих интерфейсов становится большой проблемой, поскольку они начинают использоваться в разных местах.
  • Параллелизм. Посмотрим правде в глаза, это то, чего вы редко можете избежать в современном программировании на стороне сервера. И хотя это может показаться работой, которую можно отложить, помните, что распараллеливание требует от вас кода определенным образом. Если вы воспримете это как «дополнение», вам нужно будет перепроектировать свой код, чтобы это произошло. Более того, параллельная работа — это не просто создание потоков; контролируя поток, нельзя игнорировать количество параллельных событий и их статус.
  • Восстановление после сбоя. Предполагая, что вы делаете все вышеперечисленное довольно хорошо, есть одна вещь, которая может свести вас с ума: как восстановить после сбоя. Теперь try..catch может звучать как ответ, если ошибка ограничена «бумом» — фрагментом кода без сохранения состояния, но что произойдет, если вам нужно откатиться сложный статус или сбой связан с текущим статусом объекта? Вам потребуется отменить изменения данных и повторно инициализировать свой код. А как вы заметите, что случилось что-то плохое? Собираетесь ли вы ждать ужасного звонка клиента?

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

Решение

Модель акторов — это стратегия параллельного программирования, в которой основной вычислительной единицей является актер.

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

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

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

Управление сбоями — еще один интересный факт программирования акторов. Поскольку каждый субъект живет своей собственной жизнью, каждая проблема со здоровьем, с которой может столкнуться агент, не напрямую влияет на состояние системы в целом. . Конечно, неудачный актер — это плохо, но если этот актер не является краеугольным камнем вашего проекта, его сбои не должны убить все приложение.
Интересный факт об актерах и сбоях — это обычная практика. чтобы позволить субъектам выйти из строя и не восстанавливаться самостоятельно, в пользу стратегии, в которой руководитель решает, что необходимо сделать, чтобы вернуть актера в полностью рабочее состояние. В большинстве реализаций сбой деактивирует актор, который не сможет обрабатывать дальнейшие сообщения.
Это шокирующая точка зрения, поскольку вы поднимаетесь по модели актора. кривой обучения, но вы можете ясно видеть, что в этом есть большой смысл: если способность актера действовать связана с его состоянием, то в случае неудачи существует реальная вероятность состояния. strong> поврежден, поэтому вам не нужно просто "поймать" основной код задачи, а управлять повторной инициализацией актера!

На этом этапе вы можете заметить, что модель актера выглядит как представление фабрики реального мира. Я бы сказал, это довольно смешно и тревожно.
Актеры:

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

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

Что еще? Ну что ж. На фабрике могут работать сторонние работники, как и в нашей модели.

Масштабирование!

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

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

Теперь давайте добавим кое-что, что опять-таки является источником ужасной чрезмерной боли и бессонницы: масштабируемость.
Как мы уже говорили ранее, акторы разговаривают друг с другом, и каждый экземпляр отвечает за выполнение поставленной перед ним задачи. , потенциально взаимодействуя с другими участниками в процессе выполнения своей работы. Однако до сих пор мы всегда рассматривали эту активность как абстракцию внутри одного работающего процесса. А может и нет?
Может и нет. Многие библиотеки моделей акторов также реализуют возможность создания кластеров агентов, развертывающих акторов. Эти агенты не будут одним и тем же процессом и не обязательно будут находиться на одном сервере. Поскольку общение между акторами осуществляется посредством сообщений, акторам на самом деле не нужно знать друг друга, поэтому актор определенно может общаться с другим актором, чья природа полностью неизвестно.
Это позволяет вам достичь трех замечательных вещей:

  • Система микроагентов. Небольшое специализированное программное обеспечение легче поддерживать, быстрее развертывать, отлаживать и, возможно, отдавать на аутсорсинг. Группировка акторов по аналогии в микроагенты может быть выигрышной стратегией, поскольку они могут быть развернуты на разных машинах и, следовательно, обеспечивать лучшую производительность. Философия микроагентов не является следствием программирования акторов, и модель может быть реализована несколькими способами, но модель акторов определенно подтолкнула меня в этом направлении.
  • Избыточность. Развертывания микроагентов не обязательно должны быть уникальными и не должны находиться на одном сервере. Воображаемый агент «Mailer», реализующий FailureMailActor, SuccessMailActor и DailyMailActor, не должен быть >уникальный, и если один по какой-либо причине выйдет из строя, другой все равно будет работать.
  • Независимо от того, придерживаетесь ли вы философии микроагентов или нет, даже полностью одинаковые копии всего программного обеспечения, развернутые на нескольких серверах и реализующие всех возможных участников, могут взаимодействовать друг с другом и позволять вам >распределить нагрузку между несколькими узлами.

Выводы

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

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

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

Первоначально опубликовано на 812bits.wordpress.com 31 июля 2015 г.