0

I have issues with reading messages from two zmq servers (one set to REQ|REP and one PUB|SUB)

The two servers are running on another computer. When I read just the REQ|REP connection everything works perfectly but as soon as I also try to read the PUB|SUB connection the program freezes (I guess it waits forever for a message)

from PyQt5 import QtCore, QtGui, QtWidgets
import zmq
import ui_mainwindow

class MainWindow(QtWidgets.QMainWindow, ui_mainwindow.Ui_MainWindow):
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)
        self.context = zmq.Context()
        try:
            self.stateSocket = self.context.socket(zmq.REQ)
            self.stateSocket.connect("tcp://134.105.89.197:5555")
        except zmq.ZMQError as e:
            print('States setup failed: ', e)

        try:
            self.context = zmq.Context()
            self.anglesSocket = self.context.socket(zmq.SUB)
            self.anglesSocket.connect("tcp://134.105.89.197:5556")
        except zmq.ZMQError as e:
            print('angles setup failed: ', e)

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.publishState) 
        self.timer.setInterval(500)  
        self.timer.start()

        self.timer2 = QtCore.QTimer()
        self.timer2.timeout.connect(self.publishAngles) 
        self.timer2.setInterval(500)
        self.timer2.start()

        # +more variables unrelated to problem




    def publishState(self):
        request= "a string"
        try:
            self.stateSocket.send_string(request)
            self.reset = 0
            message = self.stateSocket.recv()#flags=zmq.NOBLOCK)
            values = [float(i) for i in message.decode("UTF-8").split(',')]
            print("Status: ", message)

        except zmq.ZMQError as e:
            print('State communication: ', e)
            values = [0] * 100

    def publishAngles(self):
        try:
            message = anglesSocket.recv_string()  # flags=zmq.NOBLOCK)
            #values = [float(i) for i in message.decode("UTF-8").split(',')]
            print("Angles: ", message)

            except zmq.ZMQError as e:
                print('Angles communication: ', e)
                values = [0] * 100

edit: added the full relevant code. What I observe is the deadlock does not come from the REQ|REP, This part alone works perfectly fine. But it seems that the PUB|SUBpart does not work in the timer function. When I make a minimal example with a while loop inside publishAngels() it works.

So is there an elegant way to use a PUB|SUB socket in a Qt Timer connected function?

FR_MPI
  • 111
  • 1
  • 9
  • I am posting here feedback from the current answer, moved into the comments space, without necessarily endorsing it: _The posted code violates the Stack Overflow community standard to post problems formulated in a form of a Minimum + Complete + Verifiable + Example of code, that reproduces the asked problem. The code-snippets above, being neither Complete, nor Verifiable, exhibit but a tiny fraction of your problem._ – halfer Mar 24 '20 at 18:03

1 Answers1

0

In case one has never worked with ZeroMQ,
one may here enjoy to first look at "ZeroMQ Principles in less than Five Seconds"
before diving into further details



Q: "Is there any stupid mistake I am overlooking?"

Yes, there are a few and all easy to refine.

1)
The, so far incomplete, visible ZeroMQ part exhibits principal uncertainty of what type of the subscription and other safe-guarding settings were, if ever, when and where, applied to the SUB-socket-Archetype AccessPoint. The same applied to the REQ-socket-Archetype AccessPoint, except the subscription management related kind(s) of setting(s) for obvious reasons.

2)
The code ignores the documented principles of the known rules for the distributed-Finite-State-Automaton's (dFSA) logic, hardwired into the REQ/REP Scalable Formal Communication Archetype. Avoid this using a correct logic, not violating the, here mandatory, dFSA-stepper of REQ-REP-REQ-REP-REQ-REP, plus make either of the REQ and SUB handling become mutually independent and you have it. In other words, a naive, dFSA-rules ignoring use of the zmq.NOBLOCK flag does not solve the deadlock either.


If you feel to be serious into becoming a distributed-computing professional, a must read is the fabulous Pieter Hintjen's book "Code Connected, Volume 1"

halfer
  • 19,824
  • 17
  • 99
  • 186
user3666197
  • 1
  • 6
  • 50
  • 92
  • 2) I am not sure what you mean by type of subscription and safe guarding. I am working off of the examples given in the zeroQM guide and this is all they use. 3) how do I make them mutually independent? The way I understand it is that if one part of the REQ-REP fails it will deadlock. How do I get around that and why does that influence the other socket that is not connected to the same port? – FR_MPI Mar 24 '20 at 14:47
  • @Felix ( the original answer was damaged not by my edits --- original is here: https://stackoverflow.com/revisions/60832969/1 ) **ad 1 )** incomplete code contains items that you ask about in your item marked *2)* **SOLUTION:** post the whole MCVE-representation code or, better, open a new question, if asking about proper parameter tweaking ( not related to the deadlocking above ). **Ad 3)** Independent handling means, deadlocked REQ/REP will not avoid using PUB/SUB. The REQ/REP deadlock appears not only when either part "fails", there are more situations, when such deadlock appears. – user3666197 Mar 24 '20 at 17:49