Skip to content

Commit f4578ba

Browse files
committed
feat(nodestore) FilestoreNodeStorage, all credits to getsentry#76250
1 parent df97eb1 commit f4578ba

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .backend import FilestoreNodeStorage # NOQA
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import datetime
2+
import logging
3+
from io import BytesIO
4+
5+
from sentry import options as options_store
6+
from sentry.models.file import get_storage
7+
from sentry.nodestore.base import NodeStorage
8+
9+
logger = logging.getLogger("sentry.nodestore")
10+
11+
12+
class FilestoreNodeStorage(NodeStorage):
13+
"""
14+
A backend that persist nodes to configured File Store.
15+
Intended for "s3" or "gcs", which performnace may not be ideal.
16+
config.yml Configuration reference:
17+
>>> filestore.backend: "s3"
18+
... filestore.options:
19+
... access_key: "xxx"
20+
... secret_key: "xxx"
21+
... endpoint_url: "https://s3.us-east-1.amazonaws.com"
22+
... bucket_name: "sentry"
23+
... location: "/sentry"
24+
"""
25+
26+
def __init__(self, prefix_path=None):
27+
self.prefix_path: str = "nodestore/"
28+
backend = options_store.get("filestore.backend")
29+
if backend not in ["s3", "gcs"]:
30+
logger.warning(
31+
"FilestoreNodeStorage was intended for s3 or gcs, currently using: %s", backend
32+
)
33+
if prefix_path:
34+
self.prefix_path = prefix_path
35+
36+
def _get_bytes(self, id: str):
37+
storage = get_storage()
38+
path = self.node_path(id)
39+
return storage.open(path).read()
40+
41+
def _set_bytes(self, id: str, data: bytes, ttl=0):
42+
storage = get_storage()
43+
path = self.node_path(id)
44+
storage.save(path, BytesIO(data))
45+
46+
def delete(self, id):
47+
storage = get_storage()
48+
path = self.node_path(id)
49+
storage.delete(path)
50+
51+
def cleanup(self, cutoff: datetime.datetime):
52+
"""
53+
This driver does not have managed TTLs. To enable TTLs you will need to enable it on your
54+
bucket.
55+
"""
56+
raise NotImplementedError
57+
58+
def bootstrap(self):
59+
# Nothing for this backend to do during bootstrap
60+
pass
61+
62+
def node_path(self, id: str):
63+
return f"{self.prefix_path}{id}.json"

0 commit comments

Comments
 (0)