Skip to content

Support subscribing to event.Feed with interface channel and sending implementers #22260

@gust1n

Description

@gust1n

Rationale

Sorry if this is too meta (feel free to close), but I'm using your fanstastic event.Feed in another project, and stumbled upon the issue that typecheck() checks that it's the EXACT same type, not considering interfaces.

I suggest that if the registered type of the event.Feed is an interfaces, all implementers should be accepted by send as well.

This is NOT working today, but would with suggested change:

type Message interface{}
type SomeMessage struct{}
type SomeOtherMessage struct{}

feed := event.Feed{}

ch := make(chan Message)
feed.Subscribe(ch)
feed.Send(SomeMessage{}) // will panic

Implementation

Do you have ideas regarding the implementation of this feature?

This should work on the sending part, perhaps need a different check for registering subsribers, to not allow subscribing with a specific implementer channel (e.g. chan <- SomeOtherMessage from above)

// note: callers must hold f.mu
func (f *Feed) typecheck(typ reflect.Type) bool {
	if f.etype == nil {
		f.etype = typ
		return true
	}
	return f.etype == typ || (f.etype.Kind() == reflect.Interface && typ.Implements(f.etype)) // added part after ||
}

Are you willing to implement this feature?
Yes, can send PR with tests covering this if accepted.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions