Пример #1
0
// sendOneInvite sends invitations to all the addresses in addrs and returns the one that accepted it.
// All addrs are assumed to be equivalent and thus at most one Invite RPC will succeed.
//
// TODO: This is aiming to replicate what the RPC stack does for all the
// addresses a single name resolved to. Should all these addresses discovered
// somehow be encapsulated in a single object name?
func sendOneInvite(ctx *context.T, addrs []string) string {
	// Give at most 1 second for these connections to be made, if they
	// can't be made then consider the peer bad and ignore it.
	// TODO: Should these RPCs also use the "connection timeout" that might be implemented
	// as per proposal: https://docs.google.com/a/google.com/document/d/1prtxGhSR5TaL0lc_iDRC0Q6H1Drbg2T0x7MWVb_ZCSM/edit?usp=sharing
	ctx, cancel := context.WithTimeout(ctx, maxInvitationWaitTime)
	defer cancel()
	ch := make(chan string)
	for _, addr := range addrs {
		go func(addr string) {
			err := spec.ScreenClient(addr).Invite(ctx, options.ServerAuthorizer{security.AllowEveryone()})
			ctx.Infof("Invitation to %v sent, error: %v", addr, err)
			if err == nil {
				ch <- addr
				return
			}
			ch <- ""
		}(addr)
	}
	for i := range addrs {
		if ret := <-ch; len(ret) > 0 {
			// Drain the rest and return
			go func() {
				i++
				for i < len(addrs) {
					<-ch
				}
			}()
			return ret
		}
	}
	return ""
}
Пример #2
0
func channel2rpc(ctx *context.T, src <-chan *spec.Triangle, dst string, errch chan<- error, myScreen chan<- *spec.Triangle) {
	for t := range src {
		// This is an "interactive" game, if an RPC doesn't succeed in say
		ctxTimeout, cancel := context.WithTimeout(ctx, maxTriangleGiveTime)
		if err := spec.ScreenClient(dst).Give(ctxTimeout, *t, options.ServerAuthorizer{security.AllowEveryone()}); err != nil {
			cancel()
			returnTriangle(t, myScreen)
			ctx.Infof("%q.Give failed: %v, aborting connection with remote screen", dst, err)
			errch <- err
			break
		}
		cancel()
	}
	for t := range src {
		returnTriangle(t, myScreen)
	}
	ctx.VI(1).Infof("Exiting goroutine with connection to %q", dst)
}