Skip to content

Commit ca873d4

Browse files
committed
v0.2.0 Updates
1 parent 93a09ce commit ca873d4

File tree

5 files changed

+141
-28
lines changed

5 files changed

+141
-28
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Accept Subscribers and Awaiting Responses:
5050
Sending Responses
5151
- Receiving signals and sending responses can be done with the `SignalResponder`
5252
- To respond to a signal, simply use the `respond` method and pass in the `publisher_id` of the signal's publisher, and pass in the `event` being responded to.
53-
- (COMING SOON) `srespond(signal, ...)`: A method where the user can simply pass in the received signal object they wish to respond to instead of the signal's id/event
53+
- (NEW IN v0.2.0) `srespond(signal, ...)`: A method where the user can simply pass in the received signal object they wish to respond to instead of the signal's id/event
5454
- Responding to an "initialization" signal will subscribe the responder to that specific publisher, which will now await responses from the responder for any future signals published.
5555
- NOTE: When responding to an "initialization" signal, a Response-Action-Success (RAS) code is not necessary
5656
- For any future responses to that publisher's signals, an RAS code will be necessary, and will indicate to the publisher whether or not the responder was successful in acting upon the signal

docs/index.html

Lines changed: 108 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ <h1 class="title">Module <code>state_signals</code></h1>
8383
Creates and returns logging.Logger object for detailed logging.
8484
Used by SignalExporter and SignalResponder.
8585
&#34;&#34;&#34;
86-
logger = logging.getLogger(class_name).getChild(process_name)
86+
logger = (
87+
logging.getLogger(&#34;state-signals&#34;).getChild(class_name).getChild(process_name)
88+
)
8789
try:
8890
logger.setLevel(log_level)
8991
ch = logging.StreamHandler()
@@ -103,6 +105,7 @@ <h1 class="title">Module <code>state_signals</code></h1>
103105
All potential result codes when publishing a signal. See the publish_signal
104106
method under SignalExporter for more details.
105107
&#34;&#34;&#34;
108+
106109
ALL_SUBS_SUCCESS = 0
107110
SUB_FAILED = 1
108111
MISSING_RESPONSE = 2
@@ -472,8 +475,8 @@ <h1 class="title">Module <code>state_signals</code></h1>
472475
self.subscriber = self.redis.pubsub(ignore_subscribe_messages=True)
473476
self.subscriber.subscribe(&#34;event-signal-pubsub&#34;)
474477
self.responder_id = responder_name + &#34;-&#34; + str(uuid.uuid4()) + &#34;-resp&#34;
475-
self.locked_id = None
476-
self.locked_tag = None
478+
self._locked_id = None
479+
self._locked_tag = None
477480

478481
def _parse_signal(self, signal: Dict) -&gt; Dict:
479482
&#34;&#34;&#34;
@@ -510,8 +513,8 @@ <h1 class="title">Module <code>state_signals</code></h1>
510513
(if any were provided). Returns True if the check passes or if no
511514
locks were provided, and False otherwise.
512515
&#34;&#34;&#34;
513-
if (not self.locked_id or self.locked_id == payload[&#34;publisher_id&#34;]) and (
514-
not self.locked_tag or self.locked_tag == payload[&#34;tag&#34;]
516+
if (not self._locked_id or self._locked_id == payload[&#34;publisher_id&#34;]) and (
517+
not self._locked_tag or self._locked_tag == payload[&#34;tag&#34;]
515518
):
516519
return True
517520
return False
@@ -537,13 +540,22 @@ <h1 class="title">Module <code>state_signals</code></h1>
537540
self.redis.publish(&#34;event-signal-response&#34;, response.to_json_str())
538541
self.logger.debug(f&#34;Published response for event {event} from {publisher_id}&#34;)
539542

543+
def srespond(self, signal: Signal, ras: int = None) -&gt; None:
544+
&#34;&#34;&#34;
545+
Publish a legal response to a given signal. Serves as a wrapper
546+
for the respond method. Also allows for optional ras code to be
547+
added on (required for publisher acknowledgement, but not for
548+
initialization response).
549+
&#34;&#34;&#34;
550+
self.respond(signal.publisher_id, signal.event, ras)
551+
540552
def lock_id(self, publisher_id: str) -&gt; None:
541553
&#34;&#34;&#34;
542554
Lock onto a specific publisher_id. Only receive signals from the
543555
chosen id.
544556
&#34;&#34;&#34;
545557
if isinstance(publisher_id, str):
546-
self.locked_id == publisher_id
558+
self._locked_id == publisher_id
547559
self.logger.debug(f&#34;Locked onto id: {publisher_id}&#34;)
548560
else:
549561
raise TypeError(&#34;Unsuccessful lock, &#39;publisher_id&#39; must be type str&#34;)
@@ -553,10 +565,21 @@ <h1 class="title">Module <code>state_signals</code></h1>
553565
Lock onto a specific tag. Only receive signals from the chosen tag.
554566
&#34;&#34;&#34;
555567
if isinstance(tag, str):
556-
self.locked_tag == tag
568+
self._locked_tag == tag
557569
self.logger.debug(f&#34;Locked onto tag: {tag}&#34;)
558570
else:
559-
raise TypeError(&#34;Unsuccessful lock, &#39;tag&#39; must be type str&#34;)</code></pre>
571+
raise TypeError(&#34;Unsuccessful lock, &#39;tag&#39; must be type str&#34;)
572+
573+
def unlock(self) -&gt; None:
574+
&#34;&#34;&#34;
575+
Releases both tag and publisher_id locks. Resume receiving signals
576+
from all publisher_ids and tags.
577+
&#34;&#34;&#34;
578+
self.logger.debug(
579+
f&#34;Released locks on tag &#39;{self._locked_tag}&#39; and published_id &#39;{self._locked_id}&#39;&#34;
580+
)
581+
self._locked_id = None
582+
self._locked_tag = None</code></pre>
560583
</details>
561584
</section>
562585
<section>
@@ -705,6 +728,7 @@ <h3>Methods</h3>
705728
All potential result codes when publishing a signal. See the publish_signal
706729
method under SignalExporter for more details.
707730
&#34;&#34;&#34;
731+
708732
ALL_SUBS_SUCCESS = 0
709733
SUB_FAILED = 1
710734
MISSING_RESPONSE = 2</code></pre>
@@ -1310,8 +1334,8 @@ <h3>Methods</h3>
13101334
self.subscriber = self.redis.pubsub(ignore_subscribe_messages=True)
13111335
self.subscriber.subscribe(&#34;event-signal-pubsub&#34;)
13121336
self.responder_id = responder_name + &#34;-&#34; + str(uuid.uuid4()) + &#34;-resp&#34;
1313-
self.locked_id = None
1314-
self.locked_tag = None
1337+
self._locked_id = None
1338+
self._locked_tag = None
13151339

13161340
def _parse_signal(self, signal: Dict) -&gt; Dict:
13171341
&#34;&#34;&#34;
@@ -1348,8 +1372,8 @@ <h3>Methods</h3>
13481372
(if any were provided). Returns True if the check passes or if no
13491373
locks were provided, and False otherwise.
13501374
&#34;&#34;&#34;
1351-
if (not self.locked_id or self.locked_id == payload[&#34;publisher_id&#34;]) and (
1352-
not self.locked_tag or self.locked_tag == payload[&#34;tag&#34;]
1375+
if (not self._locked_id or self._locked_id == payload[&#34;publisher_id&#34;]) and (
1376+
not self._locked_tag or self._locked_tag == payload[&#34;tag&#34;]
13531377
):
13541378
return True
13551379
return False
@@ -1375,13 +1399,22 @@ <h3>Methods</h3>
13751399
self.redis.publish(&#34;event-signal-response&#34;, response.to_json_str())
13761400
self.logger.debug(f&#34;Published response for event {event} from {publisher_id}&#34;)
13771401

1402+
def srespond(self, signal: Signal, ras: int = None) -&gt; None:
1403+
&#34;&#34;&#34;
1404+
Publish a legal response to a given signal. Serves as a wrapper
1405+
for the respond method. Also allows for optional ras code to be
1406+
added on (required for publisher acknowledgement, but not for
1407+
initialization response).
1408+
&#34;&#34;&#34;
1409+
self.respond(signal.publisher_id, signal.event, ras)
1410+
13781411
def lock_id(self, publisher_id: str) -&gt; None:
13791412
&#34;&#34;&#34;
13801413
Lock onto a specific publisher_id. Only receive signals from the
13811414
chosen id.
13821415
&#34;&#34;&#34;
13831416
if isinstance(publisher_id, str):
1384-
self.locked_id == publisher_id
1417+
self._locked_id == publisher_id
13851418
self.logger.debug(f&#34;Locked onto id: {publisher_id}&#34;)
13861419
else:
13871420
raise TypeError(&#34;Unsuccessful lock, &#39;publisher_id&#39; must be type str&#34;)
@@ -1391,10 +1424,21 @@ <h3>Methods</h3>
13911424
Lock onto a specific tag. Only receive signals from the chosen tag.
13921425
&#34;&#34;&#34;
13931426
if isinstance(tag, str):
1394-
self.locked_tag == tag
1427+
self._locked_tag == tag
13951428
self.logger.debug(f&#34;Locked onto tag: {tag}&#34;)
13961429
else:
1397-
raise TypeError(&#34;Unsuccessful lock, &#39;tag&#39; must be type str&#34;)</code></pre>
1430+
raise TypeError(&#34;Unsuccessful lock, &#39;tag&#39; must be type str&#34;)
1431+
1432+
def unlock(self) -&gt; None:
1433+
&#34;&#34;&#34;
1434+
Releases both tag and publisher_id locks. Resume receiving signals
1435+
from all publisher_ids and tags.
1436+
&#34;&#34;&#34;
1437+
self.logger.debug(
1438+
f&#34;Released locks on tag &#39;{self._locked_tag}&#39; and published_id &#39;{self._locked_id}&#39;&#34;
1439+
)
1440+
self._locked_id = None
1441+
self._locked_tag = None</code></pre>
13981442
</details>
13991443
<h3>Methods</h3>
14001444
<dl>
@@ -1436,7 +1480,7 @@ <h3>Methods</h3>
14361480
chosen id.
14371481
&#34;&#34;&#34;
14381482
if isinstance(publisher_id, str):
1439-
self.locked_id == publisher_id
1483+
self._locked_id == publisher_id
14401484
self.logger.debug(f&#34;Locked onto id: {publisher_id}&#34;)
14411485
else:
14421486
raise TypeError(&#34;Unsuccessful lock, &#39;publisher_id&#39; must be type str&#34;)</code></pre>
@@ -1456,7 +1500,7 @@ <h3>Methods</h3>
14561500
Lock onto a specific tag. Only receive signals from the chosen tag.
14571501
&#34;&#34;&#34;
14581502
if isinstance(tag, str):
1459-
self.locked_tag == tag
1503+
self._locked_tag == tag
14601504
self.logger.debug(f&#34;Locked onto tag: {tag}&#34;)
14611505
else:
14621506
raise TypeError(&#34;Unsuccessful lock, &#39;tag&#39; must be type str&#34;)</code></pre>
@@ -1484,6 +1528,50 @@ <h3>Methods</h3>
14841528
self.logger.debug(f&#34;Published response for event {event} from {publisher_id}&#34;)</code></pre>
14851529
</details>
14861530
</dd>
1531+
<dt id="state_signals.SignalResponder.srespond"><code class="name flex">
1532+
<span>def <span class="ident">srespond</span></span>(<span>self, signal: <a title="state_signals.Signal" href="#state_signals.Signal">Signal</a>, ras: int = None) ‑> None</span>
1533+
</code></dt>
1534+
<dd>
1535+
<div class="desc"><p>Publish a legal response to a given signal. Serves as a wrapper
1536+
for the respond method. Also allows for optional ras code to be
1537+
added on (required for publisher acknowledgement, but not for
1538+
initialization response).</p></div>
1539+
<details class="source">
1540+
<summary>
1541+
<span>Expand source code</span>
1542+
</summary>
1543+
<pre><code class="python">def srespond(self, signal: Signal, ras: int = None) -&gt; None:
1544+
&#34;&#34;&#34;
1545+
Publish a legal response to a given signal. Serves as a wrapper
1546+
for the respond method. Also allows for optional ras code to be
1547+
added on (required for publisher acknowledgement, but not for
1548+
initialization response).
1549+
&#34;&#34;&#34;
1550+
self.respond(signal.publisher_id, signal.event, ras)</code></pre>
1551+
</details>
1552+
</dd>
1553+
<dt id="state_signals.SignalResponder.unlock"><code class="name flex">
1554+
<span>def <span class="ident">unlock</span></span>(<span>self) ‑> None</span>
1555+
</code></dt>
1556+
<dd>
1557+
<div class="desc"><p>Releases both tag and publisher_id locks. Resume receiving signals
1558+
from all publisher_ids and tags.</p></div>
1559+
<details class="source">
1560+
<summary>
1561+
<span>Expand source code</span>
1562+
</summary>
1563+
<pre><code class="python">def unlock(self) -&gt; None:
1564+
&#34;&#34;&#34;
1565+
Releases both tag and publisher_id locks. Resume receiving signals
1566+
from all publisher_ids and tags.
1567+
&#34;&#34;&#34;
1568+
self.logger.debug(
1569+
f&#34;Released locks on tag &#39;{self._locked_tag}&#39; and published_id &#39;{self._locked_id}&#39;&#34;
1570+
)
1571+
self._locked_id = None
1572+
self._locked_tag = None</code></pre>
1573+
</details>
1574+
</dd>
14871575
</dl>
14881576
</dd>
14891577
</dl>
@@ -1538,11 +1626,13 @@ <h4><code><a title="state_signals.SignalExporter" href="#state_signals.SignalExp
15381626
</li>
15391627
<li>
15401628
<h4><code><a title="state_signals.SignalResponder" href="#state_signals.SignalResponder">SignalResponder</a></code></h4>
1541-
<ul class="">
1629+
<ul class="two-column">
15421630
<li><code><a title="state_signals.SignalResponder.listen" href="#state_signals.SignalResponder.listen">listen</a></code></li>
15431631
<li><code><a title="state_signals.SignalResponder.lock_id" href="#state_signals.SignalResponder.lock_id">lock_id</a></code></li>
15441632
<li><code><a title="state_signals.SignalResponder.lock_tag" href="#state_signals.SignalResponder.lock_tag">lock_tag</a></code></li>
15451633
<li><code><a title="state_signals.SignalResponder.respond" href="#state_signals.SignalResponder.respond">respond</a></code></li>
1634+
<li><code><a title="state_signals.SignalResponder.srespond" href="#state_signals.SignalResponder.srespond">srespond</a></code></li>
1635+
<li><code><a title="state_signals.SignalResponder.unlock" href="#state_signals.SignalResponder.unlock">unlock</a></code></li>
15461636
</ul>
15471637
</li>
15481638
</ul>

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "state-signals"
3-
version = "0.1.5"
3+
version = "0.2.0"
44
description = "Package for easy management of state/event signal publishing, subscribing, and responding"
55

66
license = "GPL"

signal_tester.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ def _listener():
1010
ras = 0
1111
else:
1212
ras = 1
13-
responder.respond(signal.publisher_id, signal.event, ras)
13+
#responder.respond(signal.publisher_id, signal.event, ras)
14+
responder.srespond(signal, ras)
1415
init = Process(target=_listener)
1516
init.start()
1617

state_signals.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ def _create_logger(
3535
Creates and returns logging.Logger object for detailed logging.
3636
Used by SignalExporter and SignalResponder.
3737
"""
38-
logger = logging.getLogger("state-signals").getChild(class_name).getChild(process_name)
38+
logger = (
39+
logging.getLogger("state-signals").getChild(class_name).getChild(process_name)
40+
)
3941
try:
4042
logger.setLevel(log_level)
4143
ch = logging.StreamHandler()
@@ -55,6 +57,7 @@ class ResultCodes(Enum):
5557
All potential result codes when publishing a signal. See the publish_signal
5658
method under SignalExporter for more details.
5759
"""
60+
5861
ALL_SUBS_SUCCESS = 0
5962
SUB_FAILED = 1
6063
MISSING_RESPONSE = 2
@@ -424,8 +427,8 @@ def __init__(
424427
self.subscriber = self.redis.pubsub(ignore_subscribe_messages=True)
425428
self.subscriber.subscribe("event-signal-pubsub")
426429
self.responder_id = responder_name + "-" + str(uuid.uuid4()) + "-resp"
427-
self.locked_id = None
428-
self.locked_tag = None
430+
self._locked_id = None
431+
self._locked_tag = None
429432

430433
def _parse_signal(self, signal: Dict) -> Dict:
431434
"""
@@ -462,8 +465,8 @@ def _check_target(self, payload: Dict) -> bool:
462465
(if any were provided). Returns True if the check passes or if no
463466
locks were provided, and False otherwise.
464467
"""
465-
if (not self.locked_id or self.locked_id == payload["publisher_id"]) and (
466-
not self.locked_tag or self.locked_tag == payload["tag"]
468+
if (not self._locked_id or self._locked_id == payload["publisher_id"]) and (
469+
not self._locked_tag or self._locked_tag == payload["tag"]
467470
):
468471
return True
469472
return False
@@ -489,13 +492,22 @@ def respond(self, publisher_id: str, event: str, ras: int = None) -> None:
489492
self.redis.publish("event-signal-response", response.to_json_str())
490493
self.logger.debug(f"Published response for event {event} from {publisher_id}")
491494

495+
def srespond(self, signal: Signal, ras: int = None) -> None:
496+
"""
497+
Publish a legal response to a given signal. Serves as a wrapper
498+
for the respond method. Also allows for optional ras code to be
499+
added on (required for publisher acknowledgement, but not for
500+
initialization response).
501+
"""
502+
self.respond(signal.publisher_id, signal.event, ras)
503+
492504
def lock_id(self, publisher_id: str) -> None:
493505
"""
494506
Lock onto a specific publisher_id. Only receive signals from the
495507
chosen id.
496508
"""
497509
if isinstance(publisher_id, str):
498-
self.locked_id == publisher_id
510+
self._locked_id == publisher_id
499511
self.logger.debug(f"Locked onto id: {publisher_id}")
500512
else:
501513
raise TypeError("Unsuccessful lock, 'publisher_id' must be type str")
@@ -505,8 +517,18 @@ def lock_tag(self, tag: str) -> None:
505517
Lock onto a specific tag. Only receive signals from the chosen tag.
506518
"""
507519
if isinstance(tag, str):
508-
self.locked_tag == tag
520+
self._locked_tag == tag
509521
self.logger.debug(f"Locked onto tag: {tag}")
510522
else:
511523
raise TypeError("Unsuccessful lock, 'tag' must be type str")
512524

525+
def unlock(self) -> None:
526+
"""
527+
Releases both tag and publisher_id locks. Resume receiving signals
528+
from all publisher_ids and tags.
529+
"""
530+
self.logger.debug(
531+
f"Released locks on tag '{self._locked_tag}' and published_id '{self._locked_id}'"
532+
)
533+
self._locked_id = None
534+
self._locked_tag = None

0 commit comments

Comments
 (0)