This repository has been archived on 2020-09-24. You can view files and clone it, but cannot push or open issues or pull requests.
producer/consumerlocator.py

115 lines
4.4 KiB
Python
Raw Normal View History

2020-03-29 15:27:36 +02:00
#!/usr/bin/env python
2020-03-29 16:38:40 +02:00
import datetime
from communicator import Communicator
import os
2020-03-29 15:27:36 +02:00
"""
Consumer locator module, that manages the list of consumers.
2020-03-29 15:27:36 +02:00
"""
2020-03-29 17:21:36 +02:00
__author__ = "@dscharnitzky"
2020-03-29 15:27:36 +02:00
__copyright__ = "Copyright 2020, GoldenPogácsa Team"
__module_name__ = "consumerlocator"
__version__text__ = "1"
2020-03-30 21:36:26 +02:00
KNOWNCONSUMER = os.getenv("PRODUCER_KNOWNCONSUMER",'10.69.42.1')
2020-03-29 15:54:52 +02:00
2020-03-29 15:26:01 +02:00
class ConsumerLocator:
2020-03-29 15:54:52 +02:00
2020-03-29 16:46:28 +02:00
"""
2020-04-06 20:48:36 +02:00
Component responsible for managing the list of consumers. Requires an instance of :class:'communicator.Communicator'
2020-03-29 16:46:28 +02:00
"""
2020-03-30 19:33:09 +02:00
def __init__(self, uuid: str, communicator: Communicator):
2020-04-06 20:48:36 +02:00
"""Initializes the object.
Gets the known consumer's IP address from the PRODUCER_KNOWNCONSUMER envar.
:param: uuid: Not used
:param: communicator: the :class:'communicator.Communicator' instance that will be used for the low level
communication.
2020-03-29 16:46:28 +02:00
"""
self.consumerlist = [{"Host": KNOWNCONSUMER, "State": True, "LastOk": datetime.datetime.now()}]
self.currentconsumer = self.consumerlist[0]
2020-03-30 19:33:09 +02:00
self.communicator = communicator
def learnconsumerlist(self) -> None:
2020-04-06 20:48:36 +02:00
""""Learns the list of consumers from the current consumer.
Calls :func:'~communicator.Communicator.didiscoveravailableconsumers', adds the learned consumers to the list
if are not present, and then calls :func:'~consumerlocator.ConsumerLocator.updateconsumerlist'
:return: None
2020-03-29 15:54:52 +02:00
"""
recievedconsumerlist = self.communicator.discoveravailableconsumers()
if recievedconsumerlist is None:
return
for recconsumer in recievedconsumerlist:
contains = False
for consumer in self.consumerlist:
if consumer["Host"] == recconsumer:
contains = True
if not contains:
self.consumerlist.append({"Host": recconsumer, "State": True, "LastOk": datetime.datetime.now()})
self.updateconsumerlist()
2020-03-29 16:38:40 +02:00
def updateconsumerlist(self) -> None:
2020-04-06 20:48:36 +02:00
""" Updates the consumer list based on their availability.
Marks for each consumer if they are available or not. If a consumer is not available for some time (1 hour),
the it will be deleted from the list.
:return: None
2020-03-29 16:38:40 +02:00
"""
removelist = []
for consumer in self.consumerlist:
if not self.communicator.checkconsumer(consumer["Host"]):
2020-03-29 16:38:40 +02:00
consumer["State"] = False
if datetime.datetime.now() - consumer["LastOk"] > datetime.timedelta(hours=1):
removelist.append(consumer)
2020-03-29 16:38:40 +02:00
else:
consumer["LastOk"] = datetime.datetime.now()
consumer["State"] = True
for rem in removelist:
self.consumerlist.remove(rem)
2020-03-29 15:54:52 +02:00
def updateconsumer(self):
2020-04-06 20:48:36 +02:00
"""If the current consumer is not available, checks all the consumers in the list and updates the current one.
Calls :func:'~consumerlocator.ConsumerLocator.checkcurrentconsumer' and if needed
:func:'~consumerlocator.ConsumerLocator.updateconsumerlist'. Sets the :class:'communicator.Communicator'
current instance with :func:'~communicator.Communicator.set_currentconsumer'.
2020-03-29 16:46:28 +02:00
:return: the current consumer or None if there are no available customers at the moment.
2020-03-29 15:54:52 +02:00
"""
2020-03-29 16:38:40 +02:00
if not self.checkcurrentconsumer():
self.updateconsumerlist()
newcurrentconsumer = None
2020-03-29 16:38:40 +02:00
for consumer in self.consumerlist:
2020-03-29 16:38:40 +02:00
if consumer["State"]:
newcurrentconsumer = consumer
2020-03-29 16:38:40 +02:00
break
self.currentconsumer = newcurrentconsumer
if self.currentconsumer is not None:
self.learnconsumerlist()
2020-03-29 16:38:40 +02:00
if self.currentconsumer is not None:
2020-03-30 19:33:09 +02:00
self.communicator.set_currentconsumer(self.currentconsumer["Host"])
return self.currentconsumer["Host"]
2020-03-29 16:38:40 +02:00
else:
return None
2020-03-29 15:54:52 +02:00
def getcurrentconsumer(self) -> str:
2020-03-29 15:54:52 +02:00
"""
2020-04-06 20:48:36 +02:00
Returns the currently selected consumer's IP address.
2020-03-29 15:54:52 +02:00
:return: the current consumer
"""
return self.currentconsumer["Host"]
2020-03-29 15:54:52 +02:00
def checkcurrentconsumer(self) -> bool:
2020-03-29 15:54:52 +02:00
"""
2020-04-06 20:48:36 +02:00
Check the current consumer's health.
2020-03-29 15:54:52 +02:00
:return: True if OK, False if fail
"""
if self.currentconsumer is None:
return False
return self.communicator.checkconsumer(self.currentconsumer["Host"])