2

I am trying to set a class attribute basically redisconnection object once the connection is established to a variable in another class. I use setattr to set the variable. When i try to access the variable the value is null.

import importlib
import json
import sys
import time
import traceback
from twisted.python import log
import txredisapi
from settings import gcl_decorator_init
from twisted.internet import reactor

REDIS_HOST = 'localhost'
REDIS_PORT = 6379

class TestLogger(object):

    connectionObj = None

    @classmethod
    def log(cls, data):
        connObject = getattr(TestLogger, "connectionObj")
        print("connObject is : ",connObject)
        cls.connectionObj.publish("TestChannel","DataNew")

class TestServiceProtocol(txredisapi.SubscriberProtocol):

    def connectionMade(self):
        conn = txredisapi.lazyConnection(host=REDIS_HOST, port=REDIS_PORT)
        print("connected. and alive.",conn)
        setattr(TestLogger, "connectionObj", conn)
        print('value of CollectorService.connection : ',getattr(TestLogger,"connectionObj"))

    def messageReceived(self, pattern, channel, message):
        pass

    def connectionLost(self, reason):
        print("lost connection to the redis server, Reason : ", reason)

class TestServiceFactory(txredisapi.SubscriberFactory):
    maxDelay = 120
    continueTrying = True
    protocol = TestServiceProtocol

class TestService(object):
    manager = None
    connection = None

    @staticmethod
    def initialize():
        try:
            svc = TestServiceFactory()
            return svc
        except Exception as ex:
            log.msg("Exception {}".format(traceback.format_exc()))
            log.msg("Failed to initialize service {}".format(ex))
            time.sleep(5)
            raise ex

if __name__ == '__main__':
    svc = TestService.initialize()
    reactor.connectTCP(REDIS_HOST, REDIS_PORT, svc)
    reactor.run()

Below is the test program

from untitled import TestLogger

if __name__ == "__main__":
    testLogger = TestLogger()
    print("connection from object : ",getattr(testLogger,"connectionObj"))
    TestLogger.log("Data")

Require help in identifying where i get wrong. Is classmethod is appropriate? Also throw suggestion if the way to access the object is wrong.

Balachandar
  • 1,538
  • 3
  • 16
  • 25
  • From what I see, that class variable in `TestLogger` only ever gets a value if `TestService.initialize()` is called. But that does not happen in the context of your test programm, because that portion of your `untitled` (?) module is explicitly _not_ executed when that module is imported as you have that in a `__name__ == '__main__'` block – shmee Jan 09 '19 at 13:53
  • @shmee kindly understand the program and problem too. – Balachandar Jan 10 '19 at 05:31
  • 1
    Then please explain how you think `connectionObj` should get a value when you execute your test program. Because I don't see any way it could from what you shared. – shmee Jan 10 '19 at 06:16
  • First program too have a main function if you could see it. reactor.run() in it would make it to run as a server. My intension is to set the class variable which i think is fine. Or i might be wrong since i am trying to access from other process and that's where i am in need of help @shmee – Balachandar Jan 10 '19 at 09:06
  • Yes, that's exactly the point. Your test program runs in another process. Python creates a class object for `TestLogger` in the namespace of the test program process from how it is defined in the code, i.e. with `None` as a value for `connectionObj`. The fact that a redis connection object has been assigned to that class variable in the class object of another process is invisible to the test program process. You'll need a way for the two processes to communicate with each other. [Sockets](https://docs.python.org/3/library/socket.html) come to mind here. – shmee Jan 10 '19 at 09:23

0 Answers0