Python Program stops but PID is still active - python

My program stoped working after about 6 hours, but the PID is still active. Also tells me the terminal output when I use single_process module and then try to start the programm again:
There is an instance of programm.py running. Quit
The code of my program is quit simple and just reads the output from a chatroom, but I don't know why it stops working after 6 hours. Can anybody help please?:
from autobahn.asyncio.wamp import ApplicationSession
from autobahn.asyncio.wamp import ApplicationRunner
from asyncio import coroutine
from datetime import datetime
from single_process import single_process
class PoloniexComponent(ApplicationSession):
def onConnect(self):
self.join(self.config.realm)
#coroutine
def onJoin(self, details):
def onTrollbox(*args):
print("type: ", args[0])
print("msg_number: ", args[1])
print("user_name: ", args[2])
print("message: ", args[3])
print("reputation: ", args[4])
print(datetime.utcnow())
try:
yield from self.subscribe(onTrollbox, 'trollbox')
except Exception as e:
print("Could not subscribe to topic:", e)
#single_process
def main():
runner = ApplicationRunner("wss://api.poloniex.com", "realm1")
runner.run(PoloniexComponent)
if __name__ == "__main__":
main()

Related

time.sleep(300) not allowing script to stop thread | python |

I am writing a code to insert data to mongodb every 5 minutes ON and OFF
The problem here is on keyword interrupt my thread should be stop and exit the code execution
Once first record is inserted to DB my time.sleep(300) will make the script sleep
and on my terminal the following line appears -> Press enter to kill the running thread :
Incase If I change my mind don't want to run
simply when I press enter from keyboard the threading which is running and under sleep should be stop and exit
My goal is to stop the thread on the basis of input from user
My code :
import datetime
import threading
import pymongo
import time
from pymongo import MongoClient
dbUrl = pymongo.MongoClient("mongodb://localhost:1245/")
dbName = dbUrl["student"]
dbCollectionName = dbName["student_course"]
def doremon():
return "Hi Friends"
def insert_to_mongodb():
global kill_the_running_thread
while (not kill_the_running_thread):
note_start_time = datetime.datetime.now()
msg = doremon()
note_end_time = datetime.datetime.now()
dt = {"message": msg, "start_time": note_start_time, "end_time": note_end_time}
rec_id1 = dbCollectionName.insert_one(dt)
time.sleep(300)
def main():
global kill_the_running_thread
kill_the_running_thread = False
my_thread = threading.Thread(target=insert_to_mongodb)
my_thread.start()
input("Press enter to kill the running thread : ")
kill_the_running_thread = True
# Calling main
main()
There's a problem when using globals as sentinels in conjunction with sleep. The issue is that the sleep may have only just started (5 minutes in OP's case) and so it could take nearly 5 minutes for the thread to realise that it should terminate.
A preferred (by me) technique is to use a queue. You can specify a timeout on a queue and, of course, it will respond almost immediately to any data passed to it. Here's an example:
from threading import Thread
from queue import Queue, Empty
def process(queue):
while True:
try:
queue.get(timeout=5)
break
except Empty as e:
pass
print('Doing work')
queue = Queue()
thread = Thread(target=process, args=(queue,))
thread.start()
input('Press enter to terminate the thread: ')
queue.put(None)
thread.join()
The process() function will block on the queue for up to 5 seconds (in this example). If there's nothing on the queue it will do its work. If there is something (we just pass None as the trigger), it will terminate immediately
You can try customizing the class, like this:
import datetime
import threading
import pymongo
import time
from pymongo import MongoClient
dbUrl = pymongo.MongoClient("mongodb://localhost:1245/")
dbName = dbUrl["student"]
dbCollectionName = dbName["student_course"]
class ThreadWithKill(threading.Thread):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._target = kwargs.get('target')
self._kill = threading.Event()
self._sleep_duration = 300 # 5 minutes
def run(self):
while True:
# If no kill signal is set, sleep for the duration of the interval.
# If kill signal comes in while sleeping, immediately wake up and handle
self._target() # execute passed function
is_killed = self._kill.wait(self._sleep_duration)
if is_killed:
break
def kill(self):
self._kill.set()
def doremon():
return "Hi Friends"
def insert_to_mongodb():
note_start_time = datetime.datetime.now()
msg = doremon()
note_end_time = datetime.datetime.now()
dt = {"message": msg, "start_time": note_start_time, "end_time": note_end_time}
rec_id1 = dbCollectionName.insert_one(dt)
def main():
my_thread = ThreadWithKill(target=insert_to_mongodb)
my_thread.start()
input("Press enter to kill the running thread : ")
my_thread.kill()
if __name__ == "__main__":
main()
This way there is no need for the kill_the_running_thread variable.
You'll need to test this yourself, because I don't have mongodb.

