Skip to content
This repository was archived by the owner on Jan 16, 2026. It is now read-only.

Make senders.Sender be a concrete type.#115

Closed
keep94 wants to merge 3 commits intowavefrontHQ:masterfrom
keep94:sender-concrete
Closed

Make senders.Sender be a concrete type.#115
keep94 wants to merge 3 commits intowavefrontHQ:masterfrom
keep94:sender-concrete

Conversation

@keep94
Copy link
Copy Markdown
Contributor

@keep94 keep94 commented Oct 24, 2022

Here is what I am thinking about making senders.Sender be a concrete type. This is a breaking change that will cause most clients to have to change their code. Mostly the change will be replace senders.Sender with *senders.Sender

After doing this exercise, I am thinking we probably don't need the DistributionSender, MetricSender, or EventSender interfaces. They are declared in the sender package but they don't seem to be used anywhere. We can get rid of these extra interfaces in another PR.


// Sender Interface for sending metrics, distributions and spans to Wavefront
type Sender interface {
type senderSpec interface {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we give this a different name that describes its function more? I'm not sure what it would be, since its responsibility seems to be "sending". I was thinking about about the http.Client object and its internal Transport.

@LukeWinikates
Copy link
Copy Markdown
Contributor

I can't quite get all my guiding principles to line up toward a single conclusion about this API 😅

On the one hand, there's "depend on interfaces, not implementations", which suggests that Sender should be an interface type. But there's also not an obvious reason why there would ever be an alternative implementation of Sender, so maybe it does make sense to be strict and not expose an interface at all.

The "private implementation of public interface" pattern seems common in go packages and it hasn't bothered me up to this point. If anything I've kind of liked not having the concrete type exported.

@keep94 your main concern is that if Sender continues to be an interface, adding new methods in the future will technically be a breaking change because anybody who implements the interface will have to implement the new methods?

I wonder if we'll ever have a reason in the future for two different implementations of Sender again and if we'll regret making it a concrete type. I suppose it's unlikely since even though Sender is a concrete implementation, we can still do interface-based stuff inside it if we need polymorphism again for some reason.

I wonder if we'd miss any flexibility for testing that the interface-based approach offers - right now consumers of the library could make a fake sender and use that in their unit tests if they wanted to, which is nice, but then again they can make their own private interface for that.

After doing this exercise, I am thinking we probably don't need the DistributionSender, MetricSender, or EventSender interfaces.

Yeah, if we're not exporting Sender, I can't think of a reason to export any of these. If there's any internal usage of them for testing, we can make them not exported.

I wonder if we should change the type names while we're at it? is *senders.Sender actually *wavefront.Client and senderSpec is actually sender, where "sending" is an implementation detail of the client? I think I lean toward keeping Sender as the public name since if we change it, we probably need to change NewSender and even the senders package name. I suppose now that I'm thinking about it, I really don't like the senders package name at all, and I'd consider changing it 😬

@LukeWinikates
Copy link
Copy Markdown
Contributor

@keep94 I just thought of something - I think that eliminating the interface means that MultiSender will no longer work, at least not as cleanly as it previously did.

@keep94
Copy link
Copy Markdown
Contributor Author

keep94 commented Oct 28, 2022

@LukeWinikates actually in this PR where I get rid of the interface MultiSender does work. The reason why is because the Sender concrete type has an interface inside. Like I said before, we can go with PR #116, if you want to keep the interface, just know that we won't be able to do examples on individual methods of the Sender interface. @oppegard is back from training, and he will have feedback too.

@keep94
Copy link
Copy Markdown
Contributor Author

keep94 commented Nov 8, 2022

We decided to leave Sender as an interface so we merged #116 instead.

@keep94 keep94 closed this Nov 8, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants