Machine
is a library for creating data workflows. These workflows can be either very concise or quite complex, even allowing for cycles for flows that need retry or self healing mechanisms.
Add the primary library to your project
go get -u github.com/whitaker-io/machine
Download the command to generate a boilerplate project (WIP/alpha state)
go get -u github.com/whitaker-io/machine/cmd
cd $GOSRC/github.com/whitaker-io/machine/cmd
go build -a -o pkg/machine -ldflags "-s -w"
sudo ln -s pkg/machine /usr/local/bin/machine
Add the different Subscription Implementations
go get -u github.com/whitaker-io/machine/subscriptions/kafka
go get -u github.com/whitaker-io/machine/subscriptions/redis
go get -u github.com/whitaker-io/machine/subscriptions/pubsub
go get -u github.com/whitaker-io/machine/subscriptions/sqs
Redis Subscription with basic receive
-> process
-> send
Stream
// logger allows for logs to be transmitted to your log provider
var logger machine.Logger
// logStore allows for running a cluster and handles communication
var logStore machine.LogStore
// pool is a redigo Pool for a redis cluster to read the stream from
// see also the Google Pub/Sub, Kafka, and SQS implementations
var pool *redigo.Pool
redisStream := redis.New(pool, logger)
// NewPipe creates a pipe in which you can run multiple streams
// the id is the instance identifier for the cluster
p := NewPipe(uuid.New().String(), logger, logStore, fiber.Config{
ReadTimeout: time.Second,
WriteTimeout: time.Second,
BodyLimit: 4 * 1024 * 1024,
DisableKeepalive: true,
})
// StreamSubscription takes an instance of machine.Subscription
// and a time interval in which to read
// the id here needs to be the same for all the nodes for the clustering to work
builder := p.StreamSubscription("unique_stream_id", redisStream, 5*time.Millisecond,
&Option{FIFO: boolP(false)},
&Option{Injectable: boolP(true)},
&Option{Metrics: boolP(true)},
&Option{Span: boolP(false)},
&Option{BufferSize: intP(0)},
).Builder()
builder.Map("unique_id2",
func(m Data) error {
var err error
// ...do some processing
return err
},
).
Transmit("unique_id3",
func(d []Data) error {
// send a copy of the data somewhere
return nil
},
)
// Run requires a context, the port to run the fiber.App,
// and the timeout for graceful shutdown
if err := p.Run(context.Background(), ":5000", 10 * time.Second); err != nil {
// Run will return an error in the case that
// one of the paths is not terminated (i.e. missing a Transmit)
panic(err)
}
Contributions, issues and feature requests are welcome.
Feel free to check issues page if you want to contribute.
Check the contributing guide.
👤 Jonathan Whitaker
- Twitter: @io_whitaker
- Github: @jonathan-whitaker
Please ⭐️ this repository if this project helped you!
Machine is provided under the MIT License.
The MIT License (MIT)
Copyright (c) 2020 Jonathan Whitaker