Skip to content

Commit a6500a7

Browse files
authored
Merge pull request #152 from RobotWebTools/websockets-asyncio
Websockets asyncio
2 parents ed35153 + a84f389 commit a6500a7

27 files changed

Lines changed: 1407 additions & 92 deletions

.github/workflows/test-ros1.yml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ jobs:
1919
"ubuntu-py39",
2020
"ubuntu-py310",
2121
"ubuntu-py311",
22+
"ubuntu-py312",
23+
"ubuntu-py313",
24+
"ubuntu-py314",
2225
]
2326
include:
2427
- name: "ubuntu-py39"
@@ -30,6 +33,15 @@ jobs:
3033
- name: "ubuntu-py311"
3134
os: ubuntu-latest
3235
python-version: "3.11"
36+
- name: "ubuntu-py312"
37+
os: ubuntu-latest
38+
python-version: "3.12"
39+
- name: "ubuntu-py313"
40+
os: ubuntu-latest
41+
python-version: "3.13"
42+
- name: "ubuntu-py314"
43+
os: ubuntu-latest
44+
python-version: "3.14"
3345
steps:
3446
- uses: actions/checkout@v7
3547
- name: Set up Python ${{ matrix.python-version }}
@@ -51,9 +63,16 @@ jobs:
5163
- name: Run linter
5264
run: |
5365
invoke check
54-
- name: Run tests
66+
# The twisted and asyncio transports both build on Autobahn, whose txaio
67+
# layer binds a single async framework per process, so each transport is
68+
# exercised in its own pytest process.
69+
- name: Run tests (twisted transport)
70+
run: |
71+
ROSLIBPY_TRANSPORT=twisted pytest tests/ros1
72+
- name: Run tests (asyncio transport)
5573
run: |
56-
pytest tests/ros1
74+
ROSLIBPY_TRANSPORT=asyncio pytest tests/ros1
5775
- name: Tear down docker containers
76+
if: always()
5877
run: |
5978
docker rm -f rosbridge

.github/workflows/test-ros2.yml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020
"ubuntu-py310",
2121
"ubuntu-py311",
2222
"ubuntu-py312",
23+
"ubuntu-py313",
24+
"ubuntu-py314",
2325
]
2426
include:
2527
- name: "ubuntu-py39"
@@ -34,6 +36,12 @@ jobs:
3436
- name: "ubuntu-py312"
3537
os: ubuntu-latest
3638
python-version: "3.12"
39+
- name: "ubuntu-py313"
40+
os: ubuntu-latest
41+
python-version: "3.13"
42+
- name: "ubuntu-py314"
43+
os: ubuntu-latest
44+
python-version: "3.14"
3745
steps:
3846
- uses: actions/checkout@v7
3947
- name: Set up Python ${{ matrix.python-version }}
@@ -55,9 +63,15 @@ jobs:
5563
- name: Run linter
5664
run: |
5765
invoke check
58-
- name: Run tests
66+
# The twisted and asyncio transports both build on Autobahn, whose txaio
67+
# layer binds a single async framework per process, so each transport is
68+
# exercised in its own pytest process.
69+
- name: Run tests (twisted transport)
70+
run: |
71+
ROSLIBPY_TRANSPORT=twisted pytest tests/ros2
72+
- name: Run tests (asyncio transport)
5973
run: |
60-
pytest tests/ros2
74+
ROSLIBPY_TRANSPORT=asyncio pytest tests/ros2
6175
- name: Tear down docker containers
6276
run: |
6377
docker rm -f rosbridge
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Transport benchmark
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- 'v*'
9+
pull_request:
10+
branches:
11+
- main
12+
workflow_dispatch:
13+
14+
jobs:
15+
transport-benchmark:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v6
19+
- name: Set up Python 3.11
20+
uses: actions/setup-python@v6
21+
with:
22+
python-version: "3.11"
23+
- name: Install dependencies
24+
run: |
25+
python -m pip install --upgrade pip
26+
python -m pip install wheel
27+
- name: Install
28+
run: |
29+
python -m pip install --no-cache-dir -r requirements-dev.txt
30+
python -m pip install --no-cache-dir uvloop
31+
- name: Set up docker containers
32+
run: |
33+
docker build -t gramaziokohler/rosbridge:integration_tests_ros1 ./docker/ros1
34+
docker run -d -p 9090:9090 --name rosbridge gramaziokohler/rosbridge:integration_tests_ros1 /bin/bash -c "roslaunch /integration-tests.launch"
35+
docker ps -a
36+
- name: Run transport benchmark
37+
continue-on-error: true
38+
run: |
39+
python benchmarks/transport.py \
40+
--host 127.0.0.1 \
41+
--port 9090 \
42+
--cases twisted asyncio asyncio-uvloop asyncio-no-compression asyncio-uvloop-no-compression \
43+
--warmup 100 \
44+
--service-count 1500 \
45+
--topic-count 3000 \
46+
--markdown transport-benchmark.md
47+
cat transport-benchmark.md >> "$GITHUB_STEP_SUMMARY"
48+
- name: Upload transport benchmark
49+
if: always()
50+
continue-on-error: true
51+
uses: actions/upload-artifact@v4
52+
with:
53+
name: transport-benchmark
54+
path: transport-benchmark.md
55+
if-no-files-found: ignore
56+
- name: Tear down docker containers
57+
if: always()
58+
run: |
59+
docker rm -f rosbridge

.readthedocs.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: 2
2+
3+
build:
4+
os: ubuntu-24.04
5+
tools:
6+
python: "3.14"
7+
8+
sphinx:
9+
configuration: docs/conf.py
10+
11+
python:
12+
install:
13+
- requirements: docs/requirements.txt

CHANGELOG.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@ Unreleased
1212

1313
**Added**
1414

15+
* Added an asyncio transport backend (Autobahn running on an asyncio event
16+
loop instead of the Twisted reactor) selectable with ``ROSLIBPY_TRANSPORT``,
17+
``set_default_transport()``, or the ``Ros(..., transport=...)`` argument.
18+
* Added transport-parametrized ROS integration tests for CPython, while
19+
keeping IronPython on the ``cli`` transport.
20+
1521
**Changed**
1622

23+
* Updated the package classifiers to 3.9-3.14 (removes most EOL python versions, 3.9 is still supported).
24+
1725
**Fixed**
1826

1927
**Deprecated**

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
graft docs
22
graft src
33
graft tests
4+
graft benchmarks
45

56
prune docker
67

78
include .bumpversion.cfg
89
include .editorconfig
10+
include .readthedocs.yaml
911

1012
include AUTHORS.rst
1113
include CHANGELOG.rst

README.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,30 @@ To install **roslibpy**, simply use ``pip``::
6868

6969
pip install roslibpy
7070

71+
The default WebSocket transport on CPython uses Autobahn on the Twisted
72+
reactor. An alternative transport that runs the same Autobahn WebSocket stack
73+
on an asyncio event loop is also available (no extra dependencies required);
74+
see `Transport selection`_ below.
75+
7176
For IronPython, the ``pip`` command is slightly different::
7277

7378
ipy -X:Frames -m pip install --user roslibpy
7479

7580
Remember that you will need a working ROS setup including the
7681
**rosbridge server** and **TF2 web republisher** accessible within your network.
7782

83+
Transport selection
84+
-------------------
85+
86+
CPython uses the ``twisted`` transport by default; IronPython uses ``cli``. The
87+
``asyncio`` transport runs the same Autobahn WebSocket stack on an asyncio
88+
event loop. To select it, either pass it per client, set the process-wide
89+
default, or set the environment variable::
90+
91+
roslibpy.Ros(host='localhost', port=9090, transport='asyncio')
92+
roslibpy.set_default_transport('asyncio')
93+
ROSLIBPY_TRANSPORT=asyncio python my_script.py
94+
7895

7996
Documentation
8097
-------------

0 commit comments

Comments
 (0)