ZeroCM / zcm

Zero Communications and Marshalling
http://zerocm.github.io/zcm/
GNU Lesser General Public License v2.1
233 stars 67 forks source link

Can't unsubscribe a normal channel #413

Closed dfhe2004 closed 1 year ago

dfhe2004 commented 1 year ago

I am confuse the logic of unsubscription, in some case, it cannot correct unsubscribe a normal channel. Here is a test code:

import time
import os
os.environ['ZCM_DEBUG'] = '1'

from zerocm import ZCM
from example_t import example_t     # define in <your-zcm-dir>/test/types

def _handler(chnl, evt):
    print(f'[-] {chnl} : {evt}')

def run():
    zcm = ZCM("ipc://my_channel")
    if not zcm.good():
        print('cannot create zcm')
        exit()

    #--
    regex_subs1 = zcm.subscribe(".+:regex_channel:1", example_t, _handler)
    regex_subs2 = zcm.subscribe(".+:regex_channel:2", example_t, _handler)
    normal_subs = zcm.subscribe("normal_channel", example_t,  _handler)

    zcm.start()

    #--
    time.sleep(3)

    zcm.unsubscribe(regex_subs1)
    zcm.unsubscribe(regex_subs2)
    zcm.unsubscribe(normal_subs)

    zcm.stop()    

if __name__=='__main__':
    run()    
    print('[-] --- over ---')

the output is : ZCM-DEBUG: failed to find the subscription channel in unsubscribe() (../zcm/blocking.cpp @518)


when check the source code of zcm/transport/transport_zmq_local.cpp, the problem is here https://github.com/ZeroCM/zcm/blob/master/zcm/transport/transport_zmq_local.cpp#L355-L369

When I unsubscribe from the regex channel, line 367 also deletes a normal channel

I think the unsubscribe logic should be :

        auto cur = std::regex(channel);
                regexChannels.erase(channel);

                for (auto it = subsocks.begin(); it != subsocks.end(); ) {
                    if (it->second.second || isRegexSubscribed(it->first) || !regex_match(it->first, cur)) {
                        ++it;
                        continue;
                    }

                    auto ret = subsockDelete(it); // updates it
                    if (ret != ZCM_EOK) return ret;
                }

@jbendes test_code.zip

jbendes commented 1 year ago

I'll have to dive into this to take a look later. I would not be surprised if there were a bug in unsubscribe of regex though. That's not a heavily used part of the API. Will take a look at your change and get back to you! Thanks for the thorough submission! If only all questions could be as well asked as this one :)

jbendes commented 1 year ago

This is on my radar. There's almost definitely a bug with unsubscribes. Working on diagnosing. Unsubscribing is just such a low priority for most people who use this library that it is largely a neglected part of zcm. If this is urgent, please let me know and I'll prioritize getting out a fix