Skip to content

Commit

Permalink
Version [5.3.1]
Browse files Browse the repository at this point in the history
  • Loading branch information
I-am-PUID-0 committed Oct 15, 2024
1 parent 4b3f733 commit ceb770d
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 21 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0



## Version [5.3.1] - 2024-10-15 🚀

### Fixed 🛠️

- [Issue #59](https://github.com/I-am-PUID-0/DMB/issues/59) Zombie dotnet Processes Accumulating Over Time 🐛


## Version [5.3.0] - 2024-10-03 🚀

### Added ✨
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ services:
- /home/username/docker/DMB/Riven/data:/riven/backend/data ## Location for Riven backend data
- /home/username/docker/DMB/Riven/mnt:/mnt ## Location for Riven symlinks
- /home/username/docker/DMB/PostgreSQL/data:/postgres_data ## Location for PostgreSQL database
- /home/username/docker/pgAdmin4/data:/pgadmin/data ## Location for pgAdmin 4 data
- /home/username/docker/DMB/pgAdmin4/data:/pgadmin/data ## Location for pgAdmin 4 data
- /home/username/docker/DMB/Zilean/data:/zilean/app/data ## Location for Zilean data
environment:
- TZ=
Expand All @@ -65,7 +65,7 @@ services:
# network_mode: container:gluetun ## Example to attach to gluetun vpn container if realdebrid blocks IP address
ports:
- "3000:3000" ## Riven frontend
- "5050:5050" ## pgAdmin 4
- "5050:5050" ## pgAdmin 4
devices:
- /dev/fuse:/dev/fuse:rwm
cap_add:
Expand Down Expand Up @@ -243,10 +243,10 @@ The following table describes the ports used by the container. The mappings are
|`8080`| TCP | Riven backend - The API is accessible at the assigned port|
|`5432`| TCP | PostgreSQL - The SQL server is accessible at the assigned port|
|`5050`| TCP | pgAdmin 4 - A web UI is accessible at the assigned port|
|`8182`| TCP | Zilean - The API and Web Ui (/swagger/index.html) is accessible at the assigned port|
|`Random (9001-9999)`| TCP | Zurg - A web UI is accessible at the assigned port|
## 📂 Data Volumes
The following table describes the data volumes used by the container. The mappings
Expand Down Expand Up @@ -317,7 +317,7 @@ secrets:
seerr_address:
file: ./path/to/seerr_address.txt
zurg_user:
file: ./path/to/zurg_user.txt
file: ./path/to/zurg_user.txt
zurg_pass:
file: ./path/to/zurg_pass.txt
pgadmin_setup_email:
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ services:
- /home/username/docker/DMB/Riven/data:/riven/backend/data ## Location for Riven backend data
- /home/username/docker/DMB/Riven/mnt:/mnt ## Location for Riven symlinks
- /home/username/docker/DMB/PostgreSQL/data:/postgres_data ## Location for PostgreSQL database
- /home/username/docker/pgAdmin4/data:/pgadmin/data ## Location for pgAdmin 4 data
- /home/username/docker/DMB/pgAdmin4/data:/pgadmin/data ## Location for pgAdmin 4 data
- /home/username/docker/DMB/Zilean/data:/zilean/app/data ## Location for Zilean data
environment:
- TZ=
Expand Down
4 changes: 2 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def unmount_all():
else:
logger.error(f"Failed to unmount {full_path}: {umount.stderr.strip()}")

processes = ['riven_frontend', 'riven_backend', 'Zilean', 'PostgreSQL', 'Zurg', 'rclone', 'pgAdmin']
processes = ['riven_frontend', 'riven_backend', 'Zilean', 'PostgreSQL', 'Zurg', 'rclone', 'pgAdmin', 'pgAgent']
for process in processes:
stop_process(process)

Expand All @@ -43,7 +43,7 @@ def unmount_all():
def main():


version = '5.3.0'
version = '5.3.1'

ascii_art = f'''
Expand Down
43 changes: 29 additions & 14 deletions utils/processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super(ProcessHandler, cls).__new__(cls)
cls._instance.init_attributes(*args, **kwargs)
signal.signal(signal.SIGCHLD, cls._instance.reap_zombies)
return cls._instance

def init_attributes(self, logger):
Expand All @@ -23,6 +24,16 @@ def init_attributes(self, logger):
def __init__(self, logger):
pass

def reap_zombies(self, signum, frame):
while True:
try:
pid, _ = os.waitpid(-1, os.WNOHANG)
if pid == 0:
break
self.logger.info(f"Reaped zombie process with PID: {pid}")
except ChildProcessError:
break

def start_process(self, process_name, config_dir, command, key_type=None, suppress_logging=False, env=None):
try:
try:
Expand All @@ -49,11 +60,11 @@ def preexec_fn():
process_description = f"{process_name}"

if isinstance(command, str):
command = shlex.split(command)
command = shlex.split(command)

process_env = os.environ.copy()
process_env = os.environ.copy()
if env:
process_env.update(env)
process_env.update(env)

if process_name in ["rclone", "poetry_install", "install_poetry", "poetry_env_setup", "PostgreSQL_init", "npm_install", "node_build", "python_env_setup", "install_requirements", "setup_env_and_install", "dotnet_env_restore", "dotnet_publish_api", "dotnet_publish_scraper"]:
process = subprocess.Popen(
Expand All @@ -64,7 +75,7 @@ def preexec_fn():
cwd=config_dir,
universal_newlines=True,
bufsize=1,
env=process_env
env=process_env
)
else:
process = subprocess.Popen(
Expand All @@ -76,14 +87,14 @@ def preexec_fn():
universal_newlines=True,
bufsize=1,
preexec_fn=preexec_fn,
env=process_env
env=process_env
)

if not suppress_logging:
self.subprocess_logger = SubprocessLogger(self.logger, f"{process_description}")
self.subprocess_logger.start_logging_stdout(process)
self.subprocess_logger.start_monitoring_stderr(process, key_type, process_name)

self.logger.info(f"{process_name} process started with PID: {process.pid}")
self.processes[process_name] = process
return process
Expand All @@ -92,17 +103,21 @@ def preexec_fn():
self.logger.error(f"Error running subprocess for {process_description}: {e}")
return None


def wait(self, process_name):
process = self.processes.get(process_name)
if process:
self.stdout, self.stderr = process.communicate()
self.returncode = process.returncode
self.stdout = self.stdout.strip() if self.stdout else ""
self.stderr = self.stderr.strip() if self.stderr else ""
if self.subprocess_loggers.get(process_name):
self.subprocess_loggers[process_name].stop_logging_stdout()
self.subprocess_loggers[process_name].stop_monitoring_stderr()
try:
self.stdout, self.stderr = process.communicate()
self.returncode = process.returncode
self.stdout = self.stdout.strip() if self.stdout else ""
self.stderr = self.stderr.strip() if self.stderr else ""
except Exception as e:
self.logger.error(f"Error while waiting for process {process_name}: {e}")
finally:
if self.subprocess_loggers.get(process_name):
self.subprocess_loggers[process_name].stop_logging_stdout()
self.subprocess_loggers[process_name].stop_monitoring_stderr()
del self.processes[process_name]
else:
self.logger.error(f"No process found with the name {process_name}.")

Expand Down

0 comments on commit ceb770d

Please sign in to comment.