5 ms·
Golang script to send and receive events with a tiny simple API
- fiatjaf 11y agoI'm curious about use cases for this.
- simoncion 11y agoThis smells to me like a Publish/Subscribe mechanism. [0] I mean, this would be useful anywhere you want to send events/messages to some number of interested "parties", when you don't necessarily know what or who those parties are going to be ahead of time. I'm not snarking when I ask this, it's a genuine question: Have you ever done that sort of thing before? [0] https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_patt...
- dantaylor08 11y agoI've used almost this exact pattern (in Go) for a data normalization system. Considered sharing the code, but "never got around to it". What I built actually closely resembled node.js's streams. Really convenient when you've got various chains of transformations that need to be combined/reordered/dropped while processing streams of data.
- gianlucaguarini 11y agoI am not reinventing the wheel here I have just tried to add a pattern I really like in other programming languages that I was missing in Go. You can use it however you want, and if you don't like it just use something else. > Have you ever done that sort of thing before? yes I did that's one of the reasons I had to code go-observable
- simoncion 11y ago> I am not reinventing the wheel here... I never said that you were. :) > yes I did that's one of the reasons I had to code go-observable I don't mean to sound mean or anything like this, but you do know that this question was directed directly at fiatjaf, and noone else, right? :) [0] I mean, I guess I appreciate the input, but I asked the question because it seemed obvious to me -because I spent several years working with software that made use of Pub/Sub mechanisms- that go-observable was a Pub/Sub mechanism for Go. So... I was wondering if fiatjaf had ever done any such thing in the past. Obviously, as you are publishing a pub/sub mechanism in a given language it's either because you had need to do it in the past (or you were just doing it for funzies) and are sharing the fruits of your efforts. :) [0] Or did my comment appear to be a direct descendent of your HN post, rather than a descendent of fiatjaf's question? I've heard that particular bug mentioned once or twice in the past.
- gianlucaguarini 11y agoOk sorry I thought the question was referred to me :) There are many pub/sub modules for go but I made this one because I was missing in some case the asynchronous callbacks that I can use with other languages ( node for example ) but in a really simple way without too many ceremony (probably I am too stupid for other solutions) and also with the benefit of using the async go routines that IMHO are an advantage and not cons like someone else pointed out (performance tests are still needed here)
- fiatjaf 11y agoI was under the impression that this was useful only for GUI programming, but yes, that's a use case. I'm happy to know there are other legit use cases.
- simoncion 11y agoOh yeah! Pub/sub is useful anywhere you have an N message producers and M message consumers (where both N and M are >= 0). I mean, the way pretty much everyone does GUIs (with the central message pump that pulls external events off of a queue and changes UI state based on those messages) is an entirely reasonable way to think of all systems that use message passing to communicate -e.g. Elixir or Erlang- between loosely coupled parts of the system.
- whisk3rs 11y agoIt is part of the Observer pattern: https://en.wikipedia.org/wiki/Observer_pattern https://en.wikipedia.org/wiki/Observer_pattern One common use case is in workflow systems. For example, you might "wait" for a bunch of files to exist before kicking off a job. This could be implemented as a bunch of "subjects" notifying when the files exist, and then the "observer" taking action when all of its subjects notify. It is also used in UI frameworks to update visual representation when underlying data changes.
- gianlucaguarini 11y agoLet's say you want to publish a library that for example logs the global keyboard events. If you want to simply notify any keypress in a really simple manner you can just use myLib.On("keypress", func() {}) and no matter where the "keypress" event gets dispatched you will have always a callback listening it.
- AYBABTME 11y agoSeems to only work with a single receiver, in a synchronous manner, in which case I wonder what's the point of using that instead of a simple function call.
- ridiculous_fish 11y agoThis package is using threads but not safely. A call to Trigger kicks off the `listen` function in a background thread, which accesses a map and walks over a list of callbacks. If you then call On() or Off() immediately after Trigger, that map and/or list gets modified while `listen` is walking it. This is a serious problem. It's great that there's tests, but all of the tests follow the same pattern: On and then Trigger. It's the reverse order that's busted.
- JamesMcMinn 11y agoTo add to this slightly, The race detector built into Go is fantastic and very easy to use (simply "go build -race")
- mitchellh 11y agoThe above is completely correct. In addition to this, there is a lot of `reflect` usage. This in and of itself isn't really a problem, but this will really slow down the usage and I imagine there are relatively high performance use cases for the observer pattern. Not trying to discourage you or anything! It is great that you built something and made it available for the world. Just trying to give some hints from someone that has worked with Go a lot (parent has as well!)
- gianlucaguarini 11y agoOk thanks I will try to add some performance tests
- zippoxer 11y agoReflect usage is a slow down, but you know what? Still much faster than most dynamic languages
- elithrar 11y agoAs of Go 1.6 the concurrent map access will also forcibly crash the program: https://tip.golang.org/doc/go1.6#runtime https://tip.golang.org/doc/go1.6#runtime
- 11y ago
- empressplay 11y agoA nitpick, but thing-what-compiles is not a "script".
- iofj 11y agoThis API mostly shows just how badly Go needs generics. Would you really not want any data into those events ? But you can't design an API like that in Go, it just wouldn't work.