Skip to main content

Backend-neutral cache contracts and AOP annotations for Spakky Framework

Project description

Spakky Cache

Spakky Framework를 위한 백엔드 중립 애플리케이션 데이터 캐시 계약과 AOP 어노테이션입니다. 서비스 메서드의 @cacheable/@cache_evict 선언을 등록된 cache backend Pod와 연결합니다.

설치

pip install spakky-cache

주요 기능

  • 타입화된 캐시 결과: CacheHit[T]CacheMiss는 백엔드별 예외 없이 hit/miss 결과를 표현합니다.
  • 동기/비동기 계약: ICache[T]get, set, delete, clear와 비동기 대응 메서드를 정의합니다.
  • TTL 의미론: 양수 TTL 값은 항목을 결정적으로 만료시키며, 없는 항목과 만료된 항목은 miss입니다.
  • AOP 메서드 캐싱: @cacheable()@cache_evict()은 수동 배선 없이 cache hit/miss와 evict 동작을 적용합니다.
  • 운영 backend 분리: Core package는 저장소 backend를 등록하지 않으며, spakky-redis 같은 backend plugin이 ICache[T] 구현체를 제공합니다.
  • 애플리케이션 데이터 범위: 이 패키지는 ApplicationContext 내부 캐시를 노출하거나 변경하지 않습니다.

빠른 시작

from datetime import timedelta

from spakky.cache import cache_evict, cacheable
from spakky.core.application.application import SpakkyApplication
from spakky.core.application.application_context import ApplicationContext
from spakky.core.application.plugin import Plugin
from spakky.core.stereotype.usecase import UseCase


@UseCase()
class ProfileService:
    def __init__(self) -> None:
        self.calls = 0

    @cacheable(key="profile:{0}", ttl=timedelta(minutes=5))
    def load_profile(self, user_id: str) -> str:
        self.calls += 1
        return f"profile:{user_id}"

    @cache_evict(key="profile:{0}")
    def refresh_profile(self, user_id: str) -> None:
        ...


app = (
    SpakkyApplication(ApplicationContext())
    .load_plugins(
        include={
            Plugin(name="spakky-cache"),
            Plugin(name="spakky-redis"),
        }
    )
    .add(ProfileService)
    .start()
)

profiles = app.container.get(type_=ProfileService)
profiles.load_profile("42")

어노테이션 사용

spakky-cache 플러그인을 로드한 뒤 서비스 메서드에 어노테이션을 붙입니다. 이 플러그인은 CacheAspect, AsyncCacheAspect를 등록하며, 실제 저장소 backend는 spakky-redis 같은 plugin이 ICache Pod로 제공합니다.

from datetime import timedelta

from spakky.cache import cache_evict, cacheable
from spakky.core.stereotype.usecase import UseCase


@UseCase()
class ProfileService:
    def __init__(self) -> None:
        self.calls = 0

    @cacheable(key="profile:{0}", ttl=timedelta(minutes=5))
    def load_profile(self, user_id: str) -> str:
        self.calls += 1
        return f"profile:{user_id}"

    @cache_evict(key="profile:{0}")
    def refresh_profile(self, user_id: str) -> None:
        ...

기본 키는 메서드 모듈, 정규화된 이름, 위치 인자, 정렬된 키워드 인자에서 파생됩니다. 명시적 key 값은 메서드 호출 인자에 대해 평가되는 Python format 문자열입니다. 키 포맷이 유효하지 않으면 CacheKeyGenerationError가 발생합니다. 백엔드 실패는 삼키지 않고 캐시 에러로 전파합니다.

@cache_evict()은 어노테이션이 붙은 메서드가 성공한 뒤에만 일치하는 항목을 삭제합니다. 실패한 메서드 호출은 기존 항목을 건드리지 않으므로, refresh 실패가 마지막으로 알려진 캐시 값을 지우지 않습니다.

비동기 사용

from spakky.cache import cacheable
from spakky.core.stereotype.usecase import UseCase


@UseCase()
class AnswerService:
    @cacheable(key="answer:{0}")
    async def load_answer(self, question_id: str) -> int:
        return 42

TTL 규칙

ttl=None은 명시적 삭제 또는 전체 삭제 전까지 항목을 저장합니다. 양수 float, int, datetime.timedelta 값은 해당 시간이 지난 뒤 항목을 만료시킵니다. 0 이하 TTL 값은 InvalidCacheTTLError를 발생시킵니다.

캐시 evict 어노테이션은 어노테이션이 붙은 메서드가 성공한 뒤에만 일치하는 항목 하나를 제거합니다.

범위

spakky-cache는 애플리케이션 데이터 캐시 추상화입니다. ApplicationContext 내부의 타입 캐시, 싱글톤 캐시, 컨텍스트 캐시와는 별개입니다. Tag 기반 무효화, stampede 보호, write-through/write-behind, metrics는 core capability contract로 정의되며, spakky-redis가 Redis backend 구현을 제공합니다.

라이선스

MIT License

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

spakky_cache-6.8.0.tar.gz (6.5 kB view details)

Uploaded Source

Built Distribution

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

spakky_cache-6.8.0-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

File details

Details for the file spakky_cache-6.8.0.tar.gz.

File metadata

  • Download URL: spakky_cache-6.8.0.tar.gz
  • Upload date:
  • Size: 6.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for spakky_cache-6.8.0.tar.gz
Algorithm Hash digest
SHA256 a12e1ad31e99dcd84bc4dd19fcc2823e8a2737ef153ad236db068f4817e005cf
MD5 97a241d734a6c865dd9f91b694a5ddb2
BLAKE2b-256 75f6fa461336061100c0043122a0d80949cf4251da0f4e17c003826a277a34fb

See more details on using hashes here.

Provenance

The following attestation bundles were made for spakky_cache-6.8.0.tar.gz:

Publisher: release.yml on E5presso/spakky-framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file spakky_cache-6.8.0-py3-none-any.whl.

File metadata

  • Download URL: spakky_cache-6.8.0-py3-none-any.whl
  • Upload date:
  • Size: 9.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for spakky_cache-6.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c13ea1f94e5e037d4b9c10e95fa8ca1ae5f6c93ac059dad74767ce2805557ad0
MD5 9cd2518439de16bad9658b8109690922
BLAKE2b-256 08922aaeaab73ea5afcc458d9d044f88442835c853dd7670ac24766d7053943e

See more details on using hashes here.

Provenance

The following attestation bundles were made for spakky_cache-6.8.0-py3-none-any.whl:

Publisher: release.yml on E5presso/spakky-framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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