in src/AmqpLinkTerminus.cs [169:236]
internal protected bool TryAssociateLink(AmqpLink newLink, out AmqpLink stolenLink)
{
stolenLink = null;
lock (this.thisLock)
{
if (disposed)
{
return false;
}
if (this.link != null)
{
if (newLink.AllowLinkStealing(this.LinkSettings))
{
stolenLink = this.link;
// Before disassociating the link, save current Unsettledmap of the link.
// On local side, when abort is called, Close handlers are invoked and terminus state
// is saved. Remote side, does not see abort and hence is not closed, so the remote side
// will have the link in Open state. Before allowing the stealing of link, save the
// current state of the link.
if (this.Link.State != AmqpObjectState.End)
{
this.TerminusStore.SaveDeliveriesAsync(this, this.link.UnsettledMap).GetAwaiter().GetResult();
}
this.DisassociateLink();
}
else
{
return false;
}
}
this.link = newLink;
newLink.Terminus = this;
newLink.Closed += this.OnAssociatedLinkClose;
AmqpSymbol expiryPolicy = newLink.Settings.GetExpiryPolicy();
if (expiryPolicy.Equals(TerminusExpiryPolicy.LinkDetach))
{
newLink.Closed += this.OnSuspendLinkTerminus;
}
else if (expiryPolicy.Equals(TerminusExpiryPolicy.SessionEnd))
{
newLink.Session.Closed += this.OnSuspendLinkTerminus;
}
else if (expiryPolicy.Equals(TerminusExpiryPolicy.ConnectionClose))
{
newLink.Session.Connection.Closed += this.OnSuspendLinkTerminus;
}
}
IDictionary<ArraySegment<byte>, Delivery> localUnsettledDeliveries = this.TerminusStore.RetrieveDeliveriesAsync(this).Result;
if (localUnsettledDeliveries != null)
{
if (newLink.Settings.Unsettled == null)
{
newLink.Settings.Unsettled = new AmqpMap(MapKeyByteArrayComparer.Instance);
}
foreach (var kvp in localUnsettledDeliveries)
{
newLink.Settings.Unsettled.Add(new MapKey(kvp.Key), kvp.Value.State);
}
}
stolenLink?.OnLinkStolen();
return true;
}