PHP Laravel

Tenant Migrations and the Perils of Implicit State

The Reimpact/platform project involves managing multi-tenant applications. One subtle issue arose related to running migrations within these tenants. The original approach, while seemingly straightforward, introduced an unexpected dependency on implicit state, leading to incorrect migration behavior.

The Problem

Initially, tenant migrations were executed using Laravel's Artisan::call('migrate'). This appeared to work, but a deeper look revealed a potential flaw. The Artisan::call method could, under certain circumstances, resolve a new instance of the Migrator. This new instance would not inherit the tenant-specific configuration, specifically the swapped migration repository table name. As a result, the migration process would incorrectly check the default migrations table instead of the intended tenant_migrations table.

The Solution

The fix involved directly using the Migrator singleton instance. By resolving the Migrator directly from the container, the code ensures that it uses the correctly configured instance, complete with the swapped table name. This guarantees that tenant migrations operate on the appropriate table.

use Illuminate\Database\Migrations\Migrator;
use Illuminate\Support\Facades\App;

// Incorrect (potentially resolves a new Migrator instance):
// Artisan::call('migrate', ['--database' => 'tenant']);

// Correct (uses the existing Migrator instance):
$migrator = App::make(Migrator::class);
$migrator->run(['database' => 'tenant']);

The code above shows the difference. The Artisan::call() method is replaced with direct access to the Migrator instance. The --database option is also passed to the run method, ensuring the migrations use the tenant database connection.

The Takeaway

Be mindful of implicit state when working with singletons and long-lived processes. Ensure that configurations and dependencies are correctly propagated to avoid unexpected behavior. In the context of Laravel migrations, always resolve the Migrator instance directly to guarantee the correct database table is used, especially in multi-tenant environments.

Tenant Migrations and the Perils of Implicit State
GERARDO RUIZ

GERARDO RUIZ

Author

Share: