Русский
Русский
English
Статистика
Реклама

Recovery mode Еще один фреймворк

Основная концепция работыОсновная концепция работы

Вчера я зарелизил свой первый Python фреймворк. Нет, не еще один. Это в мире - еще один. А для меня пока что первый. И я допускаю, что он первый в своем роде. Это фреймворк для создания кастомных серверов. И создаваться они будут через конфиг. Ух, насоздаем сейчас...


Вначале был конфиг

Итак, конфиг. Поскольку к этому моменту фреймворк мы уже установили. А если нет, то это легко и просто делается командой:

pip3 install idewavecore==0.0.1

Это при условии наличия у вас Python 3.6+, интернета и компьютера.

Сам конфиг при этом выглядит примерно вот так:

# settings.ymlsettings:  servers: !inject config_dir/servers.yml  db_connections:    sqlite:      host: ~      username: ~      password: ~      # default mysql 3306, postgresql 5432, sqlite don't need port      port: ~      # currently allowed: mysql, postgresql, sqlite      dialect: sqlite      # supported drivers:      # mysql: mysqlconnector, pymysql, pyodbc      # postgresql: psycopg2, pg8000, pygresql      driver: ~      # to use with sqlite this should be absolute db path      # can be empty to keep db in memory (sqlite only)      db_name: ~      charset: ~

Где !inject - это специальный тэг для импорта других yaml файлов. Что очень удобно, если нужно разбить огромную yaml-простыню на набор аккуратных мини-конфигов.

# servers.ymlsample_server:  connection:    host: 1.2.3.4    port: 1234    # possible values: tcp, websocket    connection_type: tcp  # optional  proxy:    host: ~    port: ~    # possible values: tcp, websocket    connection_type: tcp  options:    server_name: Sample Server    is_debug: false  middlewares: !pipe    - !fn native.test.mock_middleware    - !fn native.test.mock_middleware    - !infinite_loop        - !fn native.test.mock_middleware        - !fn native.test.mock_middleware        - !fn native.test.mock_middleware        - !router            ROUTE_1: !fn native.test.mock_middleware            ROUTE_2: !fn native.test.mock_middleware            ROUTE_3:              - !fn native.test.mock_middleware              - !fn native.test.mock_middleware              - !fn native.test.mock_middleware  # optional  db_connection: sqlite

Здесь уже побольше тэгов.

!pipe - это специальный тэг, который создает обертку над функциями в массиве. На данный момент все функции, используемые в разделе middlewares (о них - чуть ниже), должны быть обернуты в пайп. Вкратце - пайп выполняет поочередно переданные в него функции и пробрасывает в них необходимые параметры.

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

!router - это специальный тэг, который создает маршрутизируемый пайп. Фактически, создается словарь пайпов и какой из них выполнить, роутер определяет по специальному параметру (route).

И, наконец, !fn - специальный тэг, который позволяет импортировать функцию (далее - middleware) по указанному пути. Мой фреймворк предоставляет некоторое количество миддлвэров, но можно написать свои - достаточно создать в корне своего проекта одноименную папку - middlewares - и далее создать там файлы с необходимыми функциями. Далее, чтобы использовать вашу функцию, достаточно будет вызвать тэг:

!fn <имя_вашего_файла>.<имя_функции>

И строка будет преобразована в миддлвэр. Название корневой папки (middlewares) указывать не нужно - оно будет подставлено автоматически при импорте. Если же вы хотите использовать нативные миддлвэры фреймворка (есть! я использовал три заимствованных слова подряд!), достаточно указать префикс native в пути к функции, например:

!fn native.test.mock_middleware

В целом, большой акцент сделан именно на работу с конфигом.

Middle where

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

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

from idewavecore.session import Storage, ItemFlagasync def sample_middleware(**kwargs):    global_storage: Storage = kwargs.pop('global_storage')    server_storage: Storage = kwargs.pop('server_storage')    session_storage: Storage = kwargs.pop('session_storage')    session_storage.set_items([        {            'key1': {                'value': 'some_tmp_value'            }        },        {            'key2': {                'value': 'some_persistent_value',                'flags': ItemFlag.PERSISTENT            }        },        {            'key3': {                'value': 'some_persistent_constant_value',                'flags': ItemFlag.PERSISTENT | ItemFlag.FROZEN            }        },        {            'key4': {                'value': 'some_constant_value',                'flags': ItemFlag.FROZEN            }        }    ])    value_of_key3 = session_storage.get_value('key3')

Каждый миддлвэр имеет доступ к одному из трех типов хранилищ (storage). Хранилища бывают трех типов: глобальное (global storage), хранилище сервера (server storage) и хранилище сессии (session storage).

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

Хранилище сервера используется для хранения соединений и в основном используется для броадкаста.

Хранилище сессий создается персонально для каждого клиентского соединения и хранит данные в пределах этого соединения.

В основном в миддлвэрах будет использоваться именно хранилище сессии.

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

Запускаем...

Теперь наконец пора применить то, без чего не обходится ни одно нормальное приложение на базе моего фреймворка - Assembler. Не совсем тот, но тоже производит сборку. Примерно так:

# run.pyimport asynciofrom idewavecore import Assemblerfrom idewavecore.session import Storageif __name__ == '__main__':    loop = asyncio.get_event_loop()    global_storage = Storage()    assembler = Assembler(        global_storage=global_storage,        # ваш путь к конфигу        config_path='settings.yml'    )    servers = assembler.assemble()    for server in servers:        server.start()    loop.run_until_complete(        asyncio.gather(*[server.get() for server in servers])    )    try:        loop.run_forever()    except KeyboardInterrupt:        pass    finally:        loop.close()

Запускаем в терминале - и можем лицезреть (при условии, что вы все сделали правильно) сообщения о том, что серверы запущены. Теперь к ним можно пробовать достучаться всеми возможными способами - браузер, curl, клиент mmo rpg игры...

Что теперь

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

Присоединяйтесь https://github.com/idewave/idewavecore.

Источник: habr.com
К списку статей
Опубликовано: 21.02.2021 20:17:01
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Python

Программирование

Python3

Idewavecore

Фреймворк

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru