Цель
Я хочу создать локальное приложение для создания составных докеров таким образом, чтобы у меня было 5 служб.
- Redis
- Postgres
- RabbitMQ
- Django API
- Django Worker
В этом развертывании пользователь загружает файл через конечную точку API. Эта конечная точка сохранит файл в поле FileField
в модели.
В отдельной транзакции пользователь будет запускать асинхронную задачу через отдельную конечную точку. Это задание будет отвечать за
- загрузку файла
- извлечение файла
- пинать подзадачи для выполнения
intermediate processing steps
- загрузить файлрезультаты обработки в базу данных
intermediate processing steps
НЕ ДОЛЖЕН загружать какие-либо файлы в базу данных.
intermediate processing steps
должен использовать внутреннее хранилище файлов djangoРешение для загрузки и загрузки файлов там. Это реализовано с помощью иерархии файловой системы, которая не относится к этому вопросу.
Проблема
Мне удалось заставить мою локальную файловую систему работать с этой конфигурацией. Если я запускаю бэкэнд из redis
, postgres
и rabbitmq
. А затем я запускаю API и Worker на своей машине локально, все работает нормально.
Когда я создаю конфигурацию docker-compose
и отсоединяю все. Операция, кажется, сломана. И в моем журнале docker-compose, что я вижу:
worker_1 | [2019-10-23 22:27:34,626: WARNING/ForkPoolWorker-2] //--------------------------------------------------------------------------------
worker_1 | [2019-10-23 22:27:34,627: WARNING/ForkPoolWorker-2] // BEGINNING TASK
worker_1 | [2019-10-23 22:27:34,627: WARNING/ForkPoolWorker-2] //--------------------------------------------------------------------------------
worker_1 | [2019-10-23 22:27:34,628: WARNING/ForkPoolWorker-2] // Root Job - 183916ca-f6e6-4e7c-a997-e8f516ccf8be
worker_1 | [2019-10-23 22:27:34,628: WARNING/ForkPoolWorker-2] // Parent Job - None
worker_1 | [2019-10-23 22:27:34,628: WARNING/ForkPoolWorker-2] // Current Job - 183916ca-f6e6-4e7c-a997-e8f516ccf8be
worker_1 | [2019-10-23 22:27:34,628: WARNING/ForkPoolWorker-2] //--------------------------------------------------------------------------------
worker_1 | [2019-10-23 22:27:34,629: WARNING/ForkPoolWorker-2] // PERFORMING DATA SET PRE PROCESSING
worker_1 | [2019-10-23 22:27:34,629: WARNING/ForkPoolWorker-2] //--------------------------------------------------------------------------------
worker_1 | [2019-10-23 22:27:34,629: WARNING/ForkPoolWorker-2] {'data_set_id': 1, 'starting_node': 'Live', 'organization_id': 1}
worker_1 | [2019-10-23 22:27:34,630: WARNING/ForkPoolWorker-2] Downloading the files required to run!
worker_1 | [2019-10-23 22:27:34,645: WARNING/ForkPoolWorker-2] Downloading remote file `organizations/1/data_sets/flow_cytometry/triple_hello_world_payload.tgz`
worker_1 | [2019-10-23 22:27:34,646: WARNING/ForkPoolWorker-2] Exists: `False`
worker_1 | [2019-10-23 22:27:34,646: WARNING/ForkPoolWorker-2] ERROR occured: [Errno 2] No such file or directory: '/opt/api_webserver/media/organizations/1/data_sets/flow_cytometry/triple_hello_world_payload.tgz'.
worker_1 | [2019-10-23 22:27:34,653: INFO/ForkPoolWorker-2] Task api.versions.v1.tasks.main_task.main_task[183916ca-f6e6-4e7c-a997-e8f516ccf8be] succeeded in 0.02647909999359399s: {'iteration': 0, 'completion': 0, 'status': 'ERROR', 'message': 'Excecuting `main_task` failed!', 'error': 'Error in `main_task`: [Errno 2] No such file or directory: \'/opt/api_webserver/media/organizations/1/data_sets/flow_cytometry/triple_hello_world_payload.tgz\'.'}
Если я захожу в worker
docker container
и проверяю файловую систему, путь НЕ существует для каталога media
ифайл.
Если я захожу в api
docker container
и проверяю файловую систему, существует ли путь для каталога и файла media
.
Соответствующий код
Я выигралне предоставляет код представления или API-код, поскольку API работает нормально.
Загрузка и извлечение файла обрабатываются в процессе workers
с использованием интерфейса django
default_storage
.
API интерфейса хранилища по умолчанию в Django
Эта проблема связана с работником, поэтому вот некоторые из связанных кодов.
worker.py
# Python Standard Libraries
import os
# Third-Party Libraries
import tempfile
# Custom
from models.data_set_model import DataSet
from tasks.helpers import download_remote_file
def download_data_set(data_set_id):
print("Downloading the files required to run!")
data_set = DataSet.objects.get(id=data_set_id)
remote_file_path = data_set.file.name
remote_file_name = os.path.basename(remote_file_path)
temporary_directory_path = tempfile.mkdtemp()
temporary_compressed_file_path = os.path.join(temporary_directory_path, remote_file_name)
download_remote_file(remote_file_path, temporary_compressed_file_path)
return temporary_compressed_file_path
helpers.py
# Python Standard Libraries
# N/A
# Third-Party Libraries
from django.core.files.storage import default_storage
# CustomLibraries
# N/A
def download_remote_file(remote_file_path, local_file_path):
print(f"Downloading remote file `{remote_file_path}`")
print(f"Exists: `{default_storage.exists(remote_file_path)}`")
remote_file_contents = None
with default_storage.open(remote_file_path) as remote_file_handle:
print("Reading file contents")
remote_file_contents = remote_file_handle.read()
print(f"Placing remote file contents into `{local_file_path}`")
with open(local_file_path, "wb") as local_file_handle:
local_file_handle.write(remote_file_contents)
нерешенные вопросы
- Что я делаю не так?
- Какой идиоматический способ загрузки файлов наработник из системы FileStorage API?
- Разве команда
default_storage.open()
не должна указывать на файловую систему API и иметь возможность загружать файлы? t - Если нет, то какие конфигурации я могу настроить на рабочем месте для поддержки этого?
- Работает ли это только локально, потому что файловая система является общей, ипричина в том, что
docker-compose
разбивает их на отдельные среды?