Лайфхаки

Маленькие, полезные хитрости

Рабочий процесс проекта Python. Потоки

24.05.2023 в 04:27

Рабочий процесс проекта Python. Потоки

Semaphore прост в понимании, если его представить в виде объекта, который ограничивает выполнение блока кода установленным количеством, по умолчанию это 1. При каждом вхождении в блок кода Semaphore счетчик уменьшается. Если счетчик дошел до 0, все потоки блокируются, и пока поток не освободит семафор, другие будут ждать разрешения подключиться.

Посмотрим Semaphore на примере реализации очереди из реального кейса.

``` import datetime from threading import Semaphore, Thread from time import sleep s = Semaphore(3) def semaphore_func(payload: int): s.acquire() now = datetime.datetime.now().strftime('%H:%M:%S') print(f'{now=}, {payload=}') sleep(2) s.release() threads = for t in threads: t.start() for t in threads: t.join() ```

В результате увидим, что функция выполнялась группами по 3 потока. То есть одновременно не может выполняться кусок кода с блокировкой через Semaphore больше, чем указан в инициализации класса Semaphore . Видим паузы в 2 секунды между блокировками.

``` now='00:49:51', payload=0 now='00:49:51', payload=1 now='00:49:51', payload=2 now='00:49:53', payload=3 now='00:49:53', payload=5 now='00:49:53', payload=4 now='00:49:55', payload=6 ```

Это удобно использовать, например, в таком виде: если база данных может держать не более 30 соединений, то инстанциируем Semaphore со значением 30. Блокируем, когда поднимаем соединение и разблокируем, когда освобождаем.

Есть несколько способов синхронизации потоков, которые подходят для тех или иных ситуации. Примеры можно посмотреть в документации .

Теперь поговорим об освобождении GIL.

CPython управляет памятью с помощью подсчета ссылок. То есть для каждого объекта Python подсчитывается, сколько на него указывается ссылок с других объектов, использующих его в данный момент. При добавлении ссылки счетчик увеличивается, при удалении ссылки счетчик уменьшается. А когда счетчик ссылок становится 0 — это означает, что объект больше не нужен, и его можно удалить из памяти.

Следовательно, если не будет GIL, который запрещает Python процессу выполнять более одной команды байт-кода в каждый момент времени, то при подсчете ссылок может случиться Race-condition, с подсчетом ссылок на объекты, как это было в примере с переменными выше.

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

Стало быть, если мы сделаем библиотеку, даже с CPU-bound нагрузкой, где мы не взаимодействуем с объектами Python (словарями, списками, целыми числами и т. д.) или большая часть библиотеки не взаимодействует, то мы можем освободить GIL. Например, библиотеки hashlib и NumPy выполняют расчеты на чистом C и освобождают GIL.

time.sleep() — реализация этой функции освобождает GIL и выполняется на уровне системы и работает вне кода Python.

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

Github тесты. Общие сведения о примере

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

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

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

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

Изменяет разрешения по умолчанию, предоставленныеGITHUB_TOKEN. Зависит от потребностей рабочего процесса. Дополнительные сведения см. в разделе Назначение разрешений для заданий .

Создает группу параллелизма для определенных событий и использует оператор||для определения резервных значений. Дополнительные сведения см. в разделе Использование параллелизма .

Настраивает задание для запуска в средстве выполнения тестов, размещенном в GitHub, или в локальном средстве выполнения тестов в зависимости от репозитория, выполняющего рабочий процесс. В этом примере задание будет выполняться в локальном средстве выполнения тестов, если репозиторий называетсяdocs-internalи находится в организацииgithub. Если репозиторий не соответствует этому пути, задание будет выполняться в средстве выполнения тестовubuntu-latest, размещенном в GitHub. Дополнительные сведения об этих параметрах см. в разделе Выбор средства выполнения тестов для задания .

Ключевое словоusesсообщает заданию, что нужно получить действие с именемactions/checkout. Это действие, которое извлекает репозиторий и загружает его в средство выполнения, позволяя выполнять действия в коде (например, средства тестирования). Действие извлечения необходимо использовать в любой момент, когда рабочий процесс будет выполняться в коде репозитория или если вы используете действие, определенное в репозитории.

На этом шаге используется действиеactions/setup-nodeдля установки указанной версии пакета программного обеспечения Node.js в средстве выполнения тестов, которое предоставляет доступ к командеnpm.

Использует действиеtrilom/file-changes-actionдля сбора всех измененных файлов. Этот пример закреплен к определенной версии действия с помощью SHAa6ca26c14274c33b15e6499323aac178af06ad4b.

На этом шаге используется командаrunдля выполнения скрипта, хранящегося в репозиторииscript/rendered-content-link-checker.mjs, которая передает все необходимые параметры.

На этом шаге используется командаrunдля выполнения скрипта, хранящегося в репозиторииscript/rendered-content-link-checker.mjs, которая передает другой набор параметров.

Деплой на гитхаб.

Этот способ развёртывания подходит для проектов, которые будут в общем доступе или разрабатываются несколькими специалистами.

