Параллельное выполнение на нескольких каталогах - PullRequest
0 голосов
/ 09 июля 2019

Я хотел бы создать несколько каталогов с несколькими файлами с одним make-файлом.

У меня есть такая структура каталогов:

conf_a/conf.json
conf_b/conf.json
main.py
Makefile
requirements.txt

И хотел бы набрать make conf_a и иметь новый каталог, подобный этому:

build/conf_a/conf.json
build/conf_a/main.py
build/conf_a/requirements.txt
conf_a/conf.json
conf_b/conf.json
main.py
Makefile
requirements.txt

Или что-то вроде make conf_b и с таким новым каталогом:

build/conf_b/conf.json
build/conf_b/main.py
build/conf_b/requirements.txt
conf_a/conf.json
conf_b/conf.json
main.py
Makefile
requirements.txt

Итак, я сделал Makefile так:

# Disable built-in rules and variables
MAKEFLAGS += --no-builtin-rules
MAKEFLAGS += --no-builtin-variables
.ONESHELL:
.SHELLFLAGS: -ec
.SILENT:

BUILD_DIR := $(CURDIR)/build
CONF_FILE := conf.json
FILES_TO_COPY := requirements.txt main.py

FUNCTION_DIRS := $(shell ls */$(CONF_FILE) | xargs -n 1 -I {} dirname {})
HIDDEN_FUNCTION_DIRS := $(shell ls .*/$(CONF_FILE) 2> /dev/null | xargs -n 1 -I {} dirname {})


clean:
    rm -rf $(BUILD_DIR)

all: clean $(FUNCTION_DIRS) deploy

$(FUNCTION_DIRS) $(HIDDEN_FUNCTION_DIRS):
    tmp=$@
    FUNCTION_DIR=$${tmp%/}
    export FUNCTION=$${FUNCTION_DIR#.}
    mkdir -p $(BUILD_DIR)/$$FUNCTION
    cp -f $(FILES_TO_COPY) $$FUNCTION_DIR/$(CONF_FILE) $(BUILD_DIR)/$$FUNCTION/

test:
    for FUNCTION in $(shell ls $(BUILD_DIR))
    do
        echo "Testing $$FUNCTION"
    done

deploy:
    for FUNCTION in $(shell ls $(BUILD_DIR))
    do
        echo "Deploying $$FUNCTION"
    done

Ну, это работает ...

Поэтому, если я хочу проверить настройку, я делаю: make conf_a test. Если я хочу развернуть: make conf_b deploy

Работает тихо, но цель test или deploy является последовательной (потому что цикл for) и могла бы быть параллельной.

Моя проблема в том, что у меня слишком много конфигурационных каталогов, и поскольку развертывание медленное, параллельное развертывание могло бы быть намного лучше.

Но я не знаю, как структурировать Makefile, чтобы сделать это таким образом.

Есть идеи?


По правде говоря, задача deploy развернуть облачную функцию GCP, а test просто запустить функцию локально

1 Ответ

0 голосов
/ 09 июля 2019

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

Например:

deploy: deploy_a deploy_b

deploy_a: conf_a
    echo deploying conf_a

deploy_b: conf_b
    echo deploying conf_b

Тогда вы можете make -j2 deploy и (вероятно) правила deploy_a и deploy_b будут обрабатываться параллельно. Но учтите, что это может не сильно помочь. Несмотря на то, что у вас есть отдельные процессы для двух развертываний, если вы развертываете оба на одном и том же локальном диске, они не смогут одновременно использовать запись в разные файлы на диске. В результате вы, вероятно, не увидите значительно лучшего времени для завершения, и оно может быть даже хуже.

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

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