forked from LNP-WG/lnp-node
-
Notifications
You must be signed in to change notification settings - Fork 0
/
automata.rs
123 lines (110 loc) · 4.41 KB
/
automata.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// LNP Node: node running lightning network protocol and generalized lightning
// channels.
// Written in 2020-2022 by
// Dr. Maxim Orlovsky <[email protected]>
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the MIT License along with this software.
// If not, see <https://opensource.org/licenses/MIT>.
//! State machines help to organize complex asynchronous worflows involving multiple daemon
//! interactions.
use microservices::esb;
use crate::bus::{BusMsg, ServiceBus};
use crate::rpc::ServiceId;
use crate::Endpoints;
/// State machine used by runtimes for managing complex asynchronous workflows:
/// - Launching and managing channel daemon by lnpd for a locally created channel;
/// - Managing channel creation by channeld for a locally created channel;
/// - Accepting channel creation by channeld;
/// - Cooperative and non-cooperative channel closings;
/// - Channel operations.
pub trait StateMachine<Message, Runtime: esb::Handler<ServiceBus>>
where
esb::Error<ServiceId>: From<<Runtime as esb::Handler<ServiceBus>>::Error>,
{
/// Workflow-specific error type
type Error: std::error::Error;
/// Move state machine to a next step in response to the provided event.
/// At the completion of the cycle the state machine is consumed and `Ok(None)` is returned.
fn next(
self,
event: Event<Message>,
runtime: &mut Runtime,
) -> Result<Option<Self>, Self::Error>
where
Self: Sized;
}
/// Event changing state machine state, consisting of a certain P2P or PRC `message` sent from some
/// serivce `source` to the current `service`.
pub struct Event<'esb, Message> {
/// ESB API provided by a controller
pub endpoints: &'esb mut Endpoints,
/// Local service id (event receiver)
pub service: ServiceId,
/// Remote service id (event originator)
pub source: ServiceId,
/// Message that triggered the event
pub message: Message,
}
impl<'esb, Message> Event<'esb, Message>
where
Message: Into<BusMsg>,
{
/// Constructs event out of the provided data
pub fn with(
endpoints: &'esb mut Endpoints,
service: ServiceId,
source: ServiceId,
message: Message,
) -> Self {
Event { endpoints, service, source, message }
}
/// Finalizes event processing by sending reply message via CTL message bus
pub fn complete_ctl(self, message: Message) -> Result<(), esb::Error<ServiceId>> {
self.endpoints.send_to(ServiceBus::Ctl, self.service, self.source, message.into())
}
/// Finalizes event processing by sending reply message via CTL message bus to a specific
/// service (different from the event originating service).
pub fn complete_ctl_service(
self,
service: ServiceId,
message: Message,
) -> Result<(), esb::Error<ServiceId>> {
self.endpoints.send_to(ServiceBus::Ctl, self.service, service, message.into())
}
/// Sends a reply message via CTL message bus
pub fn send_ctl(&mut self, message: Message) -> Result<(), esb::Error<ServiceId>> {
self.endpoints.send_to(
ServiceBus::Ctl,
self.service.clone(),
self.source.clone(),
message.into(),
)
}
/// Sends reply message via CTL message bus to a specific service (different from the event
/// originating service).
pub fn send_ctl_service(
&mut self,
service: ServiceId,
message: Message,
) -> Result<(), esb::Error<ServiceId>> {
self.endpoints.send_to(ServiceBus::Ctl, self.service.clone(), service, message.into())
}
/// Finalizes event processing by sending reply message via MSG message bus
pub fn complete_msg(self, message: Message) -> Result<(), esb::Error<ServiceId>> {
self.endpoints.send_to(ServiceBus::Msg, self.service, self.source, message.into())
}
/// Finalizes event processing by sending reply message via MSG message bus to a specific
/// service (different from the event originating service).
pub fn complete_msg_service(
self,
service: ServiceId,
message: Message,
) -> Result<(), esb::Error<ServiceId>> {
self.endpoints.send_to(ServiceBus::Msg, self.service, service, message.into())
}
}