sequenceDiagram title NATS — CREATE_RESOURCE : Pair A découvre Pair B et établit le stream participant AppA as App Pair A (oc-api) participant NATSA as NATS A participant NodeA as Node A participant StreamA as StreamService A participant NodeB as Node B participant StreamB as StreamService B participant DBA as DB Pair A (oc-lib) Note over AppA: Pair B vient d'être découvert
(via indexeur ou manuel) AppA->>NATSA: Publish(CREATE_RESOURCE, {
FromApp:"oc-api",
Datatype:PEER,
Payload: Peer B {StreamAddress_B, Relation:PARTNER}
}) NATSA->>NodeA: ListenNATS callback → CREATE_RESOURCE NodeA->>NodeA: resp.FromApp == "oc-discovery" ? → Non, continuer NodeA->>NodeA: json.Unmarshal(payload) → peer.Peer B NodeA->>NodeA: pp.AddrInfoFromString(B.StreamAddress) Note over NodeA: ad_B = {ID: PeerID_B, Addrs: [...]} NodeA->>StreamA: Mu.Lock() alt peer B.Relation == PARTNER NodeA->>StreamA: ConnectToPartner(B.StreamAddress) StreamA->>StreamA: AddrInfoFromString(B.StreamAddress) → ad_B StreamA->>NodeB: Connect (libp2p) StreamA->>NodeB: NewStream /opencloud/resource/heartbeat/partner/1.0 StreamA->>NodeB: json.Encode(Heartbeat{Name_A, DID_A, PeerID_A}) NodeB->>StreamB: HandlePartnerHeartbeat(stream) StreamB->>StreamB: CheckHeartbeat → bandwidth challenge StreamB->>StreamA: Echo(payload) StreamB->>StreamB: streams[ProtocolHeartbeatPartner][PeerID_A] = {DID_A, Expiry=now+10s} StreamA->>StreamA: streams[ProtocolHeartbeatPartner][PeerID_B] = {DID_B, Expiry=now+10s} Note over StreamA,StreamB: Stream partner long-lived établi
dans les deux sens else peer B.Relation != PARTNER (révocation / blacklist) Note over NodeA: Supprimer tous les streams vers Pair B loop Pour chaque protocole dans Streams NodeA->>StreamA: streams[proto][PeerID_B].Stream.Close() NodeA->>StreamA: delete(streams[proto], PeerID_B) end end NodeA->>StreamA: Mu.Unlock() NodeA->>DBA: (pas de write direct ici — géré par l'app source)