Perform publish and subscribe operations by using the DataHub Go SDK.
Publish data
To publish data records to a topic, specify a shard ID for each record. Call the ListShard API first to retrieve the available shards under the topic. When using the PutRecords API, check the return result for any failed records.
Starting from DataHub server version 2.12, the PutRecordsByShard API is supported. For earlier versions, please use PutRecords.
Parameters
|
Parameter |
Type |
Description |
|
projectName |
string |
The project name. |
|
topicName |
string |
The topic name. |
|
shardId |
string |
The shard ID. |
|
records |
/ |
A list of records to write. |
Response example
type PutRecordsResult struct {
FailedRecordCount int `json:"FailedRecordCount"`
FailedRecords []FailedRecord `json:"FailedRecords"`
}
Error types
|
Class name |
Error code |
Description |
|
ResourceNotFoundError |
|
The requested resource does not exist. (Note: This may occur if another request is sent immediately after a Split/Merge operation.) |
|
AuthorizationFailedError |
|
Failed to parse authorization signature. Check whether your AccessKey is correct. |
|
InvalidParameterError |
|
Invalid parameters. |
|
DatahubClientError |
- |
Base class for all other exceptions. |
Code example
// put tuple data
func putTupleData() {
topic, err := dh.GetTopic(projectName, topicName)
if err != nil {
fmt.Println("get topic failed")
fmt.Println(err)
return
}
fmt.Println("get topic successful")
records := make([]datahub.IRecord, 3)
record1 := datahub.NewTupleRecord(topic.RecordSchema, 0)
record1.ShardId = "0"
record1.SetValueByName("field1", "TEST1")
record1.SetValueByName("field2", 1)
//you can add some attributes when put record
record1.SetAttribute("attribute", "test attribute")
records[0] = record1
record2 := datahub.NewTupleRecord(topic.RecordSchema, 0)
record2.ShardId = "1"
record2.SetValueByName("field1", datahub.String("TEST2"))
record2.SetValueByName("field2", datahub.Bigint(2))
records[1] = record2
record3 := datahub.NewTupleRecord(topic.RecordSchema, 0)
record3.ShardId = "2"
record3.SetValueByName("field1", datahub.String("TEST3"))
record3.SetValueByName("field2", datahub.Bigint(3))
records[2] = record3
maxReTry := 3
retryNum := 0
for retryNum < maxReTry {
result, err := dh.PutRecords(projectName, topicName, records)
if err != nil {
if _, ok := err.(*datahub.LimitExceededError); ok {
fmt.Println("maybe qps exceed limit,retry")
retryNum++
time.Sleep(5 * time.Second)
continue
} else {
fmt.Println("put record failed")
fmt.Println(err)
return
}
}
fmt.Printf("put successful num is %d, put records failed num is %d\n", len(records)-result.FailedRecordCount, result.FailedRecordCount)
for _, v := range result.FailedRecords {
fmt.Println(v)
}
break
}
if retryNum >= maxReTry {
fmt.Printf("put records failed ")
}
}
// put blob data
func putBlobData() {
records := make([]datahub.IRecord, 3)
record1 := datahub.NewBlobRecord([]byte("blob test1"), 0)
record1.ShardId = "0"
records[0] = record1
record2 := datahub.NewBlobRecord([]byte("blob test2"), 0)
record2.ShardId = "1"
record2.SetAttribute("attribute", "test attribute")
records[1] = record2
record3 := datahub.NewBlobRecord([]byte("blob test3"), 0)
record3.ShardId = "2"
records[2] = record3
maxReTry := 3
retryNum := 0
for retryNum < maxReTry {
result, err := dh.PutRecords(projectName, blobTopicName, records)
if err != nil {
if _, ok := err.(*datahub.LimitExceededError); ok {
fmt.Println("maybe qps exceed limit,retry")
retryNum++
time.Sleep(5 * time.Second)
continue
} else {
fmt.Println("put record failed")
fmt.Println(err)
return
}
}
fmt.Printf("put successful num is %d, put records failed num is %d\n", len(records)-result.FailedRecordCount, result.FailedRecordCount)
for _, v := range result.FailedRecords {
fmt.Println(v)
}
break
}
if retryNum >= maxReTry {
fmt.Printf("put records failed ")
}
}
// put data by shard
func putDataByShard() {
shardId := "0"
records := make([]datahub.IRecord, 3)
record1 := datahub.NewBlobRecord([]byte("blob test1"), 0)
records[0] = record1
record2 := datahub.NewBlobRecord([]byte("blob test2"), 0)
record2.SetAttribute("attribute", "test attribute")
records[1] = record2
record3 := datahub.NewBlobRecord([]byte("blob test3"), 0)
records[2] = record3
maxReTry := 3
retryNum := 0
for retryNum < maxReTry {
if err := dh.PutRecordsByShard(projectName, blobTopicName, shardId, records); err != nil {
if _, ok := err.(*datahub.LimitExceededError); ok {
fmt.Println("maybe qps exceed limit,retry")
retryNum++
time.Sleep(5 * time.Second)
continue
} else {
fmt.Println("put record failed")
fmt.Println(err)
return
}
}
}
if retryNum >= maxReTry {
fmt.Printf("put records failed ")
}else {
fmt.Println("put record successful")
}
}
You can also attach extra attributes to records during publishing, such as data collection metadata:
record1 := datahub.NewTupleRecord(topic.RecordSchema, 0)
record1.SetAttribute("attribute","test attribute")
record2 := datahub.NewBlobRecord([]byte("blob test2"), 0)
record2.SetAttribute("attribute","test attribute")
Subscribe to data
To subscribe to data from a topic, specify the shard and the cursor position from which to start reading. Obtain the cursor by calling the GetCursor API.
Parameters
|
Parameter |
Type |
Description |
|
projectName |
string |
The project name. |
|
topicName |
string |
The topic name. |
|
shardId |
string |
The shard ID. |
|
ctype |
CursorType |
The method used to obtain the cursor. |
|
param |
int64 |
The parameter required by the cursor type. This must be set when using |
The ctype parameter supports the following values:
-
OLDEST: The cursor points to the earliest valid record currently available.
-
LATEST: The cursor points to the latest record.
-
SEQUENCE: The cursor points to the record with the specified sequence number.
-
SYSTEM_TIME: The cursor points to the first record received after the specified timestamp.
Response example
type GetCursorResult struct {
Cursor string `json:"Cursor"`
RecordTime int64 `json:"RecordTime"`
Sequence int64 `json:"Sequence"`
}
Error descriptions
|
Class name |
Error code |
Description |
|
ResourceNotFoundError |
|
The requested resource does not exist. (Note: This may occur if a request is sent immediately after a Split/Merge operation.) |
|
SeekOutOfRangeError |
|
When calling |
|
AuthorizationFailedError |
|
Failed to parse the authorization signature. Check whether your AccessKey is correct. |
|
InvalidParameterError |
|
Invalid parameter. |
|
ShardSealedError |
- |
- |
|
DatahubClientError |
- |
Base class for all other exceptions. |
Code example
To read data from a specific shard, specify the starting cursor and the maximum number of records to read. If fewer records are available than the specified limit, only the available records are returned.
func cursor(dh datahub.DataHub, projectName, topicName string) {
shardId := "0"
gr, err := dh.GetCursor(projectName, topicName, shardId, datahub.OLDEST)
if err != nil {
fmt.Println("get cursor failed")
fmt.Println(err)
}else{
fmt.Println(gr)
}
gr, err = dh.GetCursor(projectName, topicName, shardId, datahub.LATEST)
fmt.Println(err)
fmt.Println(gr)
var seq int64 = 10
gr, err = dh.GetCursor(projectName, topicName, shardId, datahub.SEQUENCE, seq)
if err != nil {
fmt.Println("get cursor failed")
fmt.Println(err)
}else{
fmt.Println(gr)
}
}
Tuple topic data
Parameters
|
Parameter |
Type |
Description |
|
projectName |
String |
The project name. |
|
topicName |
string |
The topic name. |
|
shardId |
string |
The shard ID. |
|
cursor |
string |
The start cursor used to read data. |
|
limit |
int |
The maximum number of records to read. |
|
recordSchema |
RecordSchema |
The record schema of the topic. |
Response example
type GetRecordsResult struct {
NextCursor string `json:"NextCursor"`
RecordCount int `json:"RecordCount"`
StartSequence int64 `json:"StartSeq"`
Records []IRecord `json:"Records"`
RecordSchema *RecordSchema `json:"-"`
}
Error descriptions
|
Class name |
Error code |
Description |
|
ResourceNotFoundError |
|
The requested resource does not exist. (Note: This may occur if another request is sent immediately after a Split/Merge operation.) |
|
AuthorizationFailedError |
|
Failed to parse authorization signature. Check whether your AccessKey is correct. |
|
InvalidParameterError |
|
Invalid parameters. |
|
DatahubClientError |
- |
Base class for all other exceptions. |
Code example
func getTupleData() {
shardId := "1"
topic, err := dh.GetTopic(projectName, topicName)
if err != nil {
fmt.Println("get topic failed")
return
}
fmt.Println("get topic successful")
cursor, err := dh.GetCursor(projectName, topicName, shardId, datahub.OLDEST)
if err != nil {
fmt.Println("get cursor failed")
fmt.Println(err)
return
}
fmt.Println("get cursor successful")
limitNum := 100
maxReTry := 3
retryNum := 0
for retryNum < maxReTry {
gr, err := dh.GetTupleRecords(projectName, topicName, shardId, cursor.Cursor, limitNum, topic.RecordSchema)
if err != nil {
if _, ok := err.(*datahub.LimitExceededError); ok {
fmt.Println("maybe qps exceed limit,retry")
retryNum++
time.Sleep(5 * time.Second)
continue
} else {
fmt.Println("get record failed")
fmt.Println(err)
return
}
}
fmt.Println("get record successful")
for _, record := range gr.Records {
data, ok := record.(*datahub.TupleRecord)
if !ok {
fmt.Printf("record type is not TupleRecord, is %v\n", reflect.TypeOf(record))
} else {
fmt.Println(data.Values)
}
}
break
}
if retryNum >= maxReTry {
fmt.Printf("get records failed ")
}
}
Blob topic data
Parameters
|
Parameter |
Type |
Description |
|
projectName |
String |
The project name. |
|
topicName |
string |
The topic name. |
|
shardId |
string |
The shard ID. |
|
cursor |
string |
The start cursor used to read data. |
|
limit |
int |
The maximum number of records to read. |
Response example
type GetRecordsResult struct {
NextCursor string `json:"NextCursor"`
RecordCount int `json:"RecordCount"`
StartSequence int64 `json:"StartSeq"`
Records []IRecord `json:"Records"`
RecordSchema *RecordSchema `json:"-"`
}
Error descriptions
|
Class name |
Error code |
Description |
|
ResourceNotFoundError |
|
The requested resource does not exist. (Note: This may occur if another request is sent immediately after a Split/Merge operation.) |
|
AuthorizationFailedError |
|
Failed to parse authorization signature. Check whether your AccessKey is correct. |
|
InvalidParameterError |
|
Invalid parameters. |
|
DatahubClientError |
- |
Base class for all other exceptions. |
Code example
func getBlobData() {
shardId := "1"
cursor, err := dh.GetCursor(projectName, blobTopicName, shardId, datahub.OLDEST)
if err != nil {
fmt.Println("get cursor failed")
fmt.Println(err)
return
}
fmt.Println("get cursor successful")
limitNum := 100
maxReTry := 3
retryNum := 0
for retryNum < maxReTry {
gr, err := dh.GetBlobRecords(projectName, blobTopicName, shardId, cursor.Cursor, limitNum)
if err != nil {
if _, ok := err.(*datahub.LimitExceededError); ok {
fmt.Println("maybe qps exceed limit,retry")
retryNum++
time.Sleep(5 * time.Second)
continue
} else {
fmt.Println("get record failed")
fmt.Println(err)
return
}
}
fmt.Println("get record successful")
for _, record := range gr.Records {
data, ok := record.(*datahub.BlobRecord)
if !ok {
fmt.Printf("record type is not TupleRecord, is %v\n", reflect.TypeOf(record))
} else {
fmt.Println(data.StoreData)
}
}
break
}
if retryNum >= maxReTry {
fmt.Printf("get records failed ")
}
}