Skip to content

Commit

Permalink
Protect against running out of disk space
Browse files Browse the repository at this point in the history
Disk space availability will be checked regularly. When a minimum
threshold value is undershot, recording will get suspended. After enough
disk space will be free again, the recording will be resumed.

By default, disk space checks will run each 60 seconds and will check
for a minimum free disk space of 10%.
  • Loading branch information
amotl committed Jun 21, 2021
1 parent d2ac94c commit f791ae0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Expand Up @@ -7,6 +7,7 @@ in progress
===========

- Use 5 minutes recording chunk size as default
- Protect against running out of disk space


2021-06-20 0.2.0
Expand Down
32 changes: 32 additions & 0 deletions saraswati/recorder.py
Expand Up @@ -3,6 +3,7 @@
# Saraswati is a robust, multi-channel audio recording, transmission and storage system
# (c) 2018-2021 Andreas Motl <andreas@hiveeyes.org>
# (c) 2019 Diren Senger <diren@diren.de>
import shutil
import threading
from functools import partial
from typing import List
Expand Down Expand Up @@ -40,6 +41,12 @@ class SaraswatiRecorder(threading.Thread):
"""

# How often to check for disk usage (seconds).
SERVICE_TASK_INTERVAL = 60

# How much disk space should be free to sustain recording.
DISK_SPACE_MINIMUM_THRESHOLD = 0.1

def __init__(self, settings: SaraswatiSettings):

super().__init__()
Expand Down Expand Up @@ -68,13 +75,19 @@ def __init__(self, settings: SaraswatiSettings):
# Invoke the pipeline.
def run(self):
logger.info("Starting audio recorder")
# GLib.idle_add(self.service_idle)
self.mainloop.run()

def service_idle(self):
logger.info("Service idle")

def record(self):
try:
self.check_disk_usage()
self.play()
except Exception as ex:
logger.error(f"Recording suspended: {ex}")
self.stop()
finally:
GLib.timeout_add_seconds(self.SERVICE_TASK_INTERVAL, self.record)

Expand All @@ -89,6 +102,25 @@ def play(self):
if success:
logger.info("Started recording")

def stop(self):
# https://www.programcreek.com/python/example/69113/gi.repository.GLib.MainLoop
success = False
for i, pipeline in enumerate(self.pipelines):
(outcome, state, pending) = pipeline.gst.get_state(timeout=Gst.SECOND)
if state == Gst.State.PLAYING:
logger.info(f"Stopping pipeline: {pipeline}")
pipeline.gst.set_state(Gst.State.NULL)
success = True
if success:
logger.info("Stopped recording")

def check_disk_usage(self):
usage = shutil.disk_usage(self.settings.spool_path)
if usage.free / usage.total < self.DISK_SPACE_MINIMUM_THRESHOLD:
raise ResourceWarning(
f"Disk space minimum threshold {self.DISK_SPACE_MINIMUM_THRESHOLD * 100}% reached"
)

@property
def output_location(self):
"""
Expand Down

0 comments on commit f791ae0

Please sign in to comment.