73 lines
2.1 KiB
Python
73 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from dataclasses import dataclass
|
|
from datetime import datetime, timezone
|
|
from typing import Dict, Any
|
|
|
|
from .config import dht_config
|
|
from .crypto import digest_hex
|
|
|
|
|
|
def _json_dumps(data: Dict[str, Any]) -> bytes:
|
|
return json.dumps(data, sort_keys=True, separators=(",", ":")).encode()
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class MetaKey:
|
|
content_id: str
|
|
schema_version: str = dht_config.schema_version
|
|
|
|
def fingerprint(self) -> str:
|
|
return digest_hex(self.serialize())
|
|
|
|
def serialize(self) -> bytes:
|
|
return _json_dumps({"schema_version": self.schema_version, "content_id": self.content_id, "type": "meta"})
|
|
|
|
def __str__(self) -> str:
|
|
return f"meta:{self.schema_version}:{self.content_id}"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class MembershipKey:
|
|
node_id: str
|
|
schema_version: str = dht_config.schema_version
|
|
|
|
def fingerprint(self) -> str:
|
|
return digest_hex(self.serialize())
|
|
|
|
def serialize(self) -> bytes:
|
|
return _json_dumps({"schema_version": self.schema_version, "node_id": self.node_id, "type": "membership"})
|
|
|
|
def __str__(self) -> str:
|
|
return f"membership:{self.schema_version}:{self.node_id}"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class MetricKey:
|
|
content_id: str
|
|
window_id: str
|
|
schema_version: str = dht_config.schema_version
|
|
|
|
@classmethod
|
|
def window_for(cls, timestamp: float, window_size: int | None = None) -> str:
|
|
win = int(timestamp // (window_size or dht_config.window_size))
|
|
return datetime.fromtimestamp(win * (window_size or dht_config.window_size), tz=timezone.utc).strftime("%Y%m%d%H")
|
|
|
|
def fingerprint(self) -> str:
|
|
return digest_hex(self.serialize())
|
|
|
|
def serialize(self) -> bytes:
|
|
return _json_dumps(
|
|
{
|
|
"schema_version": self.schema_version,
|
|
"content_id": self.content_id,
|
|
"window_id": self.window_id,
|
|
"type": "metric",
|
|
}
|
|
)
|
|
|
|
def __str__(self) -> str:
|
|
return f"metric:{self.schema_version}:{self.content_id}:{self.window_id}"
|
|
|