0

I'm working with tornado and websockets(sockjs) and having trouble while handling incoming messages, getting around this specific case which is that of a circular class reference. The issue is not related to websockets per se, but essentially the cyclicity.

Here's the file which defines the class Socket for handing incoming messages, it also defines the class Async which needs the class Socket. on_message is triggered when a message is received from the client :

from logicmodule import Logic

class Async(object):

    def notify_user(self, *args):
        print("Notifying user!")
        Socket.send_message("ASYNC CALLBACK: notify_user ARGS: {:}\n".format(args))

async = Async()
logic = Logic(async)

class Socket(SockJSConnection):

    clients = set()

    def on_open(self, request):

        print("Opened Connection...")
        self.clients.add(self)

    def send_message(self, message, operation):

        return self.send(json.dumps({
            'operation': operation,
            'data': message,
        }))

    def on_message(self, msg):
        data = json.loads(msg)
        projectData = logic.create_project(data['project_info'])
        self.send_message(projectData, data['operation'])

EDIT: The Logic Class implements one method create_project, takes the async class as a parameter whose method notify_user is called within the create_project method. notify_user requires an instance of Socket class which can be created only on an incoming message in the on_open method. That instance will be a persistent connection over which the message will be sent back to user in the notify_user method.

This is may be a easy hack, but I'm new to python. How do I provide an instance of Socket to Async on an incoming message which has to be given to logic beforehand ? Please help, thanks!

vivekanon
  • 1,813
  • 3
  • 22
  • 44
  • You are already providing it in your solution, What's the problem? – hspandher Sep 23 '15 at 08:47
  • @hspandher he has circular dependency; file A imports B and file B imports A – Tim Sep 23 '15 at 08:48
  • 2
    What are the two modules A and B here? I mean you haven't describerdwhere are you getting circular dependency issue. – hspandher Sep 23 '15 at 08:57
  • 2
    Does `Async` need the *class* `Socket` or an *instance of `Socket`*? In the example `Socket.send_message()` doesn't seem to make sense, since `send_message()` is not a static/class method. – dhke Sep 23 '15 at 09:01
  • @dhke It needs the instance, but the instance can be created only on an incoming message. I'm not sure how do I instantiate Socket within on_mesage and then give it to logic. – vivekanon Sep 23 '15 at 09:06
  • @mystikacid I might be misunderstanding this, but `on_message()` has a `Socket` instance in `self`. Is there a problem with just passing `self`? – dhke Sep 23 '15 at 10:41
  • @dhke The problem is I cannot pass the self to a particular method in Logic. I would need the async instance available throughout the class scope. – vivekanon Sep 23 '15 at 11:03

1 Answers1

0

As a general rule to avoid circular dependency, if file A needs C from file B and file B needs D from file A, maybe C and D belongs together in some other file.

Although, if A needs B and B needs A is the case, maybe both A and B belongs together in same module.

hspandher
  • 15,934
  • 2
  • 32
  • 45