Skip to content

Commit

Permalink
Merge pull request #114 from vkottler/dev/2.7.0
Browse files Browse the repository at this point in the history
2.7.0 - Use vcorelib uvloop wrapper
  • Loading branch information
vkottler authored Sep 13, 2023
2 parents c52757e + e1c2092 commit b03cad0
Show file tree
Hide file tree
Showing 22 changed files with 118 additions and 71 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
- run: |
mk python-release owner=vkottler \
repo=runtimepy version=2.6.8
repo=runtimepy version=2.7.0
if: |
matrix.python-version == '3.11'
&& matrix.system == 'ubuntu-latest'
Expand Down
7 changes: 1 addition & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ $(error target this Makefile with 'mk', not '$(MAKE)' ($(MK_INFO)))
endif
###############################################################################

.PHONY: all edit clean s
.PHONY: all edit clean

.DEFAULT_GOAL := all

Expand All @@ -17,8 +17,3 @@ all: $(DZ_PREFIX)sync yaml
edit: $(PY_PREFIX)edit

clean: $(PY_PREFIX)clean $(DZ_PREFIX)clean

# --curses
s:
./venv$(PYTHON_VERSION)/bin/runtimepy arbiter ./local/arbiter/test.yaml
+@echo "success"
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
=====================================
generator=datazen
version=3.1.3
hash=b00889b261f786062d9c52086554c0ff
hash=13de77cea2a96abdf252103ade6dd6db
=====================================
-->

# runtimepy ([2.6.8](https://pypi.org/project/runtimepy/))
# runtimepy ([2.7.0](https://pypi.org/project/runtimepy/))

