// 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 }
// 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 }