lmtpd: incoming mail is rejected due to closed database connection
From time to time the grouprise-lmtpd
process seems to enter a broken state.
This is indicated by the following response of the LTMP daemon after the RCPT
line is sent by the client:
Recipient address rejected: unverified address: host localhost[::1] said: 500 Error: (InterfaceError) connection already closed (in reply to RCPT TO command)
The grouprise-lmtpd process emits the following stacktrace at that moment:
SMTP session exception
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/django/db/backends/base/base.py", line 235, in _cursor
return self._prepare_cursor(self.create_cursor(name))
File "/usr/lib/python3/dist-packages/django/db/backends/postgresql/base.py", line 223, in create_cursor
cursor = self.connection.cursor()
psycopg2.InterfaceError: connection already closed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/aiosmtpd/smtp.py", line 315, in _handle_client
await method(arg)
File "/usr/lib/python3/dist-packages/aiosmtpd/smtp.py", line 606, in smtp_RCPT
status = await self._call_handler_hook('RCPT', address, rcpt_options)
File "/usr/lib/python3/dist-packages/aiosmtpd/smtp.py", line 122, in _call_handler_hook
status = await hook(self, self.session, self.envelope, *args)
File "/usr/share/grouprise/python-lib/grouprise/features/imports/management/commands/run_lmtpd.py", line 208, in handle_RCPT
error_message = self._get_recipient_check_error_message(recipient)
File "/usr/share/grouprise/python-lib/grouprise/features/imports/management/commands/run_lmtpd.py", line 190, in _get_recipient_check_error_message
elif self._contribution_processor.is_valid_groupname(local_part):
File "/usr/share/grouprise/python-lib/grouprise/features/imports/signals.py", line 225, in is_valid_groupname
groups.Group.objects.get(slug__iexact=group_name)
File "/usr/lib/python3/dist-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/lib/python3/dist-packages/django/db/models/query.py", line 402, in get
num = len(clone)
File "/usr/lib/python3/dist-packages/django/db/models/query.py", line 256, in __len__
self._fetch_all()
File "/usr/lib/python3/dist-packages/django/db/models/query.py", line 1242, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/usr/lib/python3/dist-packages/django/db/models/query.py", line 55, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "/usr/lib/python3/dist-packages/django/db/models/sql/compiler.py", line 1140, in execute_sql
cursor = self.connection.cursor()
File "/usr/lib/python3/dist-packages/django/db/backends/base/base.py", line 256, in cursor
return self._cursor()
File "/usr/lib/python3/dist-packages/django/db/backends/base/base.py", line 235, in _cursor
return self._prepare_cursor(self.create_cursor(name))
File "/usr/lib/python3/dist-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/lib/python3/dist-packages/django/db/backends/base/base.py", line 235, in _cursor
return self._prepare_cursor(self.create_cursor(name))
File "/usr/lib/python3/dist-packages/django/db/backends/postgresql/base.py", line 223, in create_cursor
cursor = self.connection.cursor()
django.db.utils.InterfaceError: connection already closed
service grouprise-lmtpd restart
resolves the issue temporarily.