Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
41d411a
Add fault tolerance support during state migration (squashed PR #35)
kPsarakis Oct 24, 2026
05e48fc
Keep migrated keys consistent across snapshots and recovery
kPsarakis Oct 24, 2026
94685c3
Wait for in-flight keys and keep the checkpoint until the transfer is…
kPsarakis Oct 24, 2026
6834041
Migrate None-valued keys and load the migration demos' initial data
kPsarakis Oct 24, 2026
60b7648
Shorten the migration stall: keep the egress producer and apply local…
kPsarakis Oct 24, 2026
daddced
Spread the async transfer over epochs
kPsarakis Oct 24, 2026
8547faa
Keep the ingress Kafka consumer across a migration rebuild
kPsarakis Oct 24, 2026
be18240
Check pending migration keys in constant time
kPsarakis Oct 24, 2026
c9d703c
Install uvloop in the Cython hot-path unit test job
kPsarakis Oct 24, 2026
5472be0
Order snapshot completions, drop stale migration messages, tag the ch…
kPsarakis Oct 24, 2026
3f87c3e
Read the ingress source file in the except-clause test
kPsarakis Oct 24, 2026
54db952
Clean up: logging, compaction, test names, real-code tests, E2E state…
kPsarakis Oct 24, 2026
761163c
Start partitions without a recovered offset from the beginning
kPsarakis Oct 24, 2026
e8c0564
Keep unanswered requests and the FT E2E results in the uploaded logs
kPsarakis Oct 24, 2026
c7f8697
Run mis-routed requests as proxied calls from the consuming worker
kPsarakis Oct 24, 2026
c8bf919
Test that the ingress offset never passes an unrun request; count pro…
kPsarakis Oct 25, 2026
069468f
Log what a stalled epoch is waiting on
kPsarakis Oct 25, 2026
e629945
Don't recover a dead unreachable worker as a participant; log stalled…
kPsarakis Oct 25, 2026
f006ad2
Carry rescheduled requests across snapshots and migration stops
kPsarakis Oct 25, 2026
657f01c
Unpack the pending requests where a worker starts from its first snap…
kPsarakis Oct 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6.0.2

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6.2.0
with:
python-version: "3.14"
cache: "pip"
Expand All @@ -37,7 +37,7 @@ jobs:
run: pytest tests/unit/coordinator/ -v --cov=coordinator --cov-report=xml:coverage-coordinator.xml

- name: Upload coordinator coverage to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v5.5.3
with:
files: coverage-coordinator.xml
flags: coordinator
Expand All @@ -51,10 +51,10 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6.0.2

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6.2.0
with:
python-version: "3.14"
cache: "pip"
Expand All @@ -64,7 +64,7 @@ jobs:
python -m pip install --upgrade pip setuptools Cython
cd styx-package && python setup.py build_ext --inplace && cd ..
python -m pip install styx-package/
python -m pip install msgspec pytest==9.1.1 pytest-cov pytest-asyncio psutil
python -m pip install msgspec pytest==9.1.1 pytest-cov pytest-asyncio psutil uvloop

- name: Build Cython extensions
run: python worker/setup.py build_ext --inplace
Expand All @@ -73,7 +73,7 @@ jobs:
run: pytest tests/unit/worker/ -v --cov=worker --cov-report=xml:coverage-worker.xml

- name: Upload worker coverage to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v5.5.3
with:
files: coverage-worker.xml
flags: worker
Expand All @@ -87,10 +87,10 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6.0.2

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6.2.0
with:
python-version: "3.14"
cache: "pip"
Expand All @@ -106,7 +106,7 @@ jobs:
run: pytest tests/unit/styx_package/ -v --cov=styx-package/styx --cov-report=xml:coverage-styx-package.xml

- name: Upload styx-package coverage to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v5.5.3
with:
files: coverage-styx-package.xml
flags: styx-package
Expand Down Expand Up @@ -139,7 +139,7 @@ jobs:
python -m pip install --upgrade pip setuptools Cython
cd styx-package && python setup.py build_ext --inplace && cd ..
python -m pip install -e styx-package/
python -m pip install msgspec pytest==9.1.1 pytest-asyncio psutil
python -m pip install msgspec pytest==9.1.1 pytest-asyncio psutil uvloop
python worker/setup.py build_ext --inplace

- name: Check the hot-path modules are the compiled ones
Expand Down Expand Up @@ -170,10 +170,10 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6.0.2

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6.2.0
with:
python-version: "3.14"
cache: "pip"
Expand All @@ -190,7 +190,7 @@ jobs:
run: pytest tests/integration/ -v --cov=styx-package/styx --cov=coordinator --cov=worker --cov-report=xml:coverage-integration.xml

- name: Upload integration coverage to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v5.5.3
with:
files: coverage-integration.xml
flags: integration
Expand Down
99 changes: 82 additions & 17 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,23 @@ concurrency:
cancel-in-progress: true

jobs:
e2e-tests:
e2e-base:
name: "E2E — base (non-migration)"
# Provides the legacy "e2e-tests" status check via the summary job below.
runs-on: ubuntu-latest
timeout-minutes: 45
timeout-minutes: 60

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6.0.2

- name: Docker info
run: |
docker version
docker compose version

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6.2.0
with:
python-version: "3.14"
cache: "pip"
Expand All @@ -34,37 +36,100 @@ jobs:
python -m pip install --upgrade pip setuptools Cython
cd styx-package && python setup.py build_ext --inplace && cd ..
python -m pip install -r requirements.txt
# Install Styx package from repo root
python -m pip install -e styx-package/

- name: Make scripts executable
run: |
chmod +x scripts/start_styx_cluster.sh scripts/stop_styx_cluster.sh || true

# Needed so Kafka advertises a reachable external listener
- name: Set DOCKER_HOST_IP
run: echo "DOCKER_HOST_IP=127.0.0.1" >> $GITHUB_ENV

- name: Run e2e tests
- name: Run non-migration e2e tests
env:
PYTHONUNBUFFERED: "1"
run: |
pytest tests/e2e/ -m e2e -q
pytest tests/e2e/ -m "e2e" -q --log-level=DEBUG

- name: Collect worker and coordinator logs (always)
- name: Collect logs
if: always()
run: |
mkdir -p artifacts
if [ -d logs ]; then
cp -r logs artifacts/
else
echo "No logs folder found to copy."
fi
if [ -d logs ]; then cp -r logs artifacts/; fi

- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v7.0.0
with:
name: e2e-base-artifacts
path: artifacts
if-no-files-found: ignore

e2e-migration:
name: "E2E — migration"
runs-on: ubuntu-latest
timeout-minutes: 90

steps:
- name: Checkout
uses: actions/checkout@v6.0.2

- name: Docker info
run: |
docker version
docker compose version

- name: Set up Python
uses: actions/setup-python@v6.2.0
with:
python-version: "3.14"
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools Cython
cd styx-package && python setup.py build_ext --inplace && cd ..
python -m pip install -r requirements.txt
python -m pip install -e styx-package/

- name: Upload artifacts (always)
- name: Make scripts executable
run: |
chmod +x scripts/start_styx_cluster.sh scripts/stop_styx_cluster.sh || true

- name: Set DOCKER_HOST_IP
run: echo "DOCKER_HOST_IP=127.0.0.1" >> $GITHUB_ENV

- name: Run migration e2e tests
env:
PYTHONUNBUFFERED: "1"
run: |
pytest tests/e2e/ -m "e2e_migration" -q --log-level=DEBUG

- name: Collect logs
if: always()
run: |
mkdir -p artifacts
if [ -d logs ]; then cp -r logs artifacts/; fi

- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7.0.0
with:
name: e2e-artifacts
name: e2e-migration-artifacts
path: artifacts
if-no-files-found: ignore

# Legacy summary job — provides the "e2e-tests" status check that branch
# protection rules may reference from before the split into two jobs.
e2e-tests:
name: "e2e-tests"
if: always()
needs: [e2e-base, e2e-migration]
runs-on: ubuntu-latest
steps:
- name: Check results
run: |
if [[ "${{ needs.e2e-base.result }}" == "failure" || "${{ needs.e2e-migration.result }}" == "failure" ]]; then
echo "One or more E2E jobs failed"
exit 1
fi
4 changes: 2 additions & 2 deletions .github/workflows/publish-helm-chart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6.0.2

- name: Set up Helm
uses: azure/setup-helm@v4
uses: azure/setup-helm@v5.0.0

- name: Log in to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io --username ${{ github.repository_owner }} --password-stdin
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/publish-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ jobs:
image_suffix: worker
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6.0.2

- name: Set up Build
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4.0.0

- name: Log in to GHCR
uses: docker/login-action@v3
uses: docker/login-action@v4.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6.0.0
with:
images: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}-${{ matrix.image_suffix }}
tags: |
Expand All @@ -49,7 +49,7 @@ jobs:
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}

- name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7.0.0
with:
context: .
file: ${{ matrix.dockerfile }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6.0.2

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6.2.0
with:
python-version: "3.14"
cache: "pip"
Expand Down
3 changes: 3 additions & 0 deletions coordinator/aria_sync_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ def __init__(self, n_workers: int) -> None:
self.global_read_set: dict | None = None
self.stop_next_epoch: bool = False
self.take_snapshot: bool = False
# Barriers completed so far, so a stalled one can be told from a new one.
self.completed_barriers: int = 0

def check_distributed_barrier(self) -> bool:
return len(self.arrived) == self.n_workers
Expand Down Expand Up @@ -122,6 +124,7 @@ def __merge_rw_reservations(
return output_dict

def cleanup(self, epoch_end: bool = False, take_snapshot: bool = False) -> None:
self.completed_barriers += 1
self.arrived.clear()
self.logic_aborts_everywhere: set[int] = set()
self.sent_proceed_msg: bool = False
Expand Down
Loading
Loading