import asyncio
from fnmatch import fnmatch

class Relay:
    __slots__ = ('_subs',)

    def __init__(self):
        self._subs = []

    def publish(self, topic, data):
        for pattern, queue in self._subs:
            if fnmatch(topic, pattern):
                queue.put_nowait((topic, data))

    async def subscribe(self, pattern):
        queue = asyncio.Queue()
        entry = (pattern, queue)
        self._subs.append(entry)
        try:
            while True:
                yield await queue.get()
        finally:
            self._subs.remove(entry)
