예제 #1
0
func (s *SRVLoader) getConfig() (*pb.NodeConfig, error) {
	nconfig := &pb.NodeConfig{}
	var opts []grpc.DialOption
	var creds credentials.TransportAuthenticator
	creds = credentials.NewTLS(&tls.Config{
		InsecureSkipVerify: true,
	})
	opts = append(opts, grpc.WithTransportCredentials(creds))
	conn, err := grpc.Dial(s.SyndicateURL, opts...)
	if err != nil {
		return nconfig, fmt.Errorf("Failed to dial ring server for config: %s", err)
	}
	defer conn.Close()

	client := pb.NewSyndicateClient(conn)

	ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)

	rr := &pb.RegisterRequest{}
	rr.Hostname, _ = os.Hostname()
	addrs, _ := net.InterfaceAddrs()
	for k, _ := range addrs {
		rr.Addrs = append(rr.Addrs, addrs[k].String())
	}
	rr.Hardware, err = GetHardwareProfile()
	if err != nil {
		return nconfig, err
	}
	rr.Tiers = []string{rr.Hostname}

	nconfig, err = client.RegisterNode(ctx, rr)
	return nconfig, err
}
예제 #2
0
func New() (*SyndClient, error) {
	var err error
	var opts []grpc.DialOption
	var creds credentials.TransportAuthenticator
	creds = credentials.NewTLS(&tls.Config{
		InsecureSkipVerify: true,
	})
	opts = append(opts, grpc.WithTransportCredentials(creds))
	s := SyndClient{}
	s.conn, err = grpc.Dial(*syndicateAddr, opts...)
	if err != nil {
		return &SyndClient{}, fmt.Errorf("Failed to dial ring server for config: %v", err)
	}
	s.client = pb.NewSyndicateClient(s.conn)
	return &s, nil
}
예제 #3
0
func (rs *ReplValueStore) ringServerConnector(exitChan chan struct{}) {
	sleeperTicks := 2
	sleeperTicker := time.NewTicker(time.Second)
	sleeper := func() {
		for i := sleeperTicks; i > 0; i-- {
			select {
			case <-exitChan:
				break
			case <-sleeperTicker.C:
			}
		}
		if sleeperTicks < 60 {
			sleeperTicks *= 2
		}
	}
	for {
		select {
		case <-exitChan:
			break
		default:
		}
		ringServer := rs.ringServer
		if ringServer == "" {
			var err error

			ringServer, err = oort.GetRingServer("value")
			if err != nil {
				rs.logError("replValueStore: error resolving ring service: %s", err)
				sleeper()
				continue
			}
		}
		conn, err := grpc.Dial(ringServer, rs.ringServerGRPCOpts...)
		if err != nil {
			rs.logError("replValueStore: error connecting to ring service %q: %s", ringServer, err)
			sleeper()
			continue
		}
		stream, err := synpb.NewSyndicateClient(conn).GetRingStream(context.Background(), &synpb.SubscriberID{Id: rs.ringClientID})
		if err != nil {
			rs.logError("replValueStore: error creating stream with ring service %q: %s", ringServer, err)
			sleeper()
			continue
		}
		connDoneChan := make(chan struct{})
		somethingICanTakeAnAddressOf := int32(0)
		activity := &somethingICanTakeAnAddressOf
		// This goroutine will detect when the exitChan is closed so it can
		// close the conn so that the blocking stream.Recv will get an error
		// and everything will unwind properly.
		// However, if the conn errors out on its own and exitChan isn't
		// closed, we're going to loop back around and try a new conn, but we
		// need to clear out this goroutine, which is what the connDoneChan is
		// for.
		// One last thing is that if nothing happens for fifteen minutes, we
		// can assume the conn has gone stale and close it, causing a loop
		// around to try a new conn.
		// It would be so much easier if Recv could use a timeout Context...
		go func(c *grpc.ClientConn, a *int32, cdc chan struct{}) {
			for {
				select {
				case <-exitChan:
				case <-cdc:
				case <-time.After(15 * time.Minute):
					// I'm comfortable with time.After here since it's just
					// once per fifteen minutes or new conn.
					v := atomic.LoadInt32(a)
					if v != 0 {
						atomic.AddInt32(a, -v)
						continue
					}
				}
				break
			}
			c.Close()
		}(conn, activity, connDoneChan)
		for {
			select {
			case <-exitChan:
				break
			default:
			}
			res, err := stream.Recv()
			if err != nil {
				rs.logDebug("replValueStore: error with stream to ring service %q: %s", ringServer, err)
				break
			}
			atomic.AddInt32(activity, 1)
			if res != nil {
				if r, err := ring.LoadRing(bytes.NewBuffer(res.Ring)); err != nil {
					rs.logDebug("replValueStore: error with ring received from stream to ring service %q: %s", ringServer, err)
				} else {
					// This will cache the ring if ringCachePath is not empty.
					rs.SetRing(r)
					// Resets the exponential sleeper since we had success.
					sleeperTicks = 2
					rs.logDebug("replValueStore: got new ring from stream to ring service %q: %d", ringServer, res.Version)
				}
			}
		}
		close(connDoneChan)
		sleeper()
	}
}