Skip to main content

1μs multiprocessing cache (TCP/Unix socket)

Project description

tiny-mp-cache

tiny-mp-cache — минималистичный k/v‑кэш на Rust с Python‑клиентом.
Он рассчитан на использование как локальный сервис кэширования между несколькими Python‑процессами (например, воркерами multiprocessing) в одном pod’е или на одной машине.

Поддерживаются два транспорта:

  • TCP (serve(port), адрес вида "127.0.0.1:5002");
  • Unix domain socket (serve_unix(path), адрес вида "unix:///tmp/tiny-mp-cache.sock").

Установка из PyPI

После публикации пакет можно ставить напрямую:

python -m venv .venv
source .venv/bin/activate  # или .venv\Scripts\activate на Windows

pip install tiny-mp-cache

Модуль tiny_mp_cache станет доступен во всех скриптах в этом окружении.


Локальная сборка из исходников

Проект использует maturin и PyO3 (Rust‑расширение для Python).

python -m venv .venv
source .venv/bin/activate  # или .venv\Scripts\activate на Windows

pip install maturin

# установка расширения в текущий venv (editable-режим)
maturin develop --release

После этого модуль tiny_mp_cache доступен в Python в этом виртуальном окружении.
При изменении Rust‑кода библиотеку нужно пересобирать повторным запуском maturin develop или maturin develop --release.


Быстрый старт: TCP‑сервер

Запуск сервера и использование кэша по TCP.

import multiprocessing as mp
import time
from tiny_mp_cache import serve, TinyCache

PORT = 5002
ADDR = f"127.0.0.1:{PORT}"


def server():
    # Rust-сервер, слушает 127.0.0.1:PORT и обрабатывает команды
    serve(PORT)


def main():
    mp.set_start_method("fork", force=True)  # для Linux/macOS

    # стартуем сервер в отдельном процессе
    srv = mp.Process(target=server, daemon=True)
    srv.start()
    time.sleep(0.5)  # небольшая пауза на инициализацию

    cache = TinyCache(ADDR)
    cache.set("foo", b"bar")
    value = cache.get("foo")
    print(value)  # b'bar'


if __name__ == "__main__":
    main()

serve(port) поднимает один TCP‑сервер на 127.0.0.1:port.
TinyCache — клиентский класс, который ходит к этому серверу по TCP.


Быстрый старт: Unix domain socket

Пример запуска сервера и клиента через Unix‑сокет.

import multiprocessing as mp
import time
import os
from tiny_mp_cache import serve_unix, TinyCache

SOCK_PATH = os.path.join(os.getcwd(), "tiny-mp-cache-test.sock")
UDS_ADDR = f"unix://{SOCK_PATH}"


def server():
    # при необходимости удаляем старый сокет
    if os.path.exists(SOCK_PATH):
        os.remove(SOCK_PATH)
    # сервер слушает Unix-сокет по заданному пути
    serve_unix(SOCK_PATH)


def main():
    mp.set_start_method("fork", force=True)  # для Linux/macOS

    srv = mp.Process(target=server, daemon=True)
    srv.start()
    time.sleep(0.5)

    cache = TinyCache(UDS_ADDR)
    cache.set("foo", b"bar")
    value = cache.get("foo")
    print(value)  # b'bar'


if __name__ == "__main__":
    main()

В serve_unix передаётся файловый путь (/tmp/… или путь в os.getcwd()),
а в TinyCache — URI с префиксом unix://….


API Python‑клиента

from tiny_mp_cache import TinyCache

cache_tcp = TinyCache("127.0.0.1:5002")
cache_uds = TinyCache("unix:///tmp/tiny-mp-cache.sock")
  • Ключи — строки (str).
  • Значения — байты (bytes). Сериализацию/десериализацию объектов (JSON, pickle и т.п.) контролирует приложение.

set(key: str, value: bytes) -> None

Сохраняет значение по ключу.

cache.set("user:1", b"payload")

get(key: str) -> Optional[bytes]

Возвращает значение по ключу или None, если ключа нет.

value = cache.get("user:1")
if value is not None:
    print(value.decode("utf-8"))

pop(key: str) -> Optional[bytes]

Атомарно забирает значение и удаляет ключ.

Гарантия: если несколько воркеров одновременно вызывают pop для одного и того же ключа, значение получит ровно один из них.

job_raw = cache.pop("job:123")
if job_raw is not None:
    job = job_raw.decode("utf-8")

delete(key: str) -> int

Удаляет ключ.

  • 1 — ключ существовал и был удалён;
  • 0 — ключа не было.
deleted = cache.delete("user:1")

keys(pattern: str) -> list[str]

Возвращает список ключей, подходящих под паттерн.
Сейчас поддерживается только префиксный паттерн вида "prefix*".

jobs = cache.keys("job:*")

len() -> int

Возвращает количество ключей в кэше.

print(cache.len())

Пример: продюсер и воркеры (TCP)

Пример использования кэша как простой очереди задач между несколькими процессами.

import multiprocessing as mp
import time
import json
from tiny_mp_cache import serve, TinyCache

PORT = 5002
ADDR = f"127.0.0.1:{PORT}"
N_JOBS = 1000
N_WORKERS = 8
WORK_TIME = 0.001  # 1 мс на задачу


def server():
    serve(PORT)


def make_job_key(i: int) -> str:
    return f"job:{i}"


def producer():
    cache = TinyCache(ADDR)
    for i in range(N_JOBS):
        job = {"id": i, "payload": f"data-{i}"}
        cache.set(make_job_key(i), json.dumps(job).encode("utf-8"))
    print(f"[PRODUCER] queued {N_JOBS} jobs")


def worker(worker_id: int, processed_ids):
    """
    processed_ids — общая manager.list(), используется только для проверки,
    что не было повторной обработки задач.
    """
    cache = TinyCache(ADDR)
    processed = 0
    while True:
        keys = cache.keys("job:*")
        if not keys:
            break
        for key in keys:
            raw = cache.pop(key)
            if raw is None:
                continue
            job = json.loads(raw.decode("utf-8"))
            processed_ids.append(job["id"])
            processed += 1
            time.sleep(WORK_TIME)
    print(f"[WORKER {worker_id}] processed {processed} jobs")


def main():
    mp.set_start_method("fork", force=True)

    srv = mp.Process(target=server, daemon=True)
    srv.start()
    time.sleep(0.5)

    prod = mp.Process(target=producer)
    prod.start()
    prod.join()

    with mp.Manager() as manager:
        processed_ids = manager.list()

        workers = [
            mp.Process(target=worker, args=(wid, processed_ids))
            for wid in range(N_WORKERS)
        ]
        for p in workers:
            p.start()
        for p in workers:
            p.join()

        ids = list(processed_ids)
        unique_ids = set(ids)
        duplicates = len(ids) - len(unique_ids)

        print("\n=== STATS ===")
        print(f"jobs       : {N_JOBS}")
        print(f"workers    : {N_WORKERS}")
        print(f"processed  : total={len(ids)}, unique={len(unique_ids)}, duplicates={duplicates}")

        if len(unique_ids) != N_JOBS:
            missing = set(range(N_JOBS)) - unique_ids
            print(f"WARNING: missing {len(missing)} jobs, e.g. {sorted(list(missing))[:10]}")
        if duplicates:
            print("ERROR: some jobs were processed more than once!")
        else:
            print("OK: no duplicate processing detected")

    print("ALL DONE")


if __name__ == "__main__":
    main()

Серверы serve и serve_unix также принимают опциональный аргумент wal_dir с указанием пути к директории с WAL-журналом


Запуск тестов

В репозитории есть два тестовых скрипта:

  • tests/cache_api_test.py — проверяет базовый API (set/get/pop/delete/keys/len) в одном процессе;
  • tests/full_test.py — нагрузочный многопроцессный сценарий с продюсером и воркерами.

Перед запуском убедись, что активирован тот же venv, куда ставился пакет через maturin develop или установлен tiny-mp-cache из PyPI.

python tests/cache_api_test.py
python tests/full_test.py

1

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tiny_mp_cache-0.1.13.tar.gz (18.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

tiny_mp_cache-0.1.13-cp39-abi3-win_amd64.whl (159.7 kB view details)

Uploaded CPython 3.9+Windows x86-64

tiny_mp_cache-0.1.13-cp39-abi3-win32.whl (154.3 kB view details)

Uploaded CPython 3.9+Windows x86

tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_x86_64.whl (496.6 kB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ x86-64

tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_i686.whl (526.4 kB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ i686

tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_armv7l.whl (565.8 kB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ ARMv7l

tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_aarch64.whl (471.2 kB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ ARM64

tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (290.2 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl (292.5 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ s390x

tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (313.9 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ppc64le

tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (301.0 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARMv7l

tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (298.5 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.whl (313.5 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.12+ i686

tiny_mp_cache-0.1.13-cp39-abi3-macosx_11_0_arm64.whl (259.9 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

tiny_mp_cache-0.1.13-cp39-abi3-macosx_10_12_x86_64.whl (264.6 kB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file tiny_mp_cache-0.1.13.tar.gz.

File metadata

  • Download URL: tiny_mp_cache-0.1.13.tar.gz
  • Upload date:
  • Size: 18.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.12.4

File hashes

Hashes for tiny_mp_cache-0.1.13.tar.gz
Algorithm Hash digest
SHA256 6aaeaefc98c8075ce99faaccc40eb6a8181f5b605b16be7a83727e84cea37bd9
MD5 4f6c442bfb0d144ee5820a013fd882c3
BLAKE2b-256 5ae5b5e4c4dffe3ffc467b73bc790a8f2fec48b0bf3c5a1e39956dfbd7bcd4c9

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 bb3eeb8abe413563f06fc0b774faf56f55adbc40f723dc1c5cade1f80e95517b
MD5 0a4a8a26f32fb5dbbaa2260f7bb736da
BLAKE2b-256 4804e9b31f4c7798a90d19977666bbfe8016b950e45bd5d12e4c347ca3495b2c

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-win32.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-win32.whl
Algorithm Hash digest
SHA256 92c02dad8fe7dc3ebcc91e51abaf219cc9f27dde842376bdde6bf7cba1e7bb82
MD5 b996e57b313f19bcdccf940a48111e3d
BLAKE2b-256 b3b370bb32f2424fae9940b01b123e1b9e9005250b7393845449e8a3df2781ee

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9f40be28ca32ba62e881cd5ce90418b2a1ea8de56f299c8088593be1d45cdff9
MD5 8d8164ee5c2637f2b323e8d5ec582e4a
BLAKE2b-256 cb729445e99aef0574375e0d597a7c99a9580e9fc1eab4855ed7a8f8146de63b

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 f6f0797411fe308bf8a333b593478f309d1b038934241d8bbe00fc93cb2b6f65
MD5 dd4d923078a95858e59eed4624e9e476
BLAKE2b-256 5686e29f819262695fb90af7f4a88715d6b69173efc6f35fc11220af9b8050e1

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 75773244a23874f98d74f4bfa847363c10aa0f1f81556c7407f331a2b49b18d2
MD5 fdf77e1db9e8d7a94092129dfaa03692
BLAKE2b-256 a19ebea78643d5ac67689c1b196417b26cfb45f772d1be3f3dbc45066d2ebb21

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 f94f036c262b4c897881946822fa32bc21b96496aac24451ccb5fc4d120c1eaa
MD5 f6db9f98e64cd98f07980347adcf944e
BLAKE2b-256 1e92b76b75f6aa68f0470a4921c6e4f644c9b8c0226f45a4ee8c21f408caf99c

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d6bbf1f8ebafed9fc850dea8ddd7b1a38eeb4492a3f96f95e3cbe4148fc9b6cd
MD5 7d54d83e705afe233cc7d680fa2aa6f3
BLAKE2b-256 eb1990fef87837df11a234e8bcf51e86d01d2b06132f52d4611b8294cfb0a7e6

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 ae2917272469347ab3d8d17eb825174c8395926329c52d8d9d8f7228ca68ea56
MD5 021d24b46fc014fc4519565a21322c77
BLAKE2b-256 00ab190b336b931c4a61ee63bd7e52d3cfcb178f543e74d2fc8f01618e5910bf

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 fe7945e609e816e9c359eb9da53e3a2ed9824e4af481db44d9cab1e13de1ffce
MD5 55e544fac2f9db6eeb8f59d2fd63fe81
BLAKE2b-256 945660bd816f1142aa9d3ebcab7fc5d8e8edba06dc5aea6dcabe10595f1e6d9f

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 9dbdb7ede9e667afaafa03070132dd4ee51e9bad5dabffbefb73066deed35206
MD5 6a83b9172f0c3087033321c9deae9d0b
BLAKE2b-256 20acedb1fbb755c89ae55d0e9c587a56ee89564f7f3d80be3b58075d5b236412

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3b3c8b9f8ff756627eed4ecc671dbebac6e17f1f21f408225b05982cb5a51fd2
MD5 86d58a49f9c0279817a4fe278dffa8a3
BLAKE2b-256 f943afb4ca9b57d7fa9f871b8871c3bdc066596a970ef9cb2560d382a4e6026a

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 0c7ee3eea06b9736527b0fbe5789abe5a48c2cd6ca6bb8eb809a11b7afb37ed6
MD5 fb12574001f6c5d902f8b1734fbc37de
BLAKE2b-256 4bed871866c1bb1051f31092506b31b0fa108ae0ec3a53930ec2d9fc04500f98

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 525469093cdc22d14e7886d3ed63a3e510c237fc4da4f0f8cea1d5f5065d3672
MD5 fedf8c173852ed308c771ed8dce968a9
BLAKE2b-256 d2072e9434e2a334c856e19335e4100286ca678dcfab12ebaa5594815ac19126

See more details on using hashes here.

File details

Details for the file tiny_mp_cache-0.1.13-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tiny_mp_cache-0.1.13-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c25dded2875fb2bc74dfbbdf7e2cbaf49b5ec1c86b9f1c76e090b0cb714b7839
MD5 29e66c85b977ddd362c7fa877bdcf577
BLAKE2b-256 c7cd10dc8a40d17536b9f76f6fe4c060449b7b92d8abab9ee9bcfbed21efe297

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page