Skip to content

Commit 59001ab

Browse files
Asakizotavio
authored andcommitted
Rework on listener
Signed-off-by: asakiz <[email protected]>
1 parent ba034b1 commit 59001ab

File tree

2 files changed

+28
-81
lines changed

2 files changed

+28
-81
lines changed

examples/state_change_listener.py

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,56 +10,43 @@
1010
import updatehub.listener
1111

1212

13-
SCL = updatehub.listener.StateChangeListener()
13+
SCL = updatehub.listener.StateChange()
1414

1515

1616
def signal_handler(*args): # pylint: disable=unused-argument
1717
SCL.stop()
1818
sys.exit(0)
1919

2020

21-
def download_callback(state, command):
22-
"""
23-
Callback that will be called after the "enter download" is received.
24-
"""
25-
print("CALLBACK: " + state)
26-
print("Canceling the command...")
27-
command.cancel()
28-
print("Done!")
21+
def download_callback(_state, handler):
22+
print("function called when starting the Download state")
23+
print("it will cancel the transition")
24+
handler.cancel()
2925

3026

31-
def error_callback(error_message, command):
32-
"""
33-
Callback to be called after receiving an error state.
34-
"""
35-
print("ERROR: " + error_message)
36-
command.proceed()
37-
print("Done!")
27+
def install_callback(_state, handler):
28+
print("function called when starting the Install state")
29+
handler.proceed()
3830

3931

40-
def rebooting_callback(state, _command):
41-
"""
42-
Callback that will be called after the "enter download" is received.
43-
"""
44-
print("CALLBACK: " + state)
45-
print("Stopping listener...")
32+
def rebooting_callback(_state, _handler):
33+
print("function called when starting the reboot state")
4634
SCL.stop()
4735
sys.exit(0)
4836

4937

5038
def main():
5139
"""
52-
Main method. Instantiates a StateChangeListener, adds callbacks to the
53-
"enter download" state and the error state and then starts the listener.
40+
Main method. Instantiates a StateChange, adds callbacks to the
41+
download state and the install state and then starts the listener.
5442
"""
5543
signal.signal(signal.SIGINT, signal_handler)
5644
signal.signal(signal.SIGQUIT, signal_handler)
5745
signal.signal(signal.SIGTERM, signal_handler)
58-
SCL.on_state_change(updatehub.listener.State.DOWNLOAD,
59-
download_callback)
60-
SCL.on_state_change(updatehub.listener.State.REBOOT,
61-
rebooting_callback)
62-
SCL.on_error(error_callback)
46+
47+
SCL.on_state(updatehub.listener.State.DOWNLOAD, download_callback)
48+
SCL.on_state(updatehub.listener.State.INSTALL, install_callback)
49+
SCL.on_state(updatehub.listener.State.REBOOT, rebooting_callback)
6350

6451
SCL.start()
6552

updatehub/listener.py

Lines changed: 12 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ class State(Enum):
1818
"""
1919
A enum class that contains all reported states of the updatehub agent.
2020
21+
:PROBE: triggered when the agent is about to start probing for a
22+
update.
2123
:DOWNLOAD: triggered when the agent is about to start downloading
2224
a new update.
2325
:INSTALL: triggered when the agent is about to start installing
2426
a new update.
2527
:REBOOT: triggered when the agent is about to start rebooting the device.
2628
:ERROR: triggered when the agent has encountered an error.
2729
"""
30+
PROBE = "probe"
2831
DOWNLOAD = "download"
2932
INSTALL = "install"
3033
REBOOT = "reboot"
@@ -65,20 +68,7 @@ def proceed(self):
6568
# agent to proceed handling the current state.
6669

6770

