Skip to content

Commit

Permalink
Merge pull request #113 from icgood/transient
Browse files Browse the repository at this point in the history
Retry SWIM configuration on transient failure
  • Loading branch information
icgood committed May 10, 2021
2 parents e9a1945 + 013392d commit 029e2a4
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
32 changes: 24 additions & 8 deletions pymap/cluster/swim.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@
from __future__ import annotations

import asyncio
from argparse import ArgumentParser
import logging
from argparse import ArgumentParser, Namespace
from collections.abc import Mapping
from contextlib import AsyncExitStack

from pymap.context import cluster_metadata
from pymap.interfaces.backend import ServiceInterface
from swimprotocol.config import ConfigError
from swimprotocol.config import ConfigError, TransientConfigError
from swimprotocol.members import Member, Members
from swimprotocol.status import Status
from swimprotocol.transport import load_transport


__all__ = ['transport_type', 'SwimService']

_log = logging.getLogger(__name__)

#: The :class:`~swimprotocol.transport.Transport` implementation.
transport_type = load_transport()

Expand All @@ -42,16 +45,29 @@ def _local_update(self, members: Members,
metadata: Mapping[str, bytes]) -> None:
members.update(members.local, new_metadata=metadata)

async def start(self, stack: AsyncExitStack) -> None:
args = self.config.args
try:
config = transport_type.config_type.from_args(args)
except ConfigError:
return # do not run SWIM if not configured properly
async def _start(self, args: Namespace, stack: AsyncExitStack) -> None:
while True:
try:
config = transport_type.config_type.from_args(args)
except TransientConfigError as exc:
_log.debug('SWIM configuration failure: %s', exc)
await asyncio.sleep(exc.wait_hint)
except ConfigError:
return # do not run SWIM if not configured properly
else:
break

transport = transport_type(config)
members = Members(config)
cluster_metadata.get().listen(self._local_update, members)
stack.enter_context(members.listener.on_notify(self._remote_update))
worker = await stack.enter_async_context(transport.enter(members))
task = asyncio.create_task(worker.run())
stack.callback(task.cancel)

async def start(self, stack: AsyncExitStack) -> None:
args = self.config.args
swim_stack = AsyncExitStack()
await stack.enter_async_context(swim_stack)
task = asyncio.create_task(self._start(args, swim_stack))
stack.callback(task.cancel)
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
license = f.read()

setup(name='pymap',
version='0.24.4',
version='0.24.5',
author='Ian Good',
author_email='ian@icgood.net',
description='Lightweight, asynchronous IMAP serving in Python.',
Expand Down Expand Up @@ -56,7 +56,7 @@
'macaroon': ['pymacaroons'],
'redis': ['aioredis ~= 1.3.1', 'msgpack ~= 1.0'],
'sieve': ['sievelib'],
'swim': ['swim-protocol ~= 0.3.5'],
'swim': ['swim-protocol ~= 0.3.6'],
'systemd': ['systemd-python'],
'optional': ['hiredis', 'passlib', 'pid']},
entry_points={
Expand Down

0 comments on commit 029e2a4

Please sign in to comment.