Skip to content

Instantly share code, notes, and snippets.

@Spindel
Last active March 31, 2019 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Spindel/93be3f582d8543b749ef8606e224930b to your computer and use it in GitHub Desktop.
Save Spindel/93be3f582d8543b749ef8606e224930b to your computer and use it in GitHub Desktop.
Delay Maps
#!/usr/bin/env python3
import asyncio
import random
import uuid
import time
class MaxMap:
def __init__(self):
self._map = {}
self._list = []
self._lock = asyncio.Lock()
async def add(self, key, val):
kv = key, val
async with self._lock:
self._map[key] = val
self._list.append(kv)
async def max(self):
async with self._lock:
self._list.sort()
kv = self._list[-1]
return kv
async def pop(self, key):
async with self._lock:
val = self._map.pop(key)
kv = key, val
self._list.remove(kv)
return val
class MaxList:
def __init__(self):
self._list = []
self._lock = asyncio.Lock()
async def add(self, item):
async with self._lock:
self._list.append(item)
async def max(self):
async with self._lock:
self._list.sort()
return self._list[-1]
async def remove(self, item):
async with self._lock:
self._list.remove(item)
class Timestamp:
"""A class representing a timestamp"""
def __init__(self):
self.start = time.monotonic()
@property
def spent(self):
now = time.monotonic()
return now - self.start
def __hash__(self):
return hash(self.start)
def __eq__(self, other):
return self.start == other.start
def __lt__(self, other):
return self.start > other.start
def __gt__(self, other):
return self.start < other.start
def __repr__(self):
return f"{self.start}, {self.spent}"
class TimestampContainer:
def __init__(self, ref):
self.start = time.monotonic()
self.ref = ref
@property
def spent(self):
now = time.monotonic()
return now - self.start
def __hash__(self):
return hash((self.ref, self.start))
def __eq__(self, other):
return (self.ref == other.ref) and (self.start == other.start)
def __lt__(self, other):
return self.start > other.start
def __gt__(self, other):
return self.start < other.start
def __repr__(self):
return f"ref:{self.ref}, start:{self.start}, spent:{self.spent}"
async def run_maxmap(jobnum, storage):
delay1 = random.uniform(0, 1)
delay2 = random.uniform(0, 1)
key = uuid.uuid4()
val = Timestamp()
await storage.add(key, val)
await asyncio.sleep(delay1)
max_val = await storage.max()
print(f"{jobnum}: Max is: {max_val}")
await asyncio.sleep(delay2)
result = await storage.pop(key)
assert result is val
async def run_list(jobnum, storage):
delay1 = random.uniform(0, 1)
delay2 = random.uniform(0, 1)
key = uuid.uuid4()
val = TimestampContainer(key)
storage.append(val)
await asyncio.sleep(delay1)
max_val = max(storage)
print(f"{jobnum}: Max is: {max_val}")
await asyncio.sleep(delay2)
storage.remove(val)
async def run_maxlist(jobnum, storage):
delay1 = random.uniform(0, 1)
delay2 = random.uniform(0, 1)
key = uuid.uuid4()
val = TimestampContainer(key)
await storage.add(val)
await asyncio.sleep(delay1)
max_val = await storage.max()
print(f"{jobnum}: Max is: {max_val}")
await asyncio.sleep(delay2)
await storage.remove(val)
async def run(loop):
storage = MaxMap()
futs = (run_maxmap(x, storage) for x in range(100))
await asyncio.gather(*futs)
lst = []
futs = (run_list(x, lst) for x in range(100))
await asyncio.gather(*futs)
newstore = MaxList()
futs = (run_maxlist(x, newstore) for x in range(100))
await asyncio.gather(*futs)
def entrypoint():
loop = asyncio.get_event_loop()
loop.run_until_complete(run(loop))
loop.close()
if "__main__" == __name__:
entrypoint()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment