github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/lease/block.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package lease
     5  
     6  import "github.com/juju/juju/core/lease"
     7  
     8  // block is used to deliver lease-expiry-notification requests to a manager's
     9  // loop goroutine on behalf of BlockUntilLeadershipReleased.
    10  type block struct {
    11  	leaseKey lease.Key
    12  	unblock  chan struct{}
    13  	stop     <-chan struct{}
    14  	cancel   <-chan struct{}
    15  }
    16  
    17  // invoke sends the block request on the supplied channel, and waits for the
    18  // unblock channel to be closed.
    19  func (b block) invoke(ch chan<- block) error {
    20  	for {
    21  		select {
    22  		case <-b.stop:
    23  			return errStopped
    24  		case <-b.cancel:
    25  			return lease.ErrWaitCancelled
    26  		case ch <- b:
    27  			ch = nil
    28  		case <-b.unblock:
    29  			return nil
    30  		}
    31  	}
    32  }
    33  
    34  // blocks is used to keep track of expiry-notification channels for
    35  // each lease key.
    36  type blocks map[lease.Key][]chan struct{}
    37  
    38  // add records the block's unblock channel under the block's lease key.
    39  func (b blocks) add(block block) {
    40  	b[block.leaseKey] = append(b[block.leaseKey], block.unblock)
    41  }
    42  
    43  // unblock closes all channels added under the supplied key and removes
    44  // them from blocks.
    45  func (b blocks) unblock(lease lease.Key) {
    46  	unblocks := b[lease]
    47  	delete(b, lease)
    48  	for _, unblock := range unblocks {
    49  		close(unblock)
    50  	}
    51  }