Skip to content

Commit 9e1783a

Browse files
committed
Ensure that Underlay never return nil on MultiChannel. Fixes #228
1 parent 2879f30 commit 9e1783a

File tree

1 file changed

+18
-21
lines changed

1 file changed

+18
-21
lines changed

multi.go

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,10 @@ type multiChannelImpl struct {
7070
// https://github.com/golang/go/issues/36606
7171
lastRead int64
7272

73-
ownerId string
74-
channelId string
75-
logicalName string
76-
certs concurrenz.AtomicValue[[]*x509.Certificate]
77-
headers concurrenz.AtomicValue[map[int32][]byte]
73+
ownerId string
74+
channelId string
75+
logicalName string
76+
fallbackUnderlay concurrenz.AtomicValue[Underlay]
7877

7978
options *Options
8079
waiters waiterMap
@@ -115,8 +114,7 @@ func NewMultiChannel(config *MultiChannelConfig) (MultiChannel, error) {
115114
impl.flags.Set(flagInjectUnderlayType, config.InjectUnderlayTypeIntoMessages)
116115

117116
impl.ownerId = config.Underlay.Id()
118-
impl.certs.Store(config.Underlay.Certificates())
119-
impl.headers.Store(config.Underlay.Headers())
117+
impl.fallbackUnderlay.Store(config.Underlay)
120118
impl.underlays.Append(config.Underlay)
121119

122120
groupSecret := config.Underlay.Headers()[GroupSecretHeader]
@@ -164,8 +162,7 @@ func (self *multiChannelImpl) AcceptUnderlay(underlay Underlay) error {
164162
return fmt.Errorf("new underlay for '%s' not accepted: multi-channel is closed", self.ConnectionId())
165163
}
166164

167-
self.certs.Store(underlay.Certificates())
168-
self.headers.Store(underlay.Headers())
165+
self.fallbackUnderlay.Store(underlay)
169166
self.underlays.Append(underlay)
170167

171168
self.startMultiplex(underlay)
@@ -223,19 +220,15 @@ func (self *multiChannelImpl) ConnectionId() string {
223220
}
224221

225222
func (self *multiChannelImpl) Certificates() []*x509.Certificate {
226-
return self.certs.Load()
223+
return self.fallbackUnderlay.Load().Certificates()
227224
}
228225

229226
func (self *multiChannelImpl) Headers() map[int32][]byte {
230-
return self.headers.Load()
227+
return self.fallbackUnderlay.Load().Headers()
231228
}
232229

233230
func (self *multiChannelImpl) Label() string {
234-
if u := self.Underlay(); u != nil {
235-
return fmt.Sprintf("ch{%s}->%s", self.LogicalName(), u.Label())
236-
} else {
237-
return fmt.Sprintf("ch{%s}->{}", self.LogicalName())
238-
}
231+
return fmt.Sprintf("ch{%s}->%s", self.LogicalName(), self.fallbackUnderlay.Load().Label())
239232
}
240233

241234
func (self *multiChannelImpl) GetOptions() *Options {
@@ -329,10 +322,7 @@ func (self *multiChannelImpl) IsClosed() bool {
329322
}
330323

331324
func (self *multiChannelImpl) Underlay() Underlay {
332-
if underlays := self.underlays.Value(); len(underlays) > 0 {
333-
return underlays[0]
334-
}
335-
return nil
325+
return self.fallbackUnderlay.Load()
336326
}
337327

338328
func (self *multiChannelImpl) Rx(m *Message) {
@@ -453,6 +443,13 @@ func (self *multiChannelImpl) closeUnderlay(underlay Underlay, notifier *CloseNo
453443
}
454444
return false
455445
})
446+
if self.fallbackUnderlay.Load() == underlay {
447+
underlays := self.underlays.Value()
448+
if len(underlays) > 0 {
449+
lastUnderlay := underlays[len(underlays)-1]
450+
self.fallbackUnderlay.Store(lastUnderlay)
451+
}
452+
}
456453
self.lock.Unlock()
457454

458455
if underlayRemoved {
@@ -617,7 +614,7 @@ func (self *UnderlayConstraints) countsShowValidState(ch MultiChannel, counts ma
617614
WithField("underlays", counts).
618615
Info("not enough total open underlays, closing multi-underlay channel")
619616
if err := ch.Close(); err != nil {
620-
pfxlog.Logger().WithError(err).Error("error closing underlay")
617+
pfxlog.Logger().WithError(err).Error("error closing channel")
621618
}
622619
}
623620
return false

0 commit comments

Comments
 (0)