В этой инструкции мы опишем размещение проекта наи его последующее клонирование на хостинг.

Файл

Предварительная настройка github

Сначала нужно настроить SSH-подключение с аутентификацией по ключу.

Настройка SSH-подключения с аутентификацией по ключу

Перейдите в папку проекта и запустите GitBash — выберите Git Bash Here в контекстном меню:

В открывшейся консоли введите:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Эта команда сгенерирует новую пару ключей и отправит об этом уведомление на указанную почту.

Далее перейдите к строке:

Здесь укажите имя для файлов с ключами.

После завершения работы алгоритма проверьте наличие файлов с ключами в папке:

Теперь добавьте ключи к SSH-агенту. Для этого запустите агент в фоновом режиме:

Затем выполните команду:

ssh-add ~/.ssh/your_file_name

В строкеyour_file_nameукажите имя файла, которое вы задали при генерации пары ключей.

Когда ключи добавлены к SSH-агенту, публичный ключ из файла * ./pub нужно разместить в аккаунте на github.

Здесь нажмите кнопку New SSH key и вставьте содержимое файла your_file_name.pub .

Проверить правильность работы ключей можно такой командой:

$ ssh -T git@github.com #Output Hi User_Name ! You've successfully authenticated, but GitHub does not provide shell access.

Как запустить проект с github Python. How to deploy Django apps to Python Anywhere through GitHub?

GitHub is a web-based interface that uses Git, the open source version control software that lets multiple people make separate changes to web pages at the same time. As Carpenter notes, because it allows for real-time collaboration, GitHub encourages teams to work together to build and edit their site content. In this blog we will know how can we deploy Django apps to python.

Why use GitHub?

There are a number of reasons.. The first is that it enables slick and easycollaboration and version control. This allows you to work on code with anyone from anywhere. Additionally, many employers use GitHub. So, if you plan on getting a job, you’ll look really good if you already know your way around GitHub. And don’t forget about the connections, learning, and portfolio aspects. GitHub is a robust learning and collaboration platform. Take time to explore it and see just how much it can expand your programming knowledge.

Common terms for GitHub

  • Repository (repo) — a folder in which all files and their version histories are stored.
  • Branch — a workspace in which you can make changes that won’t affect the live site.
  • Markdown (.md) — a way to write in Github that converts plain text to GitHub code.
    Sites such as Atom and Sublime Text are examples of free resources for developers
    using Markdown.
  • Commit Changes — a saved record of a change made to a file within the repo.
  • Pull Request (PR) — the way to ask for changes made to a branch to be merged into
    another branch that also allows for multiple users to see, discuss and review work
    being done.
  • Merge — after a pull request is approved, the commit will be pulled in (or merged) from one branch to another and then, deployed on the live site
  • Issues — how work is tracked when using git. Issues allow users to report new tasks and content fixes, as well as allows users to track progress on a project board from beginning to end of a specific project.
  • Federalist — a platform that securely deploys a website from a GitHub repository in minutes and lets users preview proposed and published changes.

How do I Use a GitHub?

1. Sign up for GitHub
2. Install Git
3. Create a Repository
4. Create a Branch
5. Create and Commit Changes to a Branch
6. Open a Pull Request
7. Merge Your Pull Request

So, I thought it would be amazing if we can just push code onto GitHub and GitHub automatically updates the code on PythonAnywhere and not to mention the default features that are provided by GitHub like Pull Requests, Issues, Actions(haven’t used them till now still a feature) and everything else that GitHub offers.

How?


tell our Django Web-App tha it has been updated so it pulls the latest code.

Step 2: Write the view function that will receive the update and update the code on the server.
Go to your views.py and add the following code:


“HttpResponse” that will be returned.

Step 3: Set the URL where the Payload from GitHub will be sent.

To add the payload URL add the following lines into urls.py file of your Django Project:

Step 4: Now push this code to GitHub and login to our account on PythonAnywhere.

Now follow the following steps:
1: Open a bash terminal on PythonAnywhere.
2: Issue the following command:

after this command you will be shown the following prompt:

3: When you’re prompted to “Enter a file in which to save the key,” press Enter. This accepts the default file location.

4: At the prompt, type a secure passphrase.

5: Issue the following command on the bash terminal of PythonAnywhere to get your key.

Step 5: Go to your GitHub Account and then Go to the Repository in which you have your Django Project.
Then follow the following steps:
1: From your repository, click Settings as shown below.
2: In the sidebar, click Deploy Keys, then click Add deploy key.

3: Provide a title, paste in your public key.

4: Select Allow write access if you want this key to have write access to the repository. A deploy key with write access lets a deployment push to the repository.
5: Click Add key.

Step 6: Go to your PythonAnywhere account and go to the bash terminal and setup your Web-App but use the SSH instead of HTTPS for cloning your Repository from GitHub.

Note: I would suggest to use the automated script pa_autoconfigure_django.py available in pythonanywhere package which can be installed via pip to automatically setup my project on PythonAnywhere.