Use golint to update Golang styles

* Update comments and return statements
* Adjust usage of Kinesis library (upgraded local source)
This commit is contained in:
Harlow Ward 2014-12-10 15:38:19 -08:00
parent 02a7c648a3
commit 8e8ee5af73
11 changed files with 47 additions and 41 deletions

View file

@ -1,9 +1,9 @@
package connector package connector
// A basic implementation of the Filter interface that returns true for all records. // AllPassFilter an implementation of the Filter interface that returns true for all records.
type AllPassFilter struct{} type AllPassFilter struct{}
// Returns true for all records. // KeepRecord returns true for all records.
func (b *AllPassFilter) KeepRecord(r interface{}) bool { func (b *AllPassFilter) KeepRecord(r interface{}) bool {
return true return true
} }

View file

@ -1,6 +1,6 @@
package connector package connector
// Used by Pipeline.ProcessShard when they want to checkpoint their progress. // Checkpoint is used by Pipeline.ProcessShard when they want to checkpoint their progress.
// The Kinesis Connector Library will pass an object implementing this interface to ProcessShard, // The Kinesis Connector Library will pass an object implementing this interface to ProcessShard,
// so they can checkpoint their progress. // so they can checkpoint their progress.
type Checkpoint interface { type Checkpoint interface {

View file

@ -1,10 +1,7 @@
package connector package connector
// The Filter is associated with an Buffer. The Buffer may use the result of calling the // Filter is an interface used for determinint whether to buffer records.
// KeepRecord() method to decide whether to store a record or discard it. // Returns false if you don't want to hold on to the record.
// A method enabling the buffer to filter records. Return false if you don't want to hold on to
// the record.
type Filter interface { type Filter interface {
KeepRecord(r interface{}) bool KeepRecord(r interface{}) bool
} }

View file

@ -7,7 +7,8 @@ import (
"github.com/sendgridlabs/go-kinesis" "github.com/sendgridlabs/go-kinesis"
) )
// This struct is used by the main application to configure instances of the user's implemented pipline. // Pipeline is used as a record processor to configure a pipline.
//
// The user should implement this such that each method returns a configured implementation of each // The user should implement this such that each method returns a configured implementation of each
// interface. It has a data type (Model) as Records come in as a byte[] and are transformed to a Model. // interface. It has a data type (Model) as Records come in as a byte[] and are transformed to a Model.
// Then they are buffered in Model form and when the buffer is full, Models's are passed to the emitter. // Then they are buffered in Model form and when the buffer is full, Models's are passed to the emitter.
@ -20,6 +21,8 @@ type Pipeline struct {
Transformer Transformer Transformer Transformer
} }
// ProcessShard kicks off the process of a Kinesis Shard.
// It is a long running process that will continue to read from the shard.
func (p Pipeline) ProcessShard(ksis *kinesis.Kinesis, shardID string) { func (p Pipeline) ProcessShard(ksis *kinesis.Kinesis, shardID string) {
args := kinesis.NewArgs() args := kinesis.NewArgs()
args.Add("ShardId", shardID) args.Add("ShardId", shardID)
@ -54,7 +57,7 @@ func (p Pipeline) ProcessShard(ksis *kinesis.Kinesis, shardID string) {
if len(recordSet.Records) > 0 { if len(recordSet.Records) > 0 {
for _, v := range recordSet.Records { for _, v := range recordSet.Records {
data, err := v.GetData() data := v.GetData()
if err != nil { if err != nil {
fmt.Printf("GetData ERROR: %v\n", err) fmt.Printf("GetData ERROR: %v\n", err)

View file

@ -1,8 +1,7 @@
package connector package connector
// This struct is a basic implementation of the Buffer interface. It is a wrapper on a buffer of // RecordBuffer is a basic implementation of the Buffer interface.
// records that are periodically flushed. It is configured with an implementation of Filter that // It buffer's records and answers questions on when it should be periodically flushed.
// decides whether a record will be added to the buffer to be emitted.
type RecordBuffer struct { type RecordBuffer struct {
NumRecordsToBuffer int NumRecordsToBuffer int
@ -12,7 +11,7 @@ type RecordBuffer struct {
sequencesInBuffer []string sequencesInBuffer []string
} }
// Adds a message to the buffer. // ProcessRecord adds a message to the buffer.
func (b *RecordBuffer) ProcessRecord(record interface{}, sequenceNumber string) { func (b *RecordBuffer) ProcessRecord(record interface{}, sequenceNumber string) {
if len(b.sequencesInBuffer) == 0 { if len(b.sequencesInBuffer) == 0 {
b.firstSequenceNumber = sequenceNumber b.firstSequenceNumber = sequenceNumber
@ -26,17 +25,17 @@ func (b *RecordBuffer) ProcessRecord(record interface{}, sequenceNumber string)
} }
} }
// Returns the records in the buffer. // Records returns the records in the buffer.
func (b *RecordBuffer) Records() []interface{} { func (b *RecordBuffer) Records() []interface{} {
return b.recordsInBuffer return b.recordsInBuffer
} }
// Returns the number of messages in the buffer. // NumRecordsInBuffer returns the number of messages in the buffer.
func (b RecordBuffer) NumRecordsInBuffer() int { func (b RecordBuffer) NumRecordsInBuffer() int {
return len(b.sequencesInBuffer) return len(b.sequencesInBuffer)
} }
// Flushes the content in the buffer and resets the sequence counter. // Flush empties the buffer and resets the sequence counter.
func (b *RecordBuffer) Flush() { func (b *RecordBuffer) Flush() {
b.recordsInBuffer = b.recordsInBuffer[:0] b.recordsInBuffer = b.recordsInBuffer[:0]
b.sequencesInBuffer = b.sequencesInBuffer[:0] b.sequencesInBuffer = b.sequencesInBuffer[:0]
@ -52,17 +51,17 @@ func (b *RecordBuffer) sequenceExists(sequenceNumber string) bool {
return false return false
} }
// Determines if the buffer has reached its target size. // ShouldFlush determines if the buffer has reached its target size.
func (b *RecordBuffer) ShouldFlush() bool { func (b *RecordBuffer) ShouldFlush() bool {
return len(b.sequencesInBuffer) >= b.NumRecordsToBuffer return len(b.sequencesInBuffer) >= b.NumRecordsToBuffer
} }
// Returns the sequence number of the first message in the buffer. // FirstSequenceNumber returns the sequence number of the first message in the buffer.
func (b *RecordBuffer) FirstSequenceNumber() string { func (b *RecordBuffer) FirstSequenceNumber() string {
return b.firstSequenceNumber return b.firstSequenceNumber
} }
// Returns the sequence number of the last message in the buffer. // LastSequenceNumber returns the sequence number of the last message in the buffer.
func (b *RecordBuffer) LastSequenceNumber() string { func (b *RecordBuffer) LastSequenceNumber() string {
return b.lastSequenceNumber return b.lastSequenceNumber
} }

View file

@ -8,7 +8,7 @@ func (r TestRecord) ToDelimitedString() string {
return "test" return "test"
} }
func (r TestRecord) ToJson() []byte { func (r TestRecord) ToJSON() []byte {
return []byte("test") return []byte("test")
} }

View file

@ -6,8 +6,8 @@ import (
"github.com/hoisie/redis" "github.com/hoisie/redis"
) )
// A Redis implementation of the Checkpont interface. This class is used to enable the Pipeline.ProcessShard // RedisCheckpoint implements the Checkpont interface.
// to checkpoint their progress. // This class is used to enable the Pipeline.ProcessShard to checkpoint their progress.
type RedisCheckpoint struct { type RedisCheckpoint struct {
AppName string AppName string
StreamName string StreamName string
@ -16,32 +16,33 @@ type RedisCheckpoint struct {
sequenceNumber string sequenceNumber string
} }
// Check whether a checkpoint for a particular Shard exists. Typically used to determine whether we should // CheckpointExists determines if a checkpoint for a particular Shard exists.
// start processing the shard with TRIM_HORIZON or AFTER_SEQUENCE_NUMBER (if checkpoint exists). // Typically used to determine whether we should start processing the shard with
// TRIM_HORIZON or AFTER_SEQUENCE_NUMBER (if checkpoint exists).
func (c *RedisCheckpoint) CheckpointExists(shardID string) bool { func (c *RedisCheckpoint) CheckpointExists(shardID string) bool {
val, _ := c.client.Get(c.key(shardID)) val, _ := c.client.Get(c.key(shardID))
if val != nil && string(val) != "" { if val != nil && string(val) != "" {
c.sequenceNumber = string(val) c.sequenceNumber = string(val)
return true return true
} else {
return false
} }
return false
} }
// Get the current checkpoint stored for the specified shard. // SequenceNumber returns the current checkpoint stored for the specified shard.
func (c *RedisCheckpoint) SequenceNumber() string { func (c *RedisCheckpoint) SequenceNumber() string {
return c.sequenceNumber return c.sequenceNumber
} }
// Record a checkpoint for a shard (e.g. sequence number of last record processed by application). // SetCheckpoint stores a checkpoint for a shard (e.g. sequence number of last record processed by application).
// Upon failover, record processing is resumed from this point. // Upon failover, record processing is resumed from this point.
func (c *RedisCheckpoint) SetCheckpoint(shardID string, sequenceNumber string) { func (c *RedisCheckpoint) SetCheckpoint(shardID string, sequenceNumber string) {
c.client.Set(c.key(shardID), []byte(sequenceNumber)) c.client.Set(c.key(shardID), []byte(sequenceNumber))
c.sequenceNumber = sequenceNumber c.sequenceNumber = sequenceNumber
} }
// Generate a unique Redis key for storage of Checkpoint. // key generates a unique Redis key for storage of Checkpoint.
func (c *RedisCheckpoint) key(shardID string) string { func (c *RedisCheckpoint) key(shardID string) string {
return fmt.Sprintf("%v:checkpoint:%v:%v", c.AppName, c.StreamName, shardID) return fmt.Sprintf("%v:checkpoint:%v:%v", c.AppName, c.StreamName, shardID)
} }

View file

@ -7,10 +7,11 @@ import (
"log" "log"
"os" "os"
// Postgres package is used when sql.Open is called
_ "github.com/lib/pq" _ "github.com/lib/pq"
) )
// This struct is an implementation of Emitter that buffered batches of records into Redshift one by one. // RedshiftEmitter is an implementation of Emitter that buffered batches of records into Redshift one by one.
// It first emits records into S3 and then perfors the Redshift JSON COPY command. S3 storage of buffered // It first emits records into S3 and then perfors the Redshift JSON COPY command. S3 storage of buffered
// data achieved using the S3Emitter. A link to jsonpaths must be provided when configuring the struct. // data achieved using the S3Emitter. A link to jsonpaths must be provided when configuring the struct.
type RedshiftEmitter struct { type RedshiftEmitter struct {
@ -21,8 +22,8 @@ type RedshiftEmitter struct {
TableName string TableName string
} }
// Invoked when the buffer is full. This method leverages the S3Emitter and then issues a copy command to // Emit is invoked when the buffer is full. This method leverages the S3Emitter and
// Redshift data store. // then issues a copy command to Redshift data store.
func (e RedshiftEmitter) Emit(b Buffer, t Transformer) { func (e RedshiftEmitter) Emit(b Buffer, t Transformer) {
s3Emitter := S3Emitter{S3Bucket: e.S3Bucket} s3Emitter := S3Emitter{S3Bucket: e.S3Bucket}
s3Emitter.Emit(b, t) s3Emitter.Emit(b, t)

View file

@ -9,8 +9,9 @@ import (
"github.com/crowdmob/goamz/s3" "github.com/crowdmob/goamz/s3"
) )
// This implementation of Emitter is used to store files from a Kinesis stream in S3. The use of // S3Emitter is an implementation of Emitter used to store files from a Kinesis stream in S3.
// this struct requires the configuration of an S3 bucket/endpoint. When the buffer is full, this //
// The use of this struct requires the configuration of an S3 bucket/endpoint. When the buffer is full, this
// struct's Emit method adds the contents of the buffer to S3 as one file. The filename is generated // struct's Emit method adds the contents of the buffer to S3 as one file. The filename is generated
// from the first and last sequence numbers of the records contained in that file separated by a // from the first and last sequence numbers of the records contained in that file separated by a
// dash. This struct requires the configuration of an S3 bucket and endpoint. // dash. This struct requires the configuration of an S3 bucket and endpoint.
@ -18,14 +19,14 @@ type S3Emitter struct {
S3Bucket string S3Bucket string
} }
// Generates a file name based on the First and Last sequence numbers from the buffer. The current // S3FileName generates a file name based on the First and Last sequence numbers from the buffer. The current
// UTC date (YYYY-MM-DD) is base of the path to logically group days of batches. // UTC date (YYYY-MM-DD) is base of the path to logically group days of batches.
func (e S3Emitter) S3FileName(firstSeq string, lastSeq string) string { func (e S3Emitter) S3FileName(firstSeq string, lastSeq string) string {
date := time.Now().UTC().Format("2006-01-02") date := time.Now().UTC().Format("2006-01-02")
return fmt.Sprintf("/%v/%v-%v.txt", date, firstSeq, lastSeq) return fmt.Sprintf("/%v/%v-%v.txt", date, firstSeq, lastSeq)
} }
// Invoked when the buffer is full. This method emits the set of filtered records. // Emit is invoked when the buffer is full. This method emits the set of filtered records.
func (e S3Emitter) Emit(b Buffer, t Transformer) { func (e S3Emitter) Emit(b Buffer, t Transformer) {
auth, _ := aws.EnvAuth() auth, _ := aws.EnvAuth()
s3Con := s3.New(auth, aws.USEast) s3Con := s3.New(auth, aws.USEast)

View file

@ -1,11 +1,14 @@
package connector package connector
// StringToStringTransformer an implemenation of Transformer interface.
type StringToStringTransformer struct{} type StringToStringTransformer struct{}
// ToRecord takes a byte array and returns a string.
func (t StringToStringTransformer) ToRecord(data []byte) interface{} { func (t StringToStringTransformer) ToRecord(data []byte) interface{} {
return string(data) return string(data)
} }
// FromRecord takes an string and returns a byte array.
func (t StringToStringTransformer) FromRecord(s interface{}) []byte { func (t StringToStringTransformer) FromRecord(s interface{}) []byte {
return []byte(s.(string)) return []byte(s.(string))
} }

View file

@ -46,7 +46,7 @@ func upcaseInitial(str string) string {
return "" return ""
} }
// Opens the file path and loads config values into the sturct. // LoadConfig opens the file path and loads config values into the sturct.
func LoadConfig(config interface{}, filename string) error { func LoadConfig(config interface{}, filename string) error {
lines, err := readLines(filename) lines, err := readLines(filename)
@ -89,7 +89,8 @@ func LoadConfig(config interface{}, filename string) error {
return nil return nil
} }
// Creates a new Kinesis stream (uses existing stream if exists) and waits for it to become available. // CreateAndWaitForStreamToBecomeAvailable creates a new Kinesis stream (uses
// existing stream if exists) and waits for it to become available.
func CreateAndWaitForStreamToBecomeAvailable(k *kinesis.Kinesis, streamName string, shardCount int) { func CreateAndWaitForStreamToBecomeAvailable(k *kinesis.Kinesis, streamName string, shardCount int) {
if !StreamExists(k, streamName) { if !StreamExists(k, streamName) {
err := k.CreateStream(streamName, shardCount) err := k.CreateStream(streamName, shardCount)
@ -119,7 +120,7 @@ func CreateAndWaitForStreamToBecomeAvailable(k *kinesis.Kinesis, streamName stri
} }
} }
// Check if a Kinesis stream exists. // StreamExists checks if a Kinesis stream exists.
func StreamExists(k *kinesis.Kinesis, streamName string) bool { func StreamExists(k *kinesis.Kinesis, streamName string) bool {
args := kinesis.NewArgs() args := kinesis.NewArgs()
resp, _ := k.ListStreams(args) resp, _ := k.ListStreams(args)
@ -131,7 +132,7 @@ func StreamExists(k *kinesis.Kinesis, streamName string) bool {
return false return false
} }
// Delete a Kinesis stream. // DeleteStream deletes a current Kinesis stream.
func DeleteStream(k *kinesis.Kinesis, streamName string) { func DeleteStream(k *kinesis.Kinesis, streamName string) {
err := k.DeleteStream("test") err := k.DeleteStream("test")