pax_global_header00006660000000000000000000000064145423752600014522gustar00rootroot0000000000000052 comment=e7e39e7c655a02b31e90e7672584fcd6f23c2e07 golang-github-cenkalti-hub-1.0.2/000077500000000000000000000000001454237526000166155ustar00rootroot00000000000000golang-github-cenkalti-hub-1.0.2/.gitignore000066400000000000000000000003741454237526000206110ustar00rootroot00000000000000# Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a *.so # Folders _obj _test # Architecture specific extensions/prefixes *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe golang-github-cenkalti-hub-1.0.2/.travis.yml000066400000000000000000000000641454237526000207260ustar00rootroot00000000000000language: go go: 1.13 arch: - amd64 - ppc64le golang-github-cenkalti-hub-1.0.2/LICENSE000066400000000000000000000020651454237526000176250ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2014 Cenk Altı Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. golang-github-cenkalti-hub-1.0.2/README.md000066400000000000000000000003231454237526000200720ustar00rootroot00000000000000hub === [![GoDoc](https://godoc.org/github.com/cenkalti/hub?status.png)](https://godoc.org/github.com/cenkalti/hub) [![Build Status](https://travis-ci.org/cenkalti/hub.png)](https://travis-ci.org/cenkalti/hub) golang-github-cenkalti-hub-1.0.2/example_test.go000066400000000000000000000007471454237526000216460ustar00rootroot00000000000000package hub_test import ( "fmt" "github.com/cenkalti/hub" ) // Different event kinds const ( happenedA hub.Kind = iota happenedB happenedC ) // Our custom event type type EventA struct { arg1, arg2 int } // Implement hub.Event interface func (e EventA) Kind() hub.Kind { return happenedA } func Example() { hub.Subscribe(happenedA, func(e hub.Event) { a := e.(EventA) // Cast to concrete type fmt.Println(a.arg1 + a.arg2) }) hub.Publish(EventA{2, 3}) // Output: 5 } golang-github-cenkalti-hub-1.0.2/go.mod000066400000000000000000000000501454237526000177160ustar00rootroot00000000000000module github.com/cenkalti/hub go 1.20 golang-github-cenkalti-hub-1.0.2/go.sum000066400000000000000000000000001454237526000177360ustar00rootroot00000000000000golang-github-cenkalti-hub-1.0.2/hub.go000066400000000000000000000034241454237526000177250ustar00rootroot00000000000000// Package hub provides a simple event dispatcher for publish/subscribe pattern. package hub import "sync" type Kind int // Event is an interface for published events. type Event interface { Kind() Kind } // Hub is an event dispatcher, publishes events to the subscribers // which are subscribed for a specific event type. // Optimized for publish calls. // The handlers may be called in order different than they are registered. type Hub struct { subscribers map[Kind][]handler m sync.RWMutex seq uint64 } type handler struct { f func(Event) id uint64 } // Subscribe registers f for the event of a specific kind. func (h *Hub) Subscribe(kind Kind, f func(Event)) (cancel func()) { var cancelled bool h.m.Lock() h.seq++ id := h.seq if h.subscribers == nil { h.subscribers = make(map[Kind][]handler) } h.subscribers[kind] = append(h.subscribers[kind], handler{id: id, f: f}) h.m.Unlock() return func() { h.m.Lock() if cancelled { h.m.Unlock() return } cancelled = true a := h.subscribers[kind] for i, f := range a { if f.id == id { a[i], h.subscribers[kind] = a[len(a)-1], a[:len(a)-1] break } } if len(a) == 0 { delete(h.subscribers, kind) } h.m.Unlock() } } // Publish an event to the subscribers. func (h *Hub) Publish(e Event) { h.m.RLock() if handlers, ok := h.subscribers[e.Kind()]; ok { for _, h := range handlers { h.f(e) } } h.m.RUnlock() } // DefaultHub is the default Hub used by Publish and Subscribe. var DefaultHub Hub // Subscribe registers f for the event of a specific kind in the DefaultHub. func Subscribe(kind Kind, f func(Event)) (cancel func()) { return DefaultHub.Subscribe(kind, f) } // Publish an event to the subscribers in DefaultHub. func Publish(e Event) { DefaultHub.Publish(e) } golang-github-cenkalti-hub-1.0.2/hub_test.go000066400000000000000000000013221454237526000207570ustar00rootroot00000000000000package hub import "testing" const testKind Kind = 1 const testValue = "foo" type testEvent string func (e testEvent) Kind() Kind { return testKind } func TestPubSub(t *testing.T) { var h Hub var s string h.Subscribe(testKind, func(e Event) { s = string(e.(testEvent)) }) h.Publish(testEvent(testValue)) if s != testValue { t.Errorf("invalid value: %s", s) } } func TestCancel(t *testing.T) { var h Hub var called int var f = func(e Event) { called += 1 } _ = h.Subscribe(testKind, f) cancel := h.Subscribe(testKind, f) h.Publish(testEvent(testValue)) // 2 calls to f cancel() h.Publish(testEvent(testValue)) // 1 call to f if called != 3 { t.Errorf("unexpected call count: %d", called) } }