Catalog PyPI
PACKAGE EXPLORERView in registry

affinity-router

PyPI

Intelligent task routing with data locality for distributed systems

consistent-hashingdata-localitydistributed-systemsload-balancerroutingtask-queue
Versions collected1
Direct dependencies1From release 0.1.0a1
Last observed20 Oct, 21:05 UTC

README

Version 0.1.0a1 documentation

AffinityRouter

Intelligent task routing with data locality for distributed systems.

Overview

AffinityRouter is a Python library for smart task routing in distributed systems. Instead of distributing work agnostically (e.g., Round-Robin), it prioritizes Data Locality using consistent hashing, ensuring tasks for the same resource always reach the same worker — maximizing in-memory cache hits and minimizing database pressure.

Key Features

  • Consistent Hashing — Tasks for the same resource always go to the same worker
  • Dynamic Cluster Management — Workers register/deregister with heartbeats
  • Native Idempotency — Built-in duplicate execution prevention
  • Pluggable Architecture — Swap transport, registry, and state backends
  • Async-First — Built on asyncio with automatic sync function wrapping

Installation

pip install --pre affinity-router

Note: The --pre flag is required to install this alpha pre-release.

Quick Start

from affinity_router import Router, Worker

# --- Router side ---
router = Router.from_redis(redis_url="redis://localhost:6379")
await router.submit(
    routing_key="ticket:12345",
    task_name="process_payment",
    payload={"amount": 100, "currency": "EUR"},
)

# --- Worker side ---
worker = Worker.from_redis(redis_url="redis://localhost:6379", worker_id="worker-1")

@worker.task("process_payment")
async def process_payment(task):
    return {"status": "paid"}

await worker.start()

Transport Backends

AffinityRouter supports multiple transport backends:

Redis Streams (default)

Best for production deployments with resilience requirements.

from affinity_router import Router, Worker
from affinity_router.transport import RedisStreamTransport

router = Router.from_redis(redis_url="redis://localhost:6379")

Direct TCP

Best for maximum throughput in controlled environments where workers have direct network access.

from affinity_router.transport import DirectTcpTransport

transport = DirectTcpTransport(registry=registry, host="0.0.0.0", port=8000)

Batched TCP

Best for high-throughput scenarios with batching to reduce syscall overhead.

from affinity_router.transport import BatchedTcpTransport

transport = BatchedTcpTransport(
    registry=registry,
    batch_size=100,
    flush_interval_ms=10
)
TransportThroughputLatencyResilienceUse Case
Redis StreamsMediumMediumHighProduction, distributed
Direct TCPHighLowLowControlled networks
Batched TCPHighestMediumLowHigh-throughput batch jobs

⚠️ Disclaimer

This software is provided "AS IS", without warranty of any kind, express or implied. The authors and contributors shall not be held liable for any damages, data loss, service disruptions, or any other issues arising from the use of this software. Users are solely responsible for evaluating the suitability of this software for their intended use case.

By using this software, you acknowledge that you have read and understood the MIT License under which it is distributed.

🚧 Alpha Status

This is an alpha release (0.1.0a1).

This version may contain incomplete implementations and undocumented critical bugs. The API surface is subject to breaking changes without prior notice.

It is strongly recommended to avoid using this package in real development or production environments.

License

MIT

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.0a19 Mar 20261

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
marcbadiam/affinityrouter

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:05 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:139fce72f9a2fce3461aafdefc22b1ecd6f7df8aaaf3dd96ebb7cfb480b8eeb9