class Core(CorePluginBase): def enable(self): self.config = deluge.configmanager.ConfigManager("myplugin.conf", DEFAULT_PREFS) core = component.get("Core") self.requests_queue = MessageQueue(87532) self.responces_queue = MessageQueue(98531) self.torrents_storage = TorrentsStorage(core) self.config = deluge.configmanager.ConfigManager("rt.conf", DEFAULT_PREFS) self.disabled = False self.thread = Thread(target=self.main) self.thread.start() def main(self): while not self.disabled: self.process_vfs_request() def parse_request_str(self, request_str): space_idx = request_str.find(' ') return int(request_str[:space_idx]), request_str[space_idx + 1:] def process_vfs_request(self): request_str, request_id = self.requests_queue.receive() offset, path = self.parse_request_str(request_str) self.torrents_storage.on_request(offset, path, 10, request_id, self.request_callback) def to_resp_str(self, allowed): return str(allowed) + '\0' def request_callback(self, request_id, result): self.responces_queue.send(self.to_resp_str(result), type=request_id) def disable(self): self.disabled = True def update(self): pass @export def set_config(self, config): """Sets the config dictionary""" for key in config.keys(): self.config[key] = config[key] self.config.save() @export def get_config(self): """Returns the config dictionary""" return self.config.config
def test_message_integrity_and_if_nebpublisher_reads_from_the_queue(self): mq = MessageQueue(123456) with patch.object(ConnectionAdapter, '__init__') as mock_method: message = "Everything is Dust in the Wind" mq.send(message) mock_method.return_value = None mock_sender = ConnectionAdapter([('127.0.0.1', 61613)], 0) mock_sender.send = MagicMock() mock_sender.__connect = MagicMock(return_value=True) ipc2activemq.main() time.sleep(0.1) mock_sender.send.assert_called_with(message, None, None) assertEqual(0, mq.current_messages)
IPC client """ # pylint: disable=no-name-in-module import sys from sysv_ipc import MessageQueue, ExistentialError if __name__ == "__main__": KEY = 128 try: mq = MessageQueue(KEY) except ExistentialError: print("IPC queue doesn't exist") sys.exit(1) while True: message_type = input("1 for time 2 to stop : ") if message_type.isdigit() and message_type in ["1", "2"]: mq.send("", type=int(message_type)) print(f"send type {message_type}") if message_type == "1": message_type, t = mq.receive(type=3) print(message_type) else: print("server stopped") break else: print("bad input")
# args queue = MessageQueue(int(argv[1])) master_name = argv[2] # master process must be the nearest parent with the exact given name master_proc = Process(getpid()) while master_proc.name() != master_name: master_proc = master_proc.parent() with Semaphore(int(argv[1])): try: # send-receive echo # type=1 : from me to other # type=2 : to me from other queue.send(msg1, type=1) # will block until a process claims the rest of the message (echo1, echo_type) = queue.receive(type=2) echo_proc = Process(queue.last_send_pid) if echo1.decode("ascii") == msg1: parent = echo_proc try: while parent.pid != master_proc.pid: parent = parent.parent() except: pass # finish the message if parent: queue.send(msg2, type=1)
Receive a message on a secure System-V IPC queue. - argv : queue - receive msg1 - echo msg1 - receive msg2 - return msg1 + msg2 This script is supposed to speak to smq_send.py Both processes must be children of the same process. """ from __future__ import print_function from sys import argv, stderr from sysv_ipc import MessageQueue, BusyError, Semaphore with Semaphore(int(argv[1]) + 1): queue = MessageQueue(int(argv[1])) try: # type=1 : to me from other # type=2 : from me to other (msg1, type) = queue.receive(type=1) queue.send(msg1, type=2) (msg2, type) = queue.receive(type=1) print((msg1 + msg2).decode("ascii")) except BusyError: queue.send("fake", block=False, type=2) raise
""" Example of an IPC server providing date information to a client """ # pylint: disable=no-name-in-module from time import asctime from sysv_ipc import MessageQueue, IPC_CREX if __name__ == "__main__": # Create IPC with key 0x80 if it doesn't exist KEY = 128 mq = MessageQueue(KEY, IPC_CREX) while True: message, t = mq.receive() # 1 : date request if t == 1: message = asctime().encode() mq.send(message, type=3) print(f"date {message} sent") # 2 : stop request elif t == 2: print("terminating") mq.remove() break
def home(exitFlag, CR=int(130 * random()), PR=int(70 * random()), ETP=int(3 * random())): print("[%d] Home : Init" % getpid()) print("[%d] Home : CR = %d\tPR = %d\tETP = %d" % (getpid(), CR, PR, ETP)) try: queueToMarket = MessageQueue(marketKey) print("[%d] Home : connected to messageQueue" % getpid()) except ExistentialError: print( "[%d] Home : can't connect to messageQueue, try launching Market before Home" % getpid()) exitFlag.value = 1 while not exitFlag.value: sleep(period) # besoin d'énergie: il en cherche auprès des maisons, sinon il achète au marché if CR > PR: energyNeeded = CR - PR sleep( timeDelay ) # petit délai pour que les receive() arrivent après les send() while energyNeeded > 0: try: message, _ = queueToMarket.receive(block=False, type=3) pid, quantity = message.decode().split(':') energyNeeded -= int(quantity) print("[%d] Home : received %d of energy" % (getpid(), int(quantity))) response = str(getpid()) + ":ACK" queueToMarket.send(response.encode(), type=int(pid)) print("[%d] Home : ACK sent to %s" % (getpid(), pid)) except (NotAttachedError, BusyError): break if energyNeeded > 0: message = str(getpid()) + ':' + str(energyNeeded) queueToMarket.send(message.encode(), type=1) print("[%d] Home : bought %d of energy to the market" % (getpid(), energyNeeded)) else: print("[%d] Home : got %d of free energy" % (getpid(), -energyNeeded)) # trop d'énergie : il fait selon ETP elif PR > CR: energyBonus = PR - CR if ETP == 0: message = str(getpid()) + ':' + str(energyBonus) queueToMarket.send(message.encode(), type=3) print("[%d] Home : gave %d of energy" % (getpid(), energyBonus)) elif ETP == 1: message = str(getpid()) + ':' + str(energyBonus) queueToMarket.send(message.encode(), type=2) print("[%d] Home : sold %d of energy to the market" % (getpid(), energyBonus)) else: try: message = str(getpid()) + ':' + str(energyBonus) queueToMarket.send(message.encode(), type=3) print( "[%d] Home : gave %d of energy, waiting for response" % (getpid(), energyBonus)) sleep(2 * timeDelay) message, t = queueToMarket.receive(block=False, type=getpid()) print("[%d] Home : response received" % getpid()) except (NotAttachedError, BusyError): message = str(getpid()) + ':' + str(energyBonus) queueToMarket.send(message.encode(), type=2) print( "[%d] Home : no response, sold %d of energy to the market" % (getpid(), energyBonus)) else: print("[%d] Home : i'm autonomous !" % getpid()) print("[%d] Home : Exit" % getpid())
class Market(ServerProcess): """ Instantiated by the server_utils, this class simulates the electricity market """ def __init__( self, shared_variables: SharedVariables, politics: int, economy: int, nb_houses: int, ipc_house: int, time_interval: int, ): super().__init__(shared_variables) # Political climate, rated from 0 to 100 self.politics = Value("i") with self.politics.get_lock(): self.politics.value = politics # Economics climate, rated from 0 to 100 self.economy = Value("i") with self.economy.get_lock(): self.economy.value = economy self.nb_houses = nb_houses # Number of houses self.mq_house = MessageQueue( ipc_house) # Message queue to communicate with houses self.daily_consumption = Value( "d") # Total consumption of the houses on this day self.surplus = Value("d") # Surplus of production self.waiting_houses = collections.deque() # Free energy waiting queue self.waiting_lock = multiprocessing.Lock() # Lock to access this queue # Set default values with self.daily_consumption.get_lock(): self.daily_consumption.value = 0 with self.surplus.get_lock(): self.surplus.value = 0 self.workers = 5 # Coefficients for energy price self.gamma = 0.98 self.alpha = [0.0001, 0.0001, 0.000001] self.beta = [0.025, 0.025, 0.025] # Politics : score between 0 and 100. # SIGUSR1 : politics situation deteriorates # SIGUSR2 : economics situation deteriorates self.market_pid = os.getpid() self.politics_process = ExternalFactor( ppid=self.market_pid, name="politics", signal_code=signal.SIGUSR1, delay=time_interval * 6, ) self.economics_process = ExternalFactor( ppid=self.market_pid, name="economics", signal_code=signal.SIGUSR2, delay=time_interval * 7, ) self.economics_process.start() self.politics_process.start() # Listen for signals signal.signal(signal.SIGUSR1, self.signal_handler) signal.signal(signal.SIGUSR2, self.signal_handler) def signal_handler(self, sig, _): """ Decreases the economical or political score when a signal is sent :param sig: signal_type :param _: ignored """ if sig == signal.SIGUSR1: with self.politics.get_lock(): self.politics.value = max(1, self.politics.value - 30) elif sig == signal.SIGUSR2: with self.economy.get_lock(): self.economy.value = max(1, self.economy.value - 30) def transaction(self, message: str, house: int): """ Performs a transaction asynchronously with a house :param message: the ipc queue raw message received :param house: the pid of the house process """ behaviour, consumption = map(float, message.decode().split(";")) behaviour = int(behaviour) # Increase the daily energy sold and bought with self.daily_consumption.get_lock(): self.daily_consumption.value += consumption # Send back the bill price, which is : # - Positive if the total consumption is greater than 0 after free energy had been taken # - Null if the house gives away its surplus energy and has consumption < 0 # - Negative if the house sells its surplus energy and has consumption < 0 if consumption > 0: # If production < consumption with self.surplus.get_lock( ): # Use the surplus given for free by other houses if self.surplus.value >= consumption: # The surplus can cover all consumption self.surplus.value -= consumption print( f"House {house} took {'{:.2f}'.format(consumption)}kWh from surplus. " f"Surplus is now {'{:.2f}'.format(self.surplus.value)}kWh\n", end="", ) consumption = 0 else: # The surplus can't cover all consumption consumption -= self.surplus.value print( f"House {house} took {'{:.2f}'.format(self.surplus.value)}" f"kWh from surplus, which is now null\n", end="", ) self.surplus.value = 0 with self.waiting_lock: # Use free givers if the house still has to pay while consumption > 0 and self.waiting_houses: # While there is a giver house_giving, surplus_house = self.waiting_houses.popleft() if surplus_house >= consumption: surplus_house -= ( consumption # decrease the surplus of this house ) print( f"House {house} took {'{:.2f}'.format(consumption)} kWh from house {house_giving} " f"surplus, which has now {'{:.2f}'.format(surplus_house)}kWh to give\n", end="", ) # and put it back in the first position of the queue self.waiting_houses.appendleft( (house_giving, surplus_house)) consumption = 0 else: # All the surplus energy is consumed print( f"House {house} took all {'{:.2f}'.format(surplus_house)} " f"kWh from house {house_giving}'s giveaway\n", end="", ) consumption -= surplus_house # Tell the giver house its energy has been taken for free self.mq_house.send("0".encode(), type=house_giving + 10**6) else: # If production > consumption if behaviour == 1: # Gives away production with self.surplus.get_lock(): self.surplus.value -= consumption # consumption is negative print( f"House {house} gave away {'{:.2f}'.format(-consumption)}kWh, " f"surplus is now {'{:.2f}'.format(self.surplus.value)}kWh\n", end="", ) consumption = 0 elif behaviour == 2: # The house sells its excess production print( f"House {house} sold {'{:.2f}'.format(-consumption)}kWh.\n", end="") elif ( behaviour == 3 ): # Put energy on wait queue to give it later, and eventually sell it if no takers print( f"Put {'{:.2f}'.format(-consumption)}kWh from house {house} on giveaway queue\n", end="", ) with self.waiting_lock: self.waiting_houses.append((house, consumption)) return # Don't return the bill now, do it later # Get the current price with self.shared_variables.price_shared.get_lock(): # Send back the bill price to the house self.mq_house.send( str(consumption * self.shared_variables.price_shared.value).encode(), type=house + 10**6, ) def update(self) -> None: """ Wait for each home to report usage Do it in a thread of a thread pool """ with concurrent.futures.ThreadPoolExecutor( max_workers=self.workers) as pool: for _ in range(self.nb_houses): message, house = self.mq_house.receive() pool.submit(self.transaction, message, house) with self.shared_variables.price_shared.get_lock(): price_kwh = self.shared_variables.price_shared.value # Type 3 houses (sell if no takers) if all the surplus isn't totally consumed while self.waiting_houses: house_giving, surplus_house = self.waiting_houses.popleft() bill = price_kwh * surplus_house self.mq_house.send(str(bill).encode(), type=house_giving + 10**6) print( f"No takers, buying {'{:.2f}'.format(-surplus_house)}kWh from house {house_giving}" ) # Reset surplus with self.surplus.get_lock(): self.surplus.value = 0 def write(self) -> None: """ Update the cost of a kWh after the turn is over """ # Get the weather conditions with self.shared_variables.weather_shared.get_lock(): temperature = self.shared_variables.weather_shared[0] cloud_coverage = self.shared_variables.weather_shared[1] # Update the price self.daily_consumption.get_lock().acquire() self.politics.get_lock().acquire() self.economy.get_lock().acquire() with self.shared_variables.price_shared.get_lock(): self.shared_variables.price_shared.value = ( self.gamma * self.shared_variables.price_shared.value + self.alpha[0] * 1 / (16 + temperature) + self.alpha[1] * cloud_coverage + self.alpha[2] * self.daily_consumption.value + self.beta[0] * 1 / self.politics.value + self.beta[1] * 1 / self.economy.value) print( f"{Fore.BLUE}New price is {round(self.shared_variables.price_shared.value, 2)} €/kWh{Style.RESET_ALL}" ) self.daily_consumption.get_lock().release() self.politics.get_lock().release() self.economy.get_lock().release() # Politics and economy tension go down, score goes up, with a limit of 100 with self.economy.get_lock(): self.economy.value = min(100, self.economy.value + 10) print( f"{Fore.MAGENTA}Economy situation: {self.economy.value}/100{Style.RESET_ALL}" ) with self.politics.get_lock(): self.politics.value = min(100, self.politics.value + 10) print( f"{Fore.MAGENTA}Politics situation: {self.politics.value}/100{Style.RESET_ALL}" ) def kill(self): """ Kills softly the child processes and then himself """ print( f"{Fore.RED}Stopping market, politics and economics{Style.RESET_ALL}" ) self.politics_process.kill() self.economics_process.kill() super().kill()