ozzy_replication/normal/
commit.rs1use super::NormalReplica;
5use crate::{Commit, Prefix, PrepareOk, ReplicationError};
6use ozzy_proto::NodeId;
7
8impl NormalReplica {
9 pub fn acknowledgment(&self) -> Result<PrepareOk, ReplicationError> {
11 self.require_normal()?;
12 if self.is_primary() {
13 return Err(ReplicationError::WrongRole);
14 }
15 Ok(PrepareOk {
16 scope: self.configuration.scope(),
17 durable: self.prefix_at(self.journal.snapshot().durable)?,
18 })
19 }
20
21 pub fn receive_ack(&mut self, from: NodeId, ack: PrepareOk) -> Result<(), ReplicationError> {
24 let (scope, prefix) = (ack.scope, ack.durable);
25 self.require_scope(scope)?;
26 let voter = self.configuration.voter_index(from)?;
27 if !self.is_primary() || voter == self.local {
28 return Err(ReplicationError::WrongRole);
29 }
30 if prefix.op < self.applied.op {
31 return Ok(());
32 }
33 if self.prefix_at(prefix.op)? != prefix {
34 return Err(self.conflict());
35 }
36 self.acknowledged[voter] = self.acknowledged[voter].max(prefix.op);
37 self.advance_commit()
38 }
39
40 pub fn announcement(&self) -> Result<Commit, ReplicationError> {
42 self.require_normal()?;
43 if !self.is_primary() {
44 return Err(ReplicationError::WrongRole);
45 }
46 Ok(Commit {
47 scope: self.configuration.scope(),
48 committed: self.committed,
49 })
50 }
51
52 pub fn start_view(&self) -> Result<Option<crate::StartView>, ReplicationError> {
56 self.require_normal()?;
57 if !self.is_primary() {
58 return Err(ReplicationError::WrongRole);
59 }
60 Ok(self.installed_view)
61 }
62
63 pub(crate) fn activation_prefix(&self) -> Result<Prefix, ReplicationError> {
64 self.require_normal()?;
65 let snapshot = self.snapshot();
66 if self
67 .installed_view
68 .is_none_or(|installed| installed.accepted != snapshot.accepted)
69 || snapshot.committed != snapshot.accepted
70 || snapshot.journal.durable < snapshot.accepted.op
71 || (self.is_primary() && self.backup_acknowledged() < snapshot.accepted.op)
72 {
73 return Err(ReplicationError::ActivationPending);
74 }
75 Ok(snapshot.accepted)
76 }
77
78 pub(crate) fn observe_installed_start(
79 &mut self,
80 from: NodeId,
81 start: crate::StartView,
82 ) -> Result<(), ReplicationError> {
83 self.require_scope(start.scope)?;
84 self.require_primary(from)?;
85 if self.is_primary() {
86 return Err(ReplicationError::WrongRole);
87 }
88 if self.installed_view != Some(start) {
89 return Err(self.conflict());
90 }
91 Ok(())
92 }
93
94 pub fn receive_commit(&mut self, from: NodeId, commit: Commit) -> Result<(), ReplicationError> {
100 self.require_scope(commit.scope)?;
101 self.require_primary(from)?;
102 if self.is_primary() {
103 return Err(ReplicationError::WrongRole);
104 }
105 if commit.committed.op < self.applied.op {
106 return Ok(());
107 }
108 if commit.committed.op > self.accepted.op
109 && self.journal_tail.is_none()
110 && self.accepted.op > self.known_commit
111 {
112 self.known_commit = self.accepted.op;
116 self.advance_commit()?;
117 }
118 if self.prefix_at(commit.committed.op)? != commit.committed {
119 return Err(self.conflict());
120 }
121 self.known_commit = self.known_commit.max(commit.committed.op);
122 self.advance_commit()
123 }
124}