Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

what is the goal of this project? #1

Open
progrium opened this issue Nov 9, 2017 · 12 comments
Open

what is the goal of this project? #1

progrium opened this issue Nov 9, 2017 · 12 comments

Comments

@progrium
Copy link

progrium commented Nov 9, 2017

If I want a library to emit events, then I create an interface and maybe structs specific to the type of data/events and let the user register listeners. As far as I know, there isn't really a need to have a library or even really an interface to standardize this.

That said, it can be useful to have a good event emitter system. Here is a great little implementation we did:
https://godoc.org/github.com/gliderlabs/comlab/pkg/events

The problem is, every time I want to use it, I end up just doing what I said before.

@ChrisHines
Copy link

I agree with @progrium. I came here to say many of the same things and to suggest that the outcome of the discussion in go-commons/commons#1 shouldn't be an event package, but rather a package design philosophy (dare I say a design pattern?) within the go-commons packages.

@bketelsen
Copy link
Contributor

awesome, consensus forms. @ChrisHines do you want to start a draft of a design philosophy?

@bketelsen
Copy link
Contributor

the comlab/events package is exactly the interface I envisioned. And as far as whether we need one in commons, it seems like it makes more sense to make one than reinvent it for every package we build?

@progrium
Copy link
Author

progrium commented Nov 9, 2017

I'm happy to donate the events package to commons. Some notes about it that might be helpful even if it's not adopted:

An important requirement we had was allowing events to be arbitrary structs. It had to not feel "in the way". Using a simple interface that returns the name of the event is enough for the library to work, and is a simple enough method to add to event structs.

The problem becomes handlers would then need to type assert to get the type they're expecting, but with a little reflection magic, users could provide handlers that get the expected type as an argument.

All this said, I'm not sure libraries that want to expose structured events should all depend on a package like this. If we can come up with some interfaces that would allow packages to implement the interfaces and work as usual without depending on this package, that would be ideal.

Something like:

type Event interface {
    EventName() string
}

type Emitter interface {
    Emit(event Event)
}

Now a library can have their own structs that implement Event, and the library can have a way to set the Emitter to use. If set, it will emit. The trick is to understand that you're not just passing around an Event because it's actually a pointer to specific type. It can be the responsibility of an Emitter implementation to let the user receive a pointer of the proper type (like I suggested above for our implementation), or a user could just write their own Emitter with handlers that type assert based on EventName.

@peterbourgon
Copy link

peterbourgon commented Nov 10, 2017

And as far as whether we need one in commons, it seems like it makes more sense to make one than reinvent it for every package we build?

There's nothing being reinvented. Each package will have its own completely unique concept of an event (or events) that can be emitted to the calling context. Any commonality presupposed by an events package would be entirely artificial.

@ChrisHines
Copy link

@ChrisHines do you want to start a draft of a design philosophy?

I will give it a shot, give me a few days.

@bketelsen
Copy link
Contributor

@progrium @peterbourgon so are you suggesting that we define an interface in this package, or that we define an "interface" that gets redefined in many other packages. I think I got lost somewhere.

@peterbourgon
Copy link

IMO, this package has no reason to exist. Any package that wants to communicate events to its callers will/should define its own, totally unique, event types.

@bketelsen
Copy link
Contributor

OK good. that's where my confusion exists. Are there any standard ways to expose the events, register the events, and introspect them?

@bketelsen
Copy link
Contributor

more clearly - is there a contract for packages that emit events?

@peterbourgon
Copy link

Again IMO, there is no natural type-level commonality between events that would allow for this kind of standardization. Any attempt to enforce one, even with something as simple as

type Event interface {
    EventID() string
}

would do more harm than good. The contract for packages we're discussing would be a document describing best practices + a robust set of examples.

@ChrisHines
Copy link

I've posted a first draft of some general design principles as seen in the link just above this comment. Next I will write some words and provide some motivating examples specifically about publishing events from Go packages. That will likely take me several more days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants