1

I need to start redis server in my UT(Unit test) code which is written in python and stop it once it is finished, this is done in multiple UTs . But i see that the stop redis server part is not working properly as when redis server start is triggered in next UT it fails with Address already in Use error. And than stop also fails.

when start function is called again after stop is being done. below error is seen. 5638:M 01 Jul 2023 07:09:12.828 * monotonic clock: POSIX clock_gettime 5638:M 01 Jul 2023 07:09:12.828 # Warning: Could not create server TCP listening socket *:6379: bind: Address already in use 5638:M 01 Jul 2023 07:09:12.828 # Failed listening on port 6379 (TCP), aborting. 5632:signal-handler (1688195360) Received SIGTERM scheduling shutdown... 5632:M 01 Jul 2023 07:09:20.844 # User requested shutdown... 5632:M 01 Jul 2023 07:09:20.844 * Saving the final RDB snapshot before exiting. 5632:M 01 Jul 2023 07:09:20.849 * DB saved on disk 5632:M 01 Jul 2023 07:09:20.849 # Redis is now ready to exit, bye bye...

and later after final stop is done if i use netstat , i see some TIME_WAIT connections still visible, this might be the reason for earlier start failure?

Below is the code :

class DBServer(object):
    def __init__(self):
        super().__init__()
        self.terminate = False
        self.__initialize_db()

    def __del__(self):
        self.terminate = True
        self.db_server.terminate()
        try:
            self.db_server.wait(timeout=10)
        except subprocess.TimeoutExpired as e:
            print("%s" % e)
        finally:
            self.db_server.kill()

    def __update_dns_entry(self):
        try:
            with open("/etc/hosts", "r+") as f:
                content = f.readlines()
                for l in content:
                    if "redis" in l:
                        return
                f.seek(0, 2)
                f.write("\n127.0.0.1\tredis")
        except:
            print("Exception occurred while trying to update /etc/hosts file %s" % traceback.format_exc())
            os.exit()

    def __initialize_db(self):
        self.__update_dns_entry()
        self.db_server = subprocess.Popen(
                ["/usr/bin/redis-server",], 
                close_fds=True)

    
    def start(self):
        time.sleep(5)
        self.add_db_entries()
        self.tid = threading.Thread(target=self.run)
        self.tid.start()

    def run(self):
        while not self.terminate:
            time.sleep(1)

    def stop(self):
        self.terminate = True
        redis_conn = redis.Redis(host = "redis", port = 6379, db=os.environ["DB"])
        redis_conn.flushall()
        self.tid.join()
        time.sleep(3)

Neeraj
  • 11
  • 3

1 Answers1

1

Instead of killing/terminating the process on which Redis is running, the right way to stop redis is calling SHUTDOWN command

Although you have not mentioned it, from your code it looks like you are using redis-py where the command to shudown redis is:

redis_conn.shutdown()

The complete documentation to use shutdown using redis-py is here

Ankit Sahay
  • 1,710
  • 8
  • 14