-
Notifications
You must be signed in to change notification settings - Fork 298
[select] break the select loop if interrupt_on_signal flag is set #624
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
44c1e4e
95e3fd2
84f2923
612b120
76a25b2
2f2abb2
b520d3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,12 +77,12 @@ bool PubSub::hasCachedData() | |
return m_keyspace_event_buffer.size() > 1; | ||
} | ||
|
||
map<string, string> PubSub::get_message(double timeout) | ||
map<string, string> PubSub::get_message(double timeout, bool interrupt_on_signal) | ||
{ | ||
return get_message_internal(timeout).second; | ||
return get_message_internal(timeout, interrupt_on_signal).second; | ||
} | ||
|
||
MessageResultPair PubSub::get_message_internal(double timeout) | ||
MessageResultPair PubSub::get_message_internal(double timeout, bool interrupt_on_signal) | ||
{ | ||
MessageResultPair ret; | ||
|
||
|
@@ -93,7 +93,7 @@ MessageResultPair PubSub::get_message_internal(double timeout) | |
} | ||
|
||
Selectable *selected; | ||
int rc = m_select.select(&selected, int(timeout)); | ||
int rc = m_select.select(&selected, int(timeout), interrupt_on_signal); | ||
ret.first = rc; | ||
switch (rc) | ||
{ | ||
|
@@ -128,13 +128,13 @@ MessageResultPair PubSub::get_message_internal(double timeout) | |
|
||
// Note: it is not straightforward to implement redis-py PubSub.listen() directly in c++ | ||
// due to the `yield` syntax, so we implement this function for blocking listen one message | ||
std::map<std::string, std::string> PubSub::listen_message() | ||
std::map<std::string, std::string> PubSub::listen_message(bool interrupt_on_signal) | ||
{ | ||
const double GET_MESSAGE_INTERVAL = 600.0; // in seconds | ||
MessageResultPair ret; | ||
for (;;) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This loop also can be removed, listen_message() only used by ConfigDBConnector::listen() method, and that method already do the retry. If loop removed, some UT also need update. please refer to my PR: #629 , I close it because it's do almost same thing with this PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @liuh-80 Is it harmful to keep the loop? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not harmful to keep the loop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @liuh-80 @qiluo-msft I have the same concerns changing it due to the reason I describe in my previous comment. A behaviour change is a different subject, not relevant to this PR. If there's a decision, that listen_message is not expected to be used by anyone, then this API should be made private and its behaviour may change. That deserves to be a different PR. This PR is a bug fix. |
||
{ | ||
ret = get_message_internal(GET_MESSAGE_INTERVAL); | ||
ret = get_message_internal(GET_MESSAGE_INTERVAL, interrupt_on_signal); | ||
if (!ret.second.empty() || ret.first == Select::SIGNALINT) | ||
{ | ||
break; | ||
|
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,34 @@ | ||
import signal | ||
import os | ||
import pytest | ||
import multiprocessing | ||
import time | ||
from swsscommon import swsscommon | ||
from swsscommon.swsscommon import SignalHandlerHelper | ||
|
||
def dummy_signal_handler(signum, stack): | ||
# ignore signal so UT will not break | ||
pass | ||
|
||
def test_SignalHandler(): | ||
signal.signal(signal.SIGUSR1, dummy_signal_handler) | ||
|
||
# Register SIGUSER1 | ||
SignalHandlerHelper.registerSignalHandler(signal.SIGUSR1) | ||
happened = SignalHandlerHelper.checkSignal(signal.SIGUSR1) | ||
assert happened == False | ||
|
||
# trigger SIGUSER manually | ||
os.kill(os.getpid(), signal.SIGUSR1) | ||
happened = SignalHandlerHelper.checkSignal(signal.SIGUSR1) | ||
assert happened == True | ||
|
||
# Reset signal | ||
SignalHandlerHelper.resetSignal(signal.SIGUSR1) | ||
happened = SignalHandlerHelper.checkSignal(signal.SIGUSR1) | ||
assert happened == False | ||
|
||
# un-register signal handler | ||
SignalHandlerHelper.restoreSignalHandler(signal.SIGUSR1) | ||
os.kill(os.getpid(), signal.SIGUSR1) | ||
happened = SignalHandlerHelper.checkSignal(signal.SIGUSR1) | ||
assert happened == False | ||
|
||
def test_config_db_listen_while_signal_received(): | ||
""" Test performs ConfigDBConnector.listen() while signal is received, | ||
checks that the listen() call is interrupted and the regular KeyboardInterrupt is raised. | ||
""" | ||
c=swsscommon.ConfigDBConnector() | ||
c.subscribe('A', lambda a: None) | ||
c.connect(wait_for_init=False) | ||
event = multiprocessing.Event() | ||
|
||
def signal_handler(signum, frame): | ||
event.set() | ||
sys.exit(0) | ||
|
||
signal.signal(signal.SIGUSR1, signal_handler) | ||
|
||
def listen(): | ||
c.listen() | ||
|
||
thr = multiprocessing.Process(target=listen) | ||
thr.start() | ||
|
||
time.sleep(5) | ||
os.kill(thr.pid, signal.SIGUSR1) | ||
|
||
thr.join() | ||
|
||
assert event.is_set() |
Uh oh!
There was an error while loading. Please reload this page.