Split for Go

We’re happy to announce that Split customers can now use us with Go projects! Split lets you see the impact of any feature release on all your key product usage and customer experience metrics. Key to this is supporting feature flags in code written across any number of languages. Now, if you have a project where one component is Java, for example, and another component is written in Go (a.k.a. Golang), you can now use Split across the entire project. Our customers are increasingly incorporating development in Golang for the ease of writing code, but the performance of a compiled language and simplicity of handling concurrency.

Teams that build on top of Go now also have the power to safely launch features and target them to users. Use Split to control your rollouts and manage the customer experience, all while gathering new data and insight on how your products are being used.

Architecture Overview

No two architectures are exactly the same. That’s why with Split’s Go SDK we ensured it was capable of running in three different modes to fit in different infrastructure configurations.

  • in-memory-standalone: The first and most straightforward operation mode (also the default one if none is specified) uses an in-memory storage to keep splits, segments & queued impressions/metrics, as well as its own synchronization tasks that periodically keep splits & segments up to date, while flushing impressions & metrics to the Split backend.
  • redis-standalone: This mode uses redis to store data, enabling clients who already have a redis cluster running within their infrastructure to reuse it. This can be useful to minimize memory usage within the server using the SDK. It uses the SDK’s own synchronization tasks.
  • redis-consumer: The third mode uses redis as a broker to retrieve splits & segments and store impressions and metrics. This mode requires the Split Synchronizer to be running in the background, populating redis with segments & splits, and flushing impressions & metrics to the Split backend. This mode is useful if you have multiple instances of Split’s SDKs running (either in the same or a different language) and want to have a single synchronization point in your infrastructure.

SDK Setup

Split’s Go SDK is shipped with a Gopkg.toml file that handles its own dependencies.

You can import the SDK into your project as defined below:

import ( "github.com/splitio/go-client/splitio/client" "github.com/splitio/go-client/splitio/conf" )
Code language: Swift (swift)

Be sure to run dep ensure to resolve all dependencies.

Creating a Long-Lived Client

The next step is to create a long-lived Split client. All you need to do is insert your API key and adjust the SDK configurations based on your preferred settings.

func main() { cfg := conf.Default() cfg.BlockUntilReady = 10 factory, err := client.NewSplitFactory("your_api_key", cfg) if err != nil { fmt.Printf("SDK init error: %s\n", err) return } client := factory.Client() // ... }
Code language: Go (go)

Splitting Your Code

Once instantiated, you can use Split to make decisions on what code path to take given different responses from Split, also known as treatments.

As an example, let’s assume we have two types of credit card payments we support—Visa and MasterCard—and are about to introduce a third—Amex.

The code would look like this:

treatment := client.Treatment("CUSTOMER_ID", "SPLIT_NAME", nil) if treatment == "visa" { // insert code here to show visa treatment } else if treatment == "master_card" { // insert code here to show master_card treatment } else if treatment == "amex" { // insert code here to show amex treatment } else { // insert your control treatment code here }
Code language: Go (go)

The Split Go SDK integrates seamlessly into your code; no other changes or dependencies are needed to get Split up and running.

Split as an On/Off Switch

Imagine the valid scenario where you want to start testing a new database like Apache Cassandra to migrate part of your existing dataset in your primary datastore. A safe approach is to do what are called dark writes, which for this exercise we’ll do in a feature named double_writes_to_cassandra. This practice is known as dark writes because for each write of the data we care about, we also perform a similar write to another database to start testing its performance. But, this data isn’t yet read from the DB, hence, it’s “dark”.

For this use-case, Split can be used as a simple on/off switch. The code would look something like this:

treatment := client.Treatment("CUSTOMER_ID", "SPLIT_NAME", nil) if treatment == "on" { // insert code here to perform writes to cassandra } else if treatment == "off" { // insert code here to do nothing } else { // insert your control treatment code here }
Code language: Go (go)

Pro Tips

  • Since the split client can be used from anywhere in the code, you can either propagate the instance manually to the modules that need it or make it available in a module, possibly exposing a .Initialize() function that instantiates and keeps the factory, and methods .Client() and .Manager() (optional) that allow you to access the instances.
  • The performance of the SDK can be optimized by adjusting the parameters SegmentWorkers and SegmentQueueSize from the advanced section in the SDK configuration. They specify the number of workers that will be used to update segments and how many segments can be queued. These should be updated while also considering the TaskPeriods.SegmentSync parameter from the configuration structure, how much often are ALL segments refreshed.
  • The SDK allows the user to provide a custom logger and a custom impression listener. We encourage developers to use non-blocking logic within these in order to avoid blocking the whole sdk and/or application. Also, deferring a function that recovers from a panic if any is recommended in case something goes wrong in the user’s custom logic.

To start using Split with Go, please read the Split Go SDK documentation. If you aren’t yet using Split, get started with our 14-day free trial.