tina4ruby 3.13.81 → 3.13.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tina4
4
+ # One MQTT 3.1.1 application message as delivered by the broker.
5
+ #
6
+ # Shaped like Tina4::Job (the Queue's unit of work): it carries the payload
7
+ # plus the delivery metadata a consumer needs, and it knows how to
8
+ # acknowledge itself back to the client it came from.
9
+ #
10
+ # The two flags matter for correctness, not decoration:
11
+ #
12
+ # retained? — the broker replayed the topic's last known value to us
13
+ # because we subscribed AFTER it was published. It is current
14
+ # state, not a fresh event.
15
+ # duplicate? — the DUP flag. The broker is REDELIVERING a QoS 1 message it
16
+ # never saw acknowledged. QoS 1 is at-least-once, so a
17
+ # duplicate is guaranteed eventually; a consumer that treats a
18
+ # DUP delivery as a new sample double-counts energy or mileage
19
+ # (test case A5). Key the ingest on (device_id,
20
+ # device_timestamp) and this is harmless.
21
+ class MqttMessage
22
+ attr_reader :topic, :payload, :qos, :packet_id
23
+
24
+ def initialize(topic:, payload:, qos: 0, retained: false, duplicate: false,
25
+ packet_id: nil, client: nil)
26
+ @topic = topic
27
+ @payload = payload
28
+ @qos = qos
29
+ @retained = retained
30
+ @duplicate = duplicate
31
+ @packet_id = packet_id
32
+ @client = client
33
+ @acknowledged = false
34
+ end
35
+
36
+ # True when the broker replayed this as the topic's retained (last known) value.
37
+ def retained?
38
+ @retained
39
+ end
40
+
41
+ # True when the broker set the DUP flag — this is a REDELIVERY of a QoS 1
42
+ # message we never acknowledged, not a new sample.
43
+ def duplicate?
44
+ @duplicate
45
+ end
46
+
47
+ # Acknowledge a QoS 1 delivery (PUBACK) so the broker stops redelivering it.
48
+ # A QoS 0 message needs no acknowledgement, and a second call is a no-op, so
49
+ # this is always safe to call once processing succeeded.
50
+ def acknowledge
51
+ return false if @acknowledged || @qos.zero? || @packet_id.nil? || @client.nil?
52
+
53
+ @client.acknowledge(@packet_id)
54
+ @acknowledged = true
55
+ end
56
+
57
+ # True once this message has been acknowledged back to the broker.
58
+ def acknowledged?
59
+ @acknowledged
60
+ end
61
+
62
+ # The payload as a String — the common case, so `"#{message}"` just works.
63
+ def to_s
64
+ @payload.to_s
65
+ end
66
+
67
+ def to_h
68
+ {
69
+ topic: @topic,
70
+ payload: @payload,
71
+ qos: @qos,
72
+ retained: @retained,
73
+ duplicate: @duplicate,
74
+ packet_id: @packet_id
75
+ }
76
+ end
77
+ end
78
+ end