github.com/klaytn/klaytn@v1.12.1/event/example_scope_test.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2016 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from event/example_scope_test.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package event_test
    22  
    23  import (
    24  	"fmt"
    25  	"sync"
    26  
    27  	"github.com/klaytn/klaytn/event"
    28  )
    29  
    30  // This example demonstrates how SubscriptionScope can be used to control the lifetime of
    31  // subscriptions.
    32  //
    33  // Our example program consists of two servers, each of which performs a calculation when
    34  // requested. The servers also allow subscribing to results of all computations.
    35  type divServer struct{ results event.Feed }
    36  type mulServer struct{ results event.Feed }
    37  
    38  func (s *divServer) do(a, b int) int {
    39  	r := a / b
    40  	s.results.Send(r)
    41  	return r
    42  }
    43  
    44  func (s *mulServer) do(a, b int) int {
    45  	r := a * b
    46  	s.results.Send(r)
    47  	return r
    48  }
    49  
    50  // The servers are contained in an App. The app controls the servers and exposes them
    51  // through its API.
    52  type App struct {
    53  	divServer
    54  	mulServer
    55  	scope event.SubscriptionScope
    56  }
    57  
    58  func (s *App) Calc(op byte, a, b int) int {
    59  	switch op {
    60  	case '/':
    61  		return s.divServer.do(a, b)
    62  	case '*':
    63  		return s.mulServer.do(a, b)
    64  	default:
    65  		panic("invalid op")
    66  	}
    67  }
    68  
    69  // The app's SubscribeResults method starts sending calculation results to the given
    70  // channel. Subscriptions created through this method are tied to the lifetime of the App
    71  // because they are registered in the scope.
    72  func (s *App) SubscribeResults(op byte, ch chan<- int) event.Subscription {
    73  	switch op {
    74  	case '/':
    75  		return s.scope.Track(s.divServer.results.Subscribe(ch))
    76  	case '*':
    77  		return s.scope.Track(s.mulServer.results.Subscribe(ch))
    78  	default:
    79  		panic("invalid op")
    80  	}
    81  }
    82  
    83  // Stop stops the App, closing all subscriptions created through SubscribeResults.
    84  func (s *App) Stop() {
    85  	s.scope.Close()
    86  }
    87  
    88  func ExampleSubscriptionScope() {
    89  	// Create the app.
    90  	var (
    91  		app  App
    92  		wg   sync.WaitGroup
    93  		divs = make(chan int)
    94  		muls = make(chan int)
    95  	)
    96  
    97  	// Run a subscriber in the background.
    98  	divsub := app.SubscribeResults('/', divs)
    99  	mulsub := app.SubscribeResults('*', muls)
   100  	wg.Add(1)
   101  	go func() {
   102  		defer wg.Done()
   103  		defer fmt.Println("subscriber exited")
   104  		defer divsub.Unsubscribe()
   105  		defer mulsub.Unsubscribe()
   106  		for {
   107  			select {
   108  			case result := <-divs:
   109  				fmt.Println("division happened:", result)
   110  			case result := <-muls:
   111  				fmt.Println("multiplication happened:", result)
   112  			case <-divsub.Err():
   113  				return
   114  			case <-mulsub.Err():
   115  				return
   116  			}
   117  		}
   118  	}()
   119  
   120  	// Interact with the app.
   121  	app.Calc('/', 22, 11)
   122  	app.Calc('*', 3, 4)
   123  
   124  	// Stop the app. This shuts down the subscriptions, causing the subscriber to exit.
   125  	app.Stop()
   126  	wg.Wait()
   127  
   128  	// Output:
   129  	// division happened: 2
   130  	// multiplication happened: 12
   131  	// subscriber exited
   132  }