Python CLick, Testing threading applications

I am trying to test a click based threading application with pytest. The application runs forever and waits for a keyboard event.
main.py
#!/usr/bin/python
import threading
import time
import typing
import logging
import click
def test_func(sample_var:str):
print("Sample is: " + sample_var)
#click.option("--sample", required=True, help="Sample String", default="sample", type=str)
#click.command()
def main(sample: str):
print("Starting App r")
interrupt = False
while not interrupt:
try:
print("Start threading ..")
my_thread = threading.Thread(
target=test_func,
kwargs=dict(sample_var=sample),
daemon=True)
my_thread.start()
my_thread.join(120)
if not interrupt:
print("Resting for 60 seconds")
time.sleep(60)
except(KeyboardInterrupt, SystemExit):
print("Received Keyboard Interrupt or system exisying, cleaning all the threads")
interrupt=True
if __name__ == "__main__":
main(auto_envvar_prefix="MYAPP")
The problem is that while testing I do not know how to send the Keyboard Interrupt Signal
main_test.py
from click.testing import CliRunner
from myapp.main import main
import pytest
import time
import click
def test_raimonitor_failing(cli_runner):
""" Tests the Startup off my app"""
runner = CliRunner()
params = ["--sample", "notsample"]
test = runner.invoke(cli = main, args = params)
expected_msg = "notsample\n"
print(test.stdout)
print(test.output)
assert 0
assert expected_msg in test.stdout
And the tests just hangs, and I don't know how to send the signal to stop it.
How can I test this system properly?
To test a KeyboardInterrupt exception handler in a click function, you can use side_effect on a Mock
from unittest import mock
with mock.patch('test_code.wait_in_loop', side_effect=KeyboardInterrupt):
result = runner.invoke(cli=main, args=params)
To make the testing easier, the time.sleep() call was moved into a separate function, and then that function was mocked.
Test Code
from unittest import mock
def test_raimonitor_failing():
""" Tests the Startup off my app"""
runner = CliRunner()
params = ["--sample", "notsample"]
with mock.patch('test_code.wait_in_loop', side_effect=KeyboardInterrupt):
result = runner.invoke(cli=main, args=params)
expected = '\n'.join(line.strip() for line in """
Starting App
Start threading ..
Sample is: notsample
Resting for 60 seconds
Received Keyboard Interrupt or system exiting, cleaning all the threads
""".split('\n')[1:-1])
assert result.output == expected
Code Under Test
from click.testing import CliRunner
import click
import threading
import time
def a_test_func(sample_var: str):
print("Sample is: " + sample_var)
def wait_in_loop():
time.sleep(60)
#click.option("--sample", required=True, help="Sample String", default="sample", type=str)
#click.command()
def main(sample: str):
print("Starting App")
interrupt = False
while not interrupt:
try:
print("Start threading ..")
my_thread = threading.Thread(
target=a_test_func,
kwargs=dict(sample_var=sample),
daemon=True)
my_thread.start()
my_thread.join(120)
if not interrupt:
print("Resting for 60 seconds")
wait_in_loop()
except(KeyboardInterrupt, SystemExit):
print("Received Keyboard Interrupt or system exiting, cleaning all the threads")
interrupt = True

Unable to use GPIO PWM when multiple threads are available

