Skip to content

Commit

Permalink
run: split into "web" and "worker" sub-commands
Browse files Browse the repository at this point in the history
  • Loading branch information
slint committed May 24, 2024
1 parent 4dec095 commit d99a84f
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 59 deletions.
103 changes: 82 additions & 21 deletions invenio_cli/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@
from .packages import packages
from .services import services
from .translations import translations
from .utils import handle_process_response, pass_cli_config, run_steps
from .utils import (
combine_decorators,
handle_process_response,
pass_cli_config,
run_steps,
)


@click.group()
Expand Down Expand Up @@ -142,48 +147,104 @@ def init(flavour, template, checkout, user_input, config):
cookiecutter_wrapper.remove_config()


@invenio_cli.command()
@click.option("--host", "-h", default="127.0.0.1", help="The interface to bind to.")
@click.option("--port", "-p", default=5000, help="The port to bind to.")
@click.option(
"--debug/--no-debug",
"-d/",
default=True,
is_flag=True,
help="Enable/disable debug mode including auto-reloading " "(default: enabled).",
)
@click.option(
@invenio_cli.group("run", invoke_without_command=True)
@click.pass_context
def run_group(ctx):
"""Run command group."""
# For backward compatibility
if ctx.invoked_subcommand is None:
ctx.invoke(run_all)


services_option = click.option(
"--services/--no-services",
"-s/-n",
default=True,
is_flag=True,
help="Enable/disable dockerized services (default: enabled).",
)
@click.option(
"--celery-log-file",
default=None,
help="Celery log file (default: None, this means logging to stderr)",
web_options = combine_decorators(
click.option("--host", "-h", default="127.0.0.1", help="The interface to bind to."),
click.option("--port", "-p", default=5000, help="The port to bind to."),
click.option(
"--debug/--no-debug",
"-d/",
default=True,
is_flag=True,
help="Enable/disable debug mode including auto-reloading "
"(default: enabled).",
),
)


@run_group.command("web")
@services_option
@web_options
@pass_cli_config
def run(cli_config, host, port, debug, services, celery_log_file):
"""Starts the local development server.
def run_web(cli_config, host, port, debug, services):
"""Starts the local development web server."""
if services:
cmds = ServicesCommands(cli_config)
response = cmds.ensure_containers_running()
# fail and exit if containers are not running
handle_process_response(response)

commands = LocalCommands(cli_config)
processes = commands.run_web(host=host, port=str(port), debug=debug)
for proc in processes:
proc.wait()


worker_options = combine_decorators(
click.option(
"--celery-log-file",
default=None,
help="Celery log file (default: None, this means logging to stderr)",
),
)


@run_group.command("worker")
@services_option
@worker_options
@pass_cli_config
def run_worker(cli_config, services, celery_log_file):
"""Starts the local development server."""
if services:
cmds = ServicesCommands(cli_config)
response = cmds.ensure_containers_running()
# fail and exit if containers are not running
handle_process_response(response)

NOTE: this only makes sense locally so no --local option
"""
commands = LocalCommands(cli_config)
processes = commands.run_worker(celery_log_file=celery_log_file)
for proc in processes:
proc.wait()


@run_group.command("all")
@services_option
@web_options
@worker_options
@pass_cli_config
def run_all(cli_config, host, port, debug, services, celery_log_file):
"""Starts web and worker development servers."""
if services:
cmds = ServicesCommands(cli_config)
response = cmds.ensure_containers_running()
# fail and exit if containers are not running
handle_process_response(response)

commands = LocalCommands(cli_config)
commands.run(
processes = commands.run_all(
host=host,
port=str(port),
debug=debug,
services=services,
celery_log_file=celery_log_file,
)
for proc in processes:
proc.wait()


@invenio_cli.command()
Expand Down
11 changes: 11 additions & 0 deletions invenio_cli/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,14 @@ def handle_process_response(response, fail_message=None):
click.secho(msg, fg="yellow")
elif response.output:
click.secho(message=response.output, fg="green")


def combine_decorators(*decorators):
"""Combine multiple decorators."""

def _decorator(f):
for dec in reversed(decorators):
f = dec(f)
return f

return _decorator
90 changes: 52 additions & 38 deletions invenio_cli/commands/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,50 +115,27 @@ def update_statics_and_assets(self, force, flask_env="production", log_file=None
break
return response

def run(self, host, port, debug=True, services=True, celery_log_file=None):
"""Run development server and celery queue."""
def _handle_sigint(self, name, process):
"""Terminate services on SIGINT."""
prev_handler = signal.getsignal(signal.SIGINT)

def signal_handler(sig, frame):
click.secho("Stopping server and worker...", fg="green")
server.terminate()
if services:
worker.terminate()
click.secho("Server and worker stopped...", fg="green")
def _signal_handler(sig, frame):
click.secho(f"Stopping {name}...", fg="green")
process.terminate()
click.secho(f"{name} stopped...", fg="green")
if prev_handler is not None:
prev_handler(sig, frame)

signal.signal(signal.SIGINT, signal_handler)

if services:
click.secho("Starting celery worker...", fg="green")

celery_command = [
"pipenv",
"run",
"celery",
"--app",
"invenio_app.celery",
"worker",
"--beat",
"--events",
"--loglevel",
"INFO",
"--queues",
"celery,low",
]

if celery_log_file:
celery_command += [
"--logfile",
celery_log_file,
]

worker = popen(celery_command)
signal.signal(signal.SIGINT, _signal_handler)

def run_web(self, host, port, debug=True):
"""Run development server."""
click.secho("Starting up local (development) server...", fg="green")
run_env = environ.copy()
run_env["FLASK_ENV"] = "development" if debug else "production"
run_env["INVENIO_SITE_UI_URL"] = f"https://{host}:{port}"
run_env["INVENIO_SITE_API_URL"] = f"https://{host}:{port}/api"
server = popen(
proc = popen(
[
"pipenv",
"run",
Expand All @@ -177,6 +154,43 @@ def signal_handler(sig, frame):
],
env=run_env,
)

self._handle_sigint("Web server", proc)
click.secho(f"Instance running!\nVisit https://{host}:{port}", fg="green")
server.wait()
return [proc]

def run_worker(self, celery_log_file=None):
"""Run Celery worker."""
click.secho("Starting celery worker...", fg="green")

celery_command = [
"pipenv",
"run",
"celery",
"--app",
"invenio_app.celery",
"worker",
"--beat",
"--events",
"--loglevel",
"INFO",
"--queues",
"celery,low",
]

if celery_log_file:
celery_command += [
"--logfile",
celery_log_file,
]

proc = popen(celery_command)
self._handle_sigint("Celery worker", proc)
click.secho("Worker running!", fg="green")
return [proc]

def run_all(self, host, port, debug=True, services=True, celery_log_file=None):
"""Run all services."""
return [
*self.run_web(host, port, debug),
*self.run_worker(celery_log_file),
]

0 comments on commit d99a84f

Please sign in to comment.