[![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
![Build Status](https://github.com/vkottler/runtimepy/workflows/Python%20Package/badge.svg)
Expand Down Expand Up @@ -47,7 +47,7 @@ This package is tested on the following platforms:
```
$ ./venv3.11/bin/runtimepy -h
usage: runtimepy [-h] [--version] [-v] [-q] [--curses] [-C DIR]
usage: runtimepy [-h] [--version] [-v] [-q] [--curses] [--no-uvloop] [-C DIR]
{arbiter,tui,noop} ...
A framework for implementing Python services.
Expand All @@ -58,6 +58,7 @@ options:
-v, --verbose set to increase logging verbosity
-q, --quiet set to reduce output
--curses whether or not to use curses.wrapper when starting
--no-uvloop whether or not to disable uvloop as event loop driver
-C DIR, --dir DIR execute from a specific directory
commands:
Expand Down
23 changes: 0 additions & 23 deletions local/arbiter/tasks/old.py

This file was deleted.

27 changes: 27 additions & 0 deletions local/arbiter/tasks/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""
A module for testing application performance.
"""

# built-in
import asyncio

from runtimepy.net.arbiter import AppInfo

# internal
from runtimepy.net.stream.json import JsonMessageConnection


async def test(app: AppInfo) -> int:
"""A network application that doesn't do anything."""

conns = list(app.search(pattern="client", kind=JsonMessageConnection))

while not app.stop.is_set():
for conn in conns:
if not conn.disabled:
for _ in range(100):
conn.send_json({"null": None})

await asyncio.sleep(0.04)

return 0
16 changes: 7 additions & 9 deletions local/arbiter/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ includes:
- ../../tests/data/valid/connection_arbiter/echo_factories.yaml
- ../../tests/data/valid/connection_arbiter/ports.yaml

# - {name: runtimepy.net.arbiter.housekeeping.ConnectionMetricsLoggerFactory}
# factories:
# - {name: tasks.TuiApp}
factories:
- {name: runtimepy.net.arbiter.housekeeping.ConnectionMetricsLoggerFactory}

# - name: log_metrics
# factory: ConnectionMetricsLoggerFactory
# period_s: 10.0
# tasks:
# - {name: tui, factory: TuiApp, period_s: 0.01}
tasks:
- name: log_metrics
factory: ConnectionMetricsLoggerFactory
period_s: 1.0

# - [tasks.test, tasks.noop1, tasks.noop2]
app:
# - runtimepy.net.apps.wait_for_stop
- tasks.textual_testing.test
- tasks.test.test
3 changes: 2 additions & 1 deletion local/configs/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ description: A framework for implementing Python services.
entry: {{entry}}

requirements:
- vcorelib>=2.7.1
- vcorelib>=2.8.0
- websockets
- "windows-curses; sys_platform == 'win32'"

dev_requirements:
- pytest-asyncio
- setuptools-wrapper
- types-setuptools
- "uvloop; sys_platform != 'win32' and sys_platform != 'cygwin'"

commands:
- name: arbiter
Expand Down
4 changes: 2 additions & 2 deletions local/variables/package.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
major: 2
minor: 6
patch: 8
minor: 7
patch: 0
entry: runtimepy
7 changes: 7 additions & 0 deletions perf_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

set -e

# --no-uvloop
sudo chrt 90 "./venv$PYTHON_VERSION/bin/runtimepy" \
-C local/arbiter arbiter test.yaml
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta:__legacy__"

[project]
name = "runtimepy"
version = "2.6.8"
version = "2.7.0"
description = "A framework for implementing Python services."
readme = "README.md"
requires-python = ">=3.10"
Expand Down Expand Up @@ -41,7 +41,8 @@ test = [
"sphinx-book-theme",
"pytest-asyncio",
"setuptools-wrapper",
"types-setuptools"
"types-setuptools",
"uvloop; sys_platform != 'win32' and sys_platform != 'cygwin'"
]

[project.scripts]
Expand Down
4 changes: 2 additions & 2 deletions runtimepy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# =====================================
# generator=datazen
# version=3.1.3
# hash=cba19142d304f4387692458f31708575
# hash=b6c52ca304f4e018893aa3811b36d6af
# =====================================

"""
Expand All @@ -10,7 +10,7 @@

DESCRIPTION = "A framework for implementing Python services."
PKG_NAME = "runtimepy"
VERSION = "2.6.8"
VERSION = "2.7.0"

# runtimepy-specific content.
METRICS_NAME = "metrics"
4 changes: 3 additions & 1 deletion runtimepy/commands/arbiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ def app(args: _Namespace) -> int:
stop_sig.set()

return _run_handle_stop(
stop_sig, entry(stop_sig, args, window=args.window)
stop_sig,
entry(stop_sig, args, window=args.window),
enable_uvloop=not getattr(args, "no_uvloop", False),
)


Expand Down
9 changes: 8 additions & 1 deletion runtimepy/commands/tui.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ def start(args: _Namespace) -> int:
max_iterations=args.iterations,
)
stop_sig = _asyncio.Event()
_run_handle_stop(stop_sig, task.run(args.window, stop_sig=stop_sig))
_run_handle_stop(
stop_sig,
task.run(
args.window,
stop_sig=stop_sig,
),
enable_uvloop=not getattr(args, "no_uvloop", False),
)

return 0

Expand Down
1 change: 1 addition & 0 deletions runtimepy/dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ sphinx-book-theme
pytest-asyncio
setuptools-wrapper
types-setuptools
uvloop; sys_platform != 'win32' and sys_platform != 'cygwin'
2 changes: 2 additions & 0 deletions runtimepy/net/arbiter/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ def run(
signals: _Iterable[int] = None,
check_connections: bool = True,
config: _JsonObject = None,
enable_uvloop: bool = True,
) -> int:
"""Run the application until the stop signal is set."""

Expand All @@ -292,4 +293,5 @@ def run(
),
eloop=eloop,
signals=signals,
enable_uvloop=enable_uvloop,
)
2 changes: 1 addition & 1 deletion runtimepy/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
vcorelib>=2.7.1
vcorelib>=2.8.0
websockets
windows-curses; sys_platform == 'win32'
17 changes: 5 additions & 12 deletions tests/commands/test_arbiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,24 @@
"""

# module under test
from runtimepy import PKG_NAME
from runtimepy.entry import main as runtimepy_main

# internal
from tests.resources import resource
from tests.resources import base_args, resource


def test_arbiter_command_basic():
"""Test basic usages of the 'arbiter' command."""

base = base_args("arbiter")

assert (
runtimepy_main(
[PKG_NAME, "arbiter", "--init_only", str(resource("empty.yaml"))]
)
runtimepy_main(base + ["--init_only", str(resource("empty.yaml"))])
== 0
)

for entry in ["basic.yaml"]:
assert (
runtimepy_main(
[
PKG_NAME,
"arbiter",
str(resource("connection_arbiter", entry)),
]
)
runtimepy_main(base + [str(resource("connection_arbiter", entry))])
== 0
)
4 changes: 2 additions & 2 deletions tests/data/valid/connection_arbiter/json.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ clients:
local_addr: [localhost, "$udp_json"]

- factory: tcp_json
name: tcp_json
name: tcp_json_client
defer: true
kwargs: {host: localhost, port: "$tcp_json"}

- factory: websocket_json
name: websocket_json
name: websocket_json_client
defer: true
args: ["ws://localhost:$websocket_json"]

Expand Down
5 changes: 4 additions & 1 deletion tests/net/apps/test_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
from runtimepy.net.apps import wait_for_stop
from runtimepy.net.arbiter import ConnectionArbiter

# internal
from tests.resources import can_use_uvloop


def test_app_wait_for_stop():
"""Test the 'wait_for_stop' app method."""
Expand All @@ -18,4 +21,4 @@ def test_app_wait_for_stop():

# Just set the stop signal before the application runs.
stop.set()
assert arbiter.run() == 0
assert arbiter.run(enable_uvloop=can_use_uvloop()) == 0
7 changes: 5 additions & 2 deletions tests/net/arbiter/test_arbiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
SampleArbiterTask,
SampleTcpConnection,
SampleWebsocketConnection,
can_use_uvloop,
)


Expand All @@ -37,8 +38,10 @@ def test_connection_arbiter_run():
assert arbiter.task_manager.register(
SampleArbiterTask("sample"), period_s=0.05
)
assert arbiter.run(app=init_only) == 0
assert arbiter.run(app=assertion_failer) != 0
assert arbiter.run(app=init_only, enable_uvloop=can_use_uvloop()) == 0
assert (
arbiter.run(app=assertion_failer, enable_uvloop=can_use_uvloop()) != 0
)


@mark.asyncio
Expand Down
26 changes: 25 additions & 1 deletion tests/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
import asyncio
from os.path import join
from pathlib import Path
from typing import Tuple
from sys import version_info
from typing import List, Tuple

# third-party
import pkg_resources
from vcorelib.platform import is_windows

# internal
from runtimepy import PKG_NAME
from runtimepy.net.arbiter import ArbiterTask
from runtimepy.net.connection import Connection
from runtimepy.net.tcp.connection import TcpConnection
Expand Down Expand Up @@ -100,3 +103,24 @@ async def dispatch(self) -> bool:

class SampleArbiterTask(ArbiterTask, SampleTask):
"""A sample arbiter task."""


def can_use_uvloop() -> bool:
"""Determine if tests should try to use uvloop."""

return not is_windows() and (
version_info.major >= 3 and version_info.minor >= 11
)


def base_args(command: str) -> List[str]:
"""Get base command-line arguments."""

base = [PKG_NAME]

# Don't use uvloop if not using Python 3.11.
if not can_use_uvloop() and not is_windows():
base.append("--no-uvloop")

base.append(command)
return base
Loading

0 comments on commit b03cad0

Please sign in to comment.