aboutsummaryrefslogtreecommitdiffstats
path: root/event/example_scope_test.go
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2017-02-03 19:56:00 +0800
committerGitHub <noreply@github.com>2017-02-03 19:56:00 +0800
commit7734ead52030a6c128613331ea4a24afd9d4173a (patch)
tree7bed2d0085c7a9cac97691ccf561976119f45c78 /event/example_scope_test.go
parent8b57c494908637a5c0e74f8f7a13b3218e026757 (diff)
parent1bed9b3fea9939581b03cae9d6b4984ced456748 (diff)
downloadgo-tangerine-7734ead52030a6c128613331ea4a24afd9d4173a.tar.gz
go-tangerine-7734ead52030a6c128613331ea4a24afd9d4173a.tar.zst
go-tangerine-7734ead52030a6c128613331ea4a24afd9d4173a.zip
Merge pull request #3605 from fjl/event-feed
event: add new Subscription type and related utilities
Diffstat (limited to 'event/example_scope_test.go')
-rw-r--r--event/example_scope_test.go128
1 files changed, 128 insertions, 0 deletions
diff --git a/event/example_scope_test.go b/event/example_scope_test.go
new file mode 100644
index 000000000..c517a8324
--- /dev/null
+++ b/event/example_scope_test.go
@@ -0,0 +1,128 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package event_test
+
+import (
+ "fmt"
+ "sync"
+
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// This example demonstrates how SubscriptionScope can be used to control the lifetime of
+// subscriptions.
+//
+// Our example program consists of two servers, each of which performs a calculation when
+// requested. The servers also allow subscribing to results of all computations.
+type divServer struct{ results event.Feed }
+type mulServer struct{ results event.Feed }
+
+func (s *divServer) do(a, b int) int {
+ r := a / b
+ s.results.Send(r)
+ return r
+}
+
+func (s *mulServer) do(a, b int) int {
+ r := a * b
+ s.results.Send(r)
+ return r
+}
+
+// The servers are contained in an App. The app controls the servers and exposes them
+// through its API.
+type App struct {
+ divServer
+ mulServer
+ scope event.SubscriptionScope
+}
+
+func (s *App) Calc(op byte, a, b int) int {
+ switch op {
+ case '/':
+ return s.divServer.do(a, b)
+ case '*':
+ return s.mulServer.do(a, b)
+ default:
+ panic("invalid op")
+ }
+}
+
+// The app's SubscribeResults method starts sending calculation results to the given
+// channel. Subscriptions created through this method are tied to the lifetime of the App
+// because they are registered in the scope.
+func (s *App) SubscribeResults(op byte, ch chan<- int) event.Subscription {
+ switch op {
+ case '/':
+ return s.scope.Track(s.divServer.results.Subscribe(ch))
+ case '*':
+ return s.scope.Track(s.mulServer.results.Subscribe(ch))
+ default:
+ panic("invalid op")
+ }
+}
+
+// Stop stops the App, closing all subscriptions created through SubscribeResults.
+func (s *App) Stop() {
+ s.scope.Close()
+}
+
+func ExampleSubscriptionScope() {
+ // Create the app.
+ var (
+ app App
+ wg sync.WaitGroup
+ divs = make(chan int)
+ muls = make(chan int)
+ )
+
+ // Run a subscriber in the background.
+ divsub := app.SubscribeResults('/', divs)
+ mulsub := app.SubscribeResults('*', muls)
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ defer fmt.Println("subscriber exited")
+ defer divsub.Unsubscribe()
+ defer mulsub.Unsubscribe()
+ for {
+ select {
+ case result := <-divs:
+ fmt.Println("division happened:", result)
+ case result := <-muls:
+ fmt.Println("multiplication happened:", result)
+ case <-divsub.Err():
+ return
+ case <-mulsub.Err():
+ return
+ }
+ }
+ }()
+
+ // Interact with the app.
+ app.Calc('/', 22, 11)
+ app.Calc('*', 3, 4)
+
+ // Stop the app. This shuts down the subscriptions, causing the subscriber to exit.
+ app.Stop()
+ wg.Wait()
+
+ // Output:
+ // division happened: 2
+ // multiplication happened: 12
+ // subscriber exited
+}