Skip to content

Commit

Permalink
🐛 Serialize mail actions
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcelWaldvogel committed Sep 27, 2020
1 parent 3bdb84f commit 1006005
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 23 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## Fixed
- `sample.env` now contains the actual names of the environment variables.
- Serialization for mail-related processing to avoid duplicate work and race
conditions

## Changed
- Format of PGP Timestamper request mail message (ISO 8601 format)
Expand Down
53 changes: 30 additions & 23 deletions autoblockchainify/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import autoblockchainify.config

logging = _logging.getLogger('mail')
serialize_receive = threading.Lock()
serialize_create = threading.Lock()


def split_host_port(host, default_port):
Expand Down Expand Up @@ -285,27 +287,31 @@ def check_for_stamper_mail(imap, stat, logfile):


def wait_for_receive(logfile):
stat = logfile.stat() # Should always succeed
logging.debug("Timestamp revision file is from %d" % stat.st_mtime)
(host, port) = split_host_port(autoblockchainify.config.arg.stamper_imap_server, 143)
with IMAP4(host=host, port=port) as imap:
imap.starttls()
imap.login(autoblockchainify.config.arg.stamper_username,
autoblockchainify.config.arg.stamper_password)
imap.select('INBOX')
if not check_for_stamper_mail(imap, stat, logfile):
# No existing message found, wait for more incoming messages
# and process them until definitely okay or giving up for good
if 'IDLE' in imap.capabilities:
imap_idle(imap, stat, logfile)
else:
logging.warning("IMAP server does not support IDLE")
# Poll every minute, for 10 minutes
for i in range(10):
time.sleep(60)
if check_for_stamper_mail(imap, stat, logfile):
return
logging.error("No response received, giving up")
with serialize_receive:
if not logfile.is_file():
logging.warning("Logfile vanished. Double mail receive thread?")
return
stat = logfile.stat()
logging.debug("Timestamp revision file is from %d" % stat.st_mtime)
(host, port) = split_host_port(autoblockchainify.config.arg.stamper_imap_server, 143)
with IMAP4(host=host, port=port) as imap:
imap.starttls()
imap.login(autoblockchainify.config.arg.stamper_username,
autoblockchainify.config.arg.stamper_password)
imap.select('INBOX')
if not check_for_stamper_mail(imap, stat, logfile):
# No existing message found, wait for more incoming messages
# and process them until definitely okay or giving up for good
if 'IDLE' in imap.capabilities:
imap_idle(imap, stat, logfile)
else:
logging.warning("IMAP server does not support IDLE")
# Poll every minute, for 10 minutes
for i in range(10):
time.sleep(60)
if check_for_stamper_mail(imap, stat, logfile):
return
logging.error("No response received, giving up")


def async_email_timestamp(resume=False):
Expand Down Expand Up @@ -333,8 +339,9 @@ def async_email_timestamp(resume=False):
new_rev = ("git commit %s\nTimestamp requested at %s\n" %
(head.target.hex,
strftime("%Y-%m-%d %H:%M:%S UTC", gmtime())))
with logfile.open('w') as f:
f.write(new_rev)
with serialize_create:
with logfile.open('w') as f:
f.write(new_rev)
send(new_rev)
threading.Thread(target=wait_for_receive, args=(logfile,),
daemon=True).start()

0 comments on commit 1006005

Please sign in to comment.