Esempio n. 1
0
// InitialTopicRequest topic from a kvnode, for an initial set
// of instances. Initial topic will always start vbucket
// streams from seqno number ZERO using the latest-vbuuid.
//
// Idempotent API.
// - return TopicResponse that contain current set of
//   active-timestamps and rollback-timestamps reflected from
//   projector, even in case of error.
//
// Possible errors returned,
// - http errors for transport related failures.
// - ErrorInvalidKVaddrs if projector unable to find colocated host.
// - ErrorInconsistentFeed for malformed feed request.
// - ErrorInvalidVbucketBranch for malformed vbuuid.
// - ErrorFeeder if upstream connection has failures.
//      upstream connection is closed for the bucket, the bucket
//      needs to be newly added.
// - ErrorNotMyVbucket due to rebalances and failures.
// - ErrorStreamRequest if StreamRequest failed for some reason
// - ErrorResponseTimeout if request is not completed within timeout.
//
// * except of ErrorFeeder, projector feed will book-keep oustanding
//   request for vbuckets and active vbuckets. Caller should observe
//   mutation feed for StreamBegin and retry until all vbuckets are
//   started.
// * active-timestamps returned in TopicResponse contain entries
//   only for successfully started {buckets,vbuckets}.
// * rollback-timestamps contain vbucket entries that need rollback.
func (client *Client) InitialTopicRequest(
	topic, pooln, endpointType string,
	instances []*protobuf.Instance) (*protobuf.TopicResponse, error) {

	buckets := make(map[string]bool, 0)
	for _, instance := range instances {
		buckets[instance.GetBucket()] = true
	}

	req := protobuf.NewMutationTopicRequest(topic, endpointType, instances)
	for bucketn := range buckets {
		ts, err := client.InitialRestartTimestamp(pooln, bucketn)
		if err != nil {
			return nil, err
		}
		req.Append(ts)
	}
	res := &protobuf.TopicResponse{}
	err := client.withRetry(
		func() error {
			err := client.ap.Request(req, res)
			if err != nil {
				return err
			} else if protoerr := res.GetErr(); protoerr != nil {
				return fmt.Errorf(protoerr.GetError())
			}
			return err // nil
		})
	if err != nil {
		return nil, err
	}
	return res, nil
}
Esempio n. 2
0
// MutationTopicRequest topic from a kvnode, with initial set
// of instances.
//
// Idempotent API.
// - return TopicResponse that contain current set of
//   active-timestamps and rollback-timestamps reflected from
//   projector, even in case of error.
// - Since the API is idempotent, it can be called repeatedly until
//   all requested vbuckets are started and returns SUCCESS to caller.
//
// Possible errors returned,
// - http errors for transport related failures.
// - ErrorInvalidKVaddrs if projector unable to find colocated host.
// - ErrorInconsistentFeed for malformed feed request.
// - ErrorInvalidVbucketBranch for malformed vbuuid.
// - ErrorFeeder if upstream connection has failures.
//      upstream connection is closed for the bucket, the bucket
//      needs to be newly added.
// - ErrorNotMyVbucket due to rebalances and failures.
// - ErrorStreamRequest if StreamRequest failed for some reason
// - ErrorResponseTimeout if request is not completed within timeout.
//
// * except of ErrorFeeder, projector feed will book-keep oustanding
//   request for vbuckets and active vbuckets. Caller should observe
//   mutation feed for StreamBegin and retry until all vbuckets are
//   started.
// * active-timestamps returned in TopicResponse response contain
//   entries only for successfully started {bucket,vbuckets}.
// * rollback-timestamp contains vbucket entries that need rollback.
func (client *Client) MutationTopicRequest(
	topic, endpointType string,
	reqTimestamps []*protobuf.TsVbuuid,
	instances []*protobuf.Instance) (*protobuf.TopicResponse, error) {

	req := protobuf.NewMutationTopicRequest(topic, endpointType, instances)
	req.ReqTimestamps = reqTimestamps
	res := &protobuf.TopicResponse{}
	err := client.withRetry(
		func() error {
			err := client.ap.Request(req, res)
			if err != nil {
				return err
			} else if protoerr := res.GetErr(); protoerr != nil {
				return fmt.Errorf(protoerr.GetError())
			}
			return err // nil
		})
	if err != nil {
		return nil, err
	}
	return res, nil
}