Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement env var based node and file limits on cortex and axon #1950

Merged
merged 10 commits into from
Nov 16, 2020
30 changes: 28 additions & 2 deletions synapse/axon.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import asyncio
import hashlib
import logging
Expand Down Expand Up @@ -71,7 +72,6 @@ async def put(self):
await self._save()
return


class AxonHttpHasV1(s_httpapi.Handler):

async def get(self, sha256):
Expand All @@ -80,7 +80,6 @@ async def get(self, sha256):
resp = await self.cell.has(s_common.uhex(sha256))
return self.sendRestRetn(resp)


class AxonHttpDownloadV1(s_httpapi.Handler):

async def get(self, sha256):
Expand Down Expand Up @@ -242,13 +241,39 @@ async def __anit__(self, dirn, conf=None): # type: ignore
self.axonmetrics.setdefault('size:bytes', 0)
self.axonmetrics.setdefault('file:count', 0)

self._initAxonLimits()
self.addHealthFunc(self._axonHealth)

# modularize blob storage
await self._initBlobStor()

self._initAxonHttpApi()

def _reqBelowLimit(self):

if (self.maxbytes is not None and
self.maxbytes <= self.axonmetrics.get('size:bytes')):
mesg = f'Axon is at size:bytes limit: {self.maxbytes}'
raise s_exc.HitLimit(mesg=mesg)

if (self.maxcount is not None and
self.maxcount <= self.axonmetrics.get('file:count')):
mesg = f'Axon is at file:count limit: {self.maxcount}'
raise s_exc.HitLimit(mesg=mesg)

def _initAxonLimits(self):

self.maxbytes = None
self.maxcount = None

maxcount = os.getenv('AXON_MAX_COUNT')
vEpiphyte marked this conversation as resolved.
Show resolved Hide resolved
if maxcount is not None:
self.maxcount = int(maxcount, 0)

maxbytes = os.getenv('AXON_MAX_BYTES')
if maxbytes is not None:
self.maxbytes = int(maxbytes, 0)

async def _axonHealth(self, health):
health.update('axon', 'nominal', '', data=await self.metrics())

Expand Down Expand Up @@ -310,6 +335,7 @@ async def metrics(self):

async def save(self, sha256, genr):

self._reqBelowLimit()
byts = self.axonslab.get(sha256, db=self.sizes)
if byts is not None:
return int.from_bytes(byts, 'big')
Expand Down
1 change: 1 addition & 0 deletions synapse/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ class SlabAlreadyOpen(SynErr): pass
class SpawnExit(SynErr): pass
class FeatureNotSupported(SynErr): pass

class HitLimit(SynErr): pass
class ReadOnlyLayer(SynErr): pass
class ReadOnlyProp(SynErr): pass
class RecursionLimitHit(SynErr): pass
Expand Down
18 changes: 18 additions & 0 deletions synapse/tests/test_axon.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,3 +344,21 @@ async def test_axon_perms(self):
await user.addRule((True, ('axon', 'has',)))
await user.addRule((True, ('axon', 'upload',)))
await self.runAxonTestBase(prox)

async def test_axon_limits(self):

with self.setTstEnvars(AXON_MAX_COUNT=10):
async with self.getTestAxon() as axon:
for i in range(10):
await axon.put(s_common.buid())

with self.raises(s_exc.HitLimit):
await axon.put(s_common.buid())

with self.setTstEnvars(AXON_MAX_BYTES=320):
async with self.getTestAxon() as axon:
for i in range(10):
await axon.put(s_common.buid())

with self.raises(s_exc.HitLimit):
await axon.put(s_common.buid())