wintercms / winter

Free, open-source, self-hosted CMS platform based on the Laravel PHP Framework.
https://wintercms.com
MIT License
1.38k stars 195 forks source link

Winter migrations are not concurrency-friendly #1225

Closed lex0r closed 2 weeks ago

lex0r commented 1 month ago

Winter CMS Build

dev-develop

PHP Version

8.1

Database engine

MySQL/MariaDB

Plugins installed

No response

Issue description

Laravel's console Command implementation allows commands to run in isolation. Essentially it means an isolated command can't have more than one active process. A typical use case is when there's some parallelism in a system and command is not mean to be run multiple times let alone in parallel. Database migration is another example when isolation is needed.

Normally, in a single instance deployment this is not an issue. However, Winter CMS may be used in a multi-server setup, when some CI/CD tool runs a parallel deployment (e.g. using Kubernetes etc), leading to winter:up command being called automatically more than once.

The simplest solution is to rely on the built-in support and --isolated option to the migration command which can be achieved by just implementing Isolatable interface (which has no methods at all).

Steps to replicate

  1. Create a non-idempotent migration (like "CREATE TABLE ...")
  2. Run it in a multi-server deployment, making sure it's executed in parallel.
  3. Observe the failure of the 2nd and other instances who attempted to run the migration (because they all started at the same time and "thought" they had to run it)

Workaround

No response

lex0r commented 1 month ago

See https://github.com/wintercms/winter/pull/1226