github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/event/example_scope_test.go (about)

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