68-
class MalformedState(Exception):
69-
"""
70-
Exception class raised on errors of the communication protocol on the
71-
socket.
72-
"""
73-
74-
75-
class StateError(Exception):
76-
"""
77-
Exception class raised when receiving errors from the agent execution.
78-
"""
79-
80-
81-
class StateChangeListener:
71+
class StateChange:
8272
"""
8373
Listener class for the agent. Objects from this class monitor a Unix socket
8474
that will receive data from the agent, and triggers registered callbacks
@@ -109,19 +99,7 @@ class StateChangeListener:
10999
"""
110100

111101
@classmethod
112-
def _get_state(cls, line):
113-
parts = line.split(' ')
114-
115-
if parts[0] == "error":
116-
raise StateError(" ".join(parts[1:]))
117-
118-
if len(parts) < 1:
119-
raise MalformedState()
120-
121-
return parts[0]
122-
123-
@classmethod
124-
def _readline(cls, conn):
102+
def _handle_connection(cls, conn):
125103
buff = io.BytesIO()
126104
while True:
127105
data = conn.recv(16)
@@ -134,13 +112,12 @@ def __init__(self):
134112
"""
135113
Creates a new listener.
136114
"""
137-
self.error_handlers = []
138115
self.listeners = {}
139116
self.sock = None
140117
self.running = False
141118
self.thread = threading.Thread(target=self._loop)
142119

143-
def on_state_change(self, state, callback):
120+
def on_state(self, state, callback):
144121
"""
145122
Adds a new callback method to a state change.
146123
@@ -153,24 +130,15 @@ def on_state_change(self, state, callback):
153130
self.listeners[key] = []
154131
self.listeners[key].append(callback)
155132

156-
def on_error(self, callback):
157-
"""
158-
Adds a new callback method to an error state.
159-
160-
:callback: the method that will be called once an error message is
161-
received by the listener.
162-
"""
163-
self.error_handlers.append(callback)
164-
165133
def start(self):
166134
"""
167135
Starts the listener. This method fails and exits the program if the
168136
updatehub-sdk-statechange-trigger program is not found at the expected
169137
path (see the SDK_TRIGGER_FILENAME constante above).
170138
"""
171-
if not os.path.isfile(StateChangeListener.SDK_TRIGGER_FILENAME):
139+
if not os.path.isfile(StateChange.SDK_TRIGGER_FILENAME):
172140
print("WARNING: updatehub-sdk-statechange-trigger not found on",
173-
StateChangeListener.SDK_TRIGGER_FILENAME)
141+
StateChange.SDK_TRIGGER_FILENAME)
174142

175143
self.running = True
176144
self.thread.start()
@@ -182,7 +150,7 @@ def stop(self):
182150
"""
183151
self.running = False
184152
socket_path = os.getenv("UH_LISTENER_TEST",
185-
default=StateChangeListener.SOCKET_PATH)
153+
default=StateChange.SOCKET_PATH)
186154

187155
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
188156
client.connect(socket_path)
@@ -209,18 +177,15 @@ def _wait_for_state(self):
209177
conn = self.sock.accept()[0]
210178
if not self.running:
211179
break
212-
line = self._readline(conn)
213-
state = self._get_state(line)
214-
self._emit(state, conn)
215-
except StateError as exception:
216-
self._throw_error(exception, conn)
180+
line = self._handle_connection(conn)
181+
self._emit(line, conn)
217182
finally:
218183
if conn is not None:
219184
conn.close()
220185

221186
def _connect(self):
222187
socket_path = os.getenv("UH_LISTENER_TEST",
223-
default=StateChangeListener.SOCKET_PATH)
188+
default=StateChange.SOCKET_PATH)
224189

225190
if os.path.exists(socket_path):
226191
os.remove(socket_path)
@@ -233,8 +198,3 @@ def _emit(self, state, connection):
233198
for callback in self.listeners.get(state) or []:
234199
command = StateCommand(connection)
235200
callback(state, command)
236-
237-
def _throw_error(self, exception, connection):
238-
for callback in self.error_handlers:
239-
command = StateCommand(connection)
240-
callback(str(exception), command)

0 commit comments

Comments
 (0)