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

Comments

Projects
None yet
4 participants
@progrium

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

This comment has been minimized.

Show comment
Hide comment
@ChrisHines

ChrisHines Nov 9, 2017

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.

ChrisHines commented Nov 9, 2017

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

This comment has been minimized.

Show comment
Hide comment
@bketelsen

bketelsen Nov 9, 2017

Contributor

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

Contributor

bketelsen commented Nov 9, 2017

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

@bketelsen

This comment has been minimized.

Show comment
Hide comment
@bketelsen

bketelsen Nov 9, 2017

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?

Contributor

bketelsen commented Nov 9, 2017

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

This comment has been minimized.

Show comment
Hide comment
@progrium

progrium 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.

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

This comment has been minimized.

Show comment
Hide comment
@peterbourgon

peterbourgon 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.

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

This comment has been minimized.

Show comment
Hide comment
@ChrisHines

ChrisHines Nov 10, 2017

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

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

ChrisHines commented Nov 10, 2017

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

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

@bketelsen

This comment has been minimized.

Show comment
Hide comment
@bketelsen

bketelsen Nov 13, 2017

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.

Contributor

bketelsen commented Nov 13, 2017

@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

This comment has been minimized.

Show comment
Hide comment
@peterbourgon

peterbourgon Nov 13, 2017

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.

peterbourgon commented Nov 13, 2017

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

This comment has been minimized.

Show comment
Hide comment
@bketelsen

bketelsen Nov 13, 2017

Contributor

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

Contributor

bketelsen commented Nov 13, 2017

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

@bketelsen

This comment has been minimized.

Show comment
Hide comment
@bketelsen

bketelsen Nov 13, 2017

Contributor

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

Contributor

bketelsen commented Nov 13, 2017

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

@peterbourgon

This comment has been minimized.

Show comment
Hide comment
@peterbourgon

peterbourgon Nov 13, 2017

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.

peterbourgon commented Nov 13, 2017

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

This comment has been minimized.

Show comment
Hide comment
@ChrisHines

ChrisHines Nov 15, 2017

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.

ChrisHines commented Nov 15, 2017

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