I am working on a project which continuously waits for an user input on a screen. Once a user input was detected a servo mechanism needs to open and then close. The whole solution is written in such a way that there's one main thread and few others that are forked from the main one as follows:
The problem with this setup is the this one:
If I execute only the operations handled in the main thread -> BoxOpeningManager.py works as expected. It opens and closes the servo.
If I execute once an operation handled in the main thread and then operation handled in the forked thread, the next time I try to execute operation on the main thread BoxOpeningManager.py is not working. No error, no nothing. It is just not opening the servo. I need to restart the program.
If first I execute an operation handled in the forked thread and then try to execute one handled in the main thread, main thread is again not working.
The long story short, every time I execute something on the forked thread, I can not use the BoxOpeningManager.py in the main thread anymore.
Here is the code of both scripts:
from servoManager import ServoManager
from proximitySensorManager import ProximitySensorManager
from configurationWrapping import GlobalConfigurationWrapper
from loggingManager import Logger
import time
class BoxOpeningManager():
def __init__(self):
self.configuration = GlobalConfigurationWrapper()
self.timeToKeepTheBoxOpen = self.configuration.box_time_to_keep_the_box_open()
self.logger = Logger()
self.servoManager = ServoManager()
self.proximitySensorManager = ProximitySensorManager();
def start_box_opening_procedure(self):
try:
self.servoManager.open()
t_end = time.time() + (int)(self.timeToKeepTheBoxOpen)
while time.time() < t_end:
continue
while True:
if not self.proximitySensorManager.object_in_front() :
self.servoManager.close()
break;
else :
time.sleep(1)
except BaseException as e:
self.logger.log_critical('<BoxOpeningManager.start_box_opening_procedure> => ' + str(e))
Servo manager:
import RPi.GPIO as GPIO
from time import sleep
from patternImplementations import Singleton
from loggingManager import Logger
class ServoManager():
__metaclass__ = Singleton
__OUTPUT_GPIO_PIN_NUMBER = 12
def __init__(self):
GPIO.setmode(GPIO.BOARD)#Numbers GPIOs by physical location
GPIO.setup(self.__OUTPUT_GPIO_PIN_NUMBER, GPIO.OUT)
self.pwm=GPIO.PWM(self.__OUTPUT_GPIO_PIN_NUMBER,50)
self.pwm.start(0)
self.logger = Logger()
def open(self):
try:
self.__set_angle(13)
except BaseException as e:
self.logger.log_critical('<ServoManager.open> => ' + str(e))
def close(self):
try:
self.__set_angle(185)
except BaseException as e:
self.logger.log_critical('<ServoManager.close> => ' + str(e))
def __set_angle(self, angle):
duty = (angle/18 + 2)
GPIO.output(self.__OUTPUT_GPIO_PIN_NUMBER, True)
self.pwm.ChangeDutyCycle(duty)
sleep(1)
GPIO.output(self.__OUTPUT_GPIO_PIN_NUMBER, False)
self.pwm.ChangeDutyCycle(0)

Hii, How do I run a command everytime I get an: "The process "XXX.exe" not found" error?

Basically this is my code, which is supposed to block a software of choice.
: import os
import time
import easygui
import subprocess
def main():
seconds = int(easygui.integerbox())
file = get_file()
close_file(file, seconds)
def get_file():
file_name = easygui.filesavebox()
return file_name
def close_file(file, seconds):
if os.path.exists(file):
while (seconds != 0):
exe_name = file.split("\\")
try:
subprocess.Popen('taskkill /f /im {}'.format(exe_name[-1]))
except:
print('Program not open')
time.sleep(1)
print(seconds)
seconds = seconds - 1
print('You can now use the program.')
if __name__ == '__main__':
main()
Every time I run it and not the software is not open I get this repeatedly "Error: The process "blablabla.exe" not found. So basically how can I run a command in case I get such an error?

Unable to remove lockfile

I'm trying to use zc.lockfile. I see that a lockfile is created in the same directory as my python script, but when I press ctrl+C, the file is NOT removed. I have a callback registered and have even tested given a long time (not sure if zc.lockfile spawns a new thread and needed time to complete).
import os
import sys
import signal
import time
import zc.lockfile
program_lock = None
def onExitCodePressed(signal, frame):
"""Callback run on a premature user exit."""
global program_lock
print '\r\nYou pressed Ctrl+C'
program_lock.close()
time.sleep(5)
sys.exit(0)
def main():
signal.signal(signal.SIGINT, onExitCodePressed)
if os.path.exists('myapp_lock'):
print "\nAnother instance of the program is already running.\n"
sys.exit(0)
else:
program_lock = zc.lockfile.LockFile('myapp_lock')
while True:
continue
if __name__ == '__main__':
main()

Categories

Resources