Простая система акторов
Project description
PEACEPIE
Простая система акторов. Пакет peacepie представляет собой некий аналог библиотеки akka в Java, систему акторов, осуществляющих взаимодействие между собой посредством сообщений. Указанной архитектуре присущи следующие положительные черты:
- масштабируемость
- отказоустойчивость
- реактивность
Основное отличие от akka — изначально поддерживаемая динамическая загрузка акторов из внешних пакетов, что позволяет распространять акторы между процессами и хостами, не перезапуская систему, строить и конфигурировать систему из набора готовых блоков, которые могут храниться как в общедоступных, так и в приватных репозиториях готовых решений. Система представляет собой, в общем случае, множество процессов (из модуля multiprocessing) обмен между которыми происходит через TCP каналы. Внутри процесса акторы обрабатывают сообщения в отдельных корутинах, обмениваясь сообщениями через "asyncio.Queue".
В Python есть проблема конфликта зависимостей, другими словами, мы не можем загрузить две различные версии одного и того же пакета. Библиотека позволяет обойти эти ограничения. Акторы, ссылающиеся на различные версии одного и того же пакета, могут быть размещены в разных процессах и не создавать конфликта, поскольку процессы являются, практически, изолированными друг от друга.
Установка
Установить библиотеку peacepie можно с помощью менеджера пакетов pip, выполнив следующую команду:
pip install --extra-index-url=https://test.pypi.org/simple peacepie
Ознакомление
Создаем проект с любым именем. С помощью команды, приведенной выше, устанавливаем библиотеку peacepie в проект. Создаем скрипт, приведенный ниже, и запускаем его первый раз без параметров. При запуске скрипта без параметров библиотека формирует окружение по умолчанию. При повторных запусках скрипт лучше запускать с параметром "./config/peacepie.cfg". При первоначальной инициализации происходит скачивание более десятка библиотек из удаленных репозиториев, что занимает некоторое время.
import asyncio
import multiprocessing
import sys
from peacepie import PeaceSystem
multiprocessing.set_start_method('spawn', force=True)
async def main():
param = sys.argv[1] if len(sys.argv) > 1 else None
pp = PeaceSystem(param)
await pp.start()
try:
await pp.task
except asyncio.CancelledError:
pass
if __name__ == '__main__':
asyncio.run(main())
В случае удачного запуска приложения по адресу http://localhost:9090 станет доступным простейший веб-интерфейс. В случае если порт занят, в скрипте ./config/app_starter_example.py измените порт на любой доступный и перезапустите скрипт.
В веб-интерфейсе присутствует четыре уровня: главный администратор, список администраторов процессов, список акторов, актор. Главный администратор присутствует на всех уровнях, администраторы процессов - на всех уровнях, кроме уровня главного администратора. Это связано с тем, что указанные акторы выполняют в системе сразу несколько ролей. Отправлять команды в систему можно только с уровня актора. Все страницы акторов для отправки сообщений равнозначны, единственное различие - поле "Получатель" заполняется именем текущего актора, но его можно изменить.
Из двух кнопок "ASK" и "SEND" лучше выбирать "ASK", поскольку режим "ASK" подразумевает содержательный ответ от исполнителя. Исключение, приходящее на ум,- команда "exit", по которой система незамедлительно закрывается, ответ не предусматривается и доставка становится невозможной в закрывающейся системе. Еще одна команда, которую лучше отправлять с помощью "SEND", - это команда "recreate_actor" в отношении актора типа "SimpleWebFace", который обеспечивает веб-интерфейс.
Ознакомление начнем со стандартного "Hello, World!". Выполняем команду:
| Поле | Значение |
|---|---|
| Комманда | create_actor |
| Тело | {"class_desc": {"requires_dist": "peacepie_example", "class": "HelloWorld"}, "name": "hello_world"} |
| Получатель | first.main.admin |
В результате создастся новый актор типа HelloWorld из пакета peacepie_example, имя можно задать любое, пакет, если пакет еще не кеширован на локальной машине, будет скачан из удаленного репозитория. Если отправить команду "tick" в адрес созданного актора, используя его имя, то актор будет выводить в консоль сообщение "Hello, World!" и возвращать ответ с командой "hello_world"
| Поле | Значение |
|---|---|
| Команда | tick |
| Тело | |
| Получатель | hello_world |
Удалить вновь созданный актор можно командой
| Поле | Значение |
|---|---|
| Команда | remove_actor |
| Тело | {"name": "hello_world"} |
| Получатель | first.main.admin |
Следующий актор похож на предыдущий, но выводит сообщение "Hello, World!" в консоль с заданной периодичностью после получения команды "tick_start". Кроме периодичности можно еще задать лимит сообщений. При заданном лимите актор выведет ограниченное число сообщений.
| Поле | Значение |
|---|---|
| Команда | create_actor |
| Тело | {"class_desc": {"requires_dist": "peacepie_example", "class": "IteratingHelloWorld"}, "name": "iterating_hello_world"} |
| Получатель | first.main.admin |
| Поле | Значение |
|---|---|
| Команда | set_params |
| Тело | {"params": [{"name": "period", "value": 2}, {"name": "limit", "value": null}]} |
| Получатель | iterating_hello_world |
| Поле | Значение |
|---|---|
| Команда | tick_start |
| Тело | |
| Получатель | iterating_hello_world |
Создаем новый процесс:
| Поле | Значение |
|---|---|
| Команда | create_process |
| Тело | |
| Получатель | first.main.admin |
И перемещаем в него наш объект:
| Поле | Значение |
|---|---|
| Команда | recreate_actor |
| Тело | {"node": "first.process_0.admin", "entity": "iterating_hello_world"} |
| Получатель | first.main.admin |
Остановить вывод можно с помощью команды "tick_stop"
| Поле | Значение |
|---|---|
| Команда | tick_stop |
| Тело | |
| Получатель | iterating_hello_world |
Удаляем актор командой
| Поле | Значение |
|---|---|
| Команда | remove_actor |
| Тело | {"name": "iterating_hello_world"} |
| Получатель | first.process_0.admin |
Командой "exit" завершаем выполнение примера. Получатель можем быть любым, поскольку команда "exit" всегда передается главному администратору.
| Поле | Значение |
|---|---|
| Комманда | exit |
| Тело | |
| Получатель | first.main.admin |
Следующий пример более интересный. Создаем актор типа CircleStarter
| Поле | Значение |
|---|---|
| Команда | create_actor |
| Тело | {"class_desc": {"requires_dist": "peacepie_example", "class": "CircleStarter"}, "name": "circle_starter"} |
| Получатель | first.main.admin |
Устанавливаем параметры созданного актора
| Поле | Значение |
|---|---|
| Команда | set_params |
| Тело | {"params": [{"name": "process_count", "value": 3}, {"name": "dancers_per_process", "value": 2}, {"name": "period", "value": 4}]} |
| Получатель | circle_starter |
Далее запускаем процесс
| Поле | Значение |
|---|---|
| Команда | begin |
| Тело | |
| Получатель | circle_starter |
Стартер "circle_starter" создаст 3 процесса и в каждом по 2 актора типа CircleDancer, каждому актору CircleDancer присваивается ссылка на следующий актор, последний актор ссылается на первый. Поведение акторов CircleDancer очень простое - при получении сообщения с командой "tick" актор через период времени заданный в параметре "period" передает сообщение следующему актору. В итоге получается, что сообщение циркулирует по кругу. Сообщение передается как внутри процесса, так и между процессами. Следующая серия команд создает еще один процесс с актором CircleDancer внутри и встраивает вновь созданный актор в круг акторов, созданных ранее.
| Поле | Значение |
|---|---|
| Команда | create_process |
| Тело | |
| Получатель | first.main.admin |
| Поле | Значение |
|---|---|
| Команда | create_actor |
| Тело | {"class_desc": {"requires_dist": "peacepie_example", "class": "CircleDancer"}, "name": "dancer_x"} |
| Получатель | first.process_2.admin |
| Поле | Значение |
|---|---|
| Команда | set_params |
| Тело | {"params": [{"name": "consumer", "value": "dancer_00"}, {"name": "period", "value": 10}]} |
| Получатель | dancer_x |
| Поле | Значение |
|---|---|
| Команда | set_params |
| Тело | {"params": [{"name": "consumer", "value": "dancer_x"}]} |
| Получатель | dancer_05 |
Командой "exit" завершаем выполнение примера
| Поле | Значение |
|---|---|
| Комманда | exit |
| Тело | |
| Получатель | first.main.admin |
Репозитарий
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file peacepie-0.2.0.tar.gz.
File metadata
- Download URL: peacepie-0.2.0.tar.gz
- Upload date:
- Size: 41.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 colorama/0.4.4 importlib-metadata/4.6.4 keyring/23.5.0 pkginfo/1.12.1.2 readme-renderer/34.0 requests-toolbelt/0.9.1 requests/2.25.1 rfc3986/1.5.0 tqdm/4.57.0 urllib3/1.26.5 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd8989082cc77bf66f582404f13c979e6492babdc17e32f45ad7bdcc56036f5c
|
|
| MD5 |
b08bc4afd259379d2a9a903faeddaccf
|
|
| BLAKE2b-256 |
d1152e6f4707d7c1915906cfd28c11d72d74467eef543fde68d3c70d67be3d81
|
File details
Details for the file peacepie-0.2.0-py3-none-any.whl.
File metadata
- Download URL: peacepie-0.2.0-py3-none-any.whl
- Upload date:
- Size: 53.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 colorama/0.4.4 importlib-metadata/4.6.4 keyring/23.5.0 pkginfo/1.12.1.2 readme-renderer/34.0 requests-toolbelt/0.9.1 requests/2.25.1 rfc3986/1.5.0 tqdm/4.57.0 urllib3/1.26.5 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acb760bb988ad78f0e9d054d27b1f026a3142a7aba5a2ed69942d7eef8fb38ea
|
|
| MD5 |
7cfe6a6212c6cdd9dbb78a4f81c7a419
|
|
| BLAKE2b-256 |
45be6912c868759b88c7dac4b71adcd895e6eab0da822a22092e64369bec9790
|