Skip to content

lab259/go-migration-tenant

Repository files navigation

go-tenant-migration CircleCI codecov Go Report Card license GoDoc

go-tenant-migration, or mtnt for short, is designed to run migrations on tenants in parallel.

This lihbrary is an extention of the go-migration.

TL;DR

Account and AccountProducer interfaces should be implemented. Where Account should provide the account database reference and AccountProducer should implement listing the Account instaces that should be migrated.

The rest should look like this:

package main

import (
	"os"
	
	mtnt "github.com/lab259/go-migration-tenant"
	mtntMongo "github.com/lab259/go-migration-tenant/mongo"
	migration "github.com/lab259/go-migration"
	
	"yoursystem"
	_ "yoursystem/migrations"
)

func main() {
	executor := mtnt.NewMigrationExecutor(
		migration.NewDefaultReporter(), 
		mtnt.NewDefaultReporter(os.Stdout),
		mtntMongo.Connector,
		yoursystem.NewAccountProducer(), // YOU MUST implement the account producer
		migration.DefaultCodeSource(),
	)
	executor.Run(10, os.Args...) // <- number of workers that will execute migrations, in other
	                            // words how many accounts you want to migrate in parallel.
}

Usage

Listing accounts

In order to run the system, you need to implement 2 interfaces: Account and AccountProducer.

Account (interface)

Account represents each tenant of your system. It should hold the database reference and provides the execution context for the migration. The execution context will be passed to each handler as it is called.

Hence, it is up to you to produce an execution context that will provide the database connection for the handlers. The default implementation expects you to provide the database connection reference as execution context. But, it can be easily changed by implementing a new Connector.

Identification() string
ProvideMigrationContext(func(executionContext interface{}) error) error

AccountProducer (interface)

AccountProducer should list all the Accounts that need to be migrated.

Get() ([]Account, error)
HasNext() bool
Total() int

Running a migration

Once implemented Account and AccountProducer, the library is able to run all migrations.

package main

import (
	"os"
	
	mtnt "github.com/lab259/go-migration-tenant"
	mtntMongo "github.com/lab259/go-migration-tenant/mongo"
	migration "github.com/lab259/go-migration"
	
	"yoursystem"
	_ "yoursystem/migrations"
)

func main() {
	executor := mtnt.NewMigrationExecutor(
		migration.NewDefaultReporter(), 
		mtnt.NewDefaultReporter(os.Stdout),
		mtntMongo.Connector,
		yoursystem.NewAccountProducer(), // YOU MUST implement the account producer
		migration.DefaultCodeSource(),
	)
	executor.Run(10, os.Args...) // <- number of workers that will execute migrations, in other
	                // words how many accounts you want to migrate in parallel.
}

Now, after compiling the system:

./bin/migration migrate

To know more about the migration commands you can:

./bin/migration --help

What if I need to filter one specific account

Well, the AccountProducer implementation is up to you. So, you should filter accounts while implementing the producer.

Concurrency

The library uses gp-prdcsm to implement a Producer & Consumer pattern to achieve concurrent migrations. Migrations at the account level are not ran in parallel. But, two, or more, accounts should run in parallel.

License

MIT