laminar_core/shuffle/transport/grpc/
pipeline_identity.rs1use super::*;
5use crate::checkpoint::PipelineIdentity;
6
7impl ShuffleSender {
8 pub fn install_pipeline_identity_pair(
16 &self,
17 receiver: &ShuffleReceiver,
18 identity: &PipelineIdentity,
19 ) -> io::Result<bool> {
20 let digest = identity_digest(identity)?;
21 let _sender_assignment = self.assignment.write();
23 let _receiver_assignment = receiver.assignment.write();
24 if self.local_id != receiver.local_id
25 || self.sender_incarnation != receiver.receiver_incarnation
26 {
27 return Err(io::Error::new(
28 io::ErrorKind::PermissionDenied,
29 "pipeline identity binds one process's own sender and receiver",
30 ));
31 }
32 let mut sender_identity = self.pipeline_identity.write();
33 let mut receiver_identity = receiver.pipeline_identity.write();
34 if *sender_identity == Some(digest) && *receiver_identity == Some(digest) {
35 return Ok(false);
36 }
37 *sender_identity = Some(digest);
38 *receiver_identity = Some(digest);
39 for (scope, lease) in [
40 (&self.scope_cancel, &self.process_lease),
41 (&receiver.scope_cancel, &receiver.process_lease),
42 ] {
43 if !scope.read().is_cancelled() {
44 rotate_scope_token(scope, lease, true);
45 }
46 }
47 self.pool.lock().clear();
48 self.connect_locks.lock().clear();
49 receiver.pending_handshakes.clear();
50 Ok(true)
51 }
52}
53
54fn identity_digest(identity: &PipelineIdentity) -> io::Result<[u8; 32]> {
55 if !identity.is_canonical() {
56 return Err(io::Error::new(
57 io::ErrorKind::InvalidInput,
58 "shuffle pipeline identity is not canonical",
59 ));
60 }
61 let mut digest = [0; 32];
62 for (byte, encoded) in digest
63 .iter_mut()
64 .zip(identity.sha256.as_bytes().as_chunks::<2>().0)
65 {
66 let encoded = std::str::from_utf8(encoded).map_err(io::Error::other)?;
67 *byte = u8::from_str_radix(encoded, 16).map_err(io::Error::other)?;
68 }
69 Ok(digest)
70}