Skip to content

Instantly share code, notes, and snippets.

@zhuravljov
Created August 27, 2018 08:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhuravljov/6f7a1f02025bcb9aff702e616acebd1a to your computer and use it in GitHub Desktop.
Save zhuravljov/6f7a1f02025bcb9aff702e616acebd1a to your computer and use it in GitHub Desktop.
Запуск команды с сетевой синхронизацией через MySQL
#!/usr/bin/env php
<?php
/**
* Запуск команды с сетевой синхронизацией через MySQL.
*
* Когда запускается сеть из docker-контейнеров каждый php-контейнер в числе
* прочих запускает команду миграции БД. И, чтобы исключить высокую вероятность,
* запуска нескольких таких процессов одновременно, используется синхронизация
* на уровне блокировок MySQL. Это гарантирует, что одновременно будет работать
* только одна из запущенных команд, а остальные будут ждать завершения.
*
* @author Roman Zhuravlev <zhuravljov@gmail.com>
*/
date_default_timezone_set(getenv('TZ'));
$params = $_SERVER['argv'];
array_shift($params);
$command = implode(' ', $params);
$mysql = new PDO(
sprintf('mysql:host=%s;dbname=%s', getenv('MYSQL_HOST'), getenv('MYSQL_DATABASE')),
getenv('MYSQL_USER'),
getenv('MYSQL_PASSWORD')
);
// Waiting a lock for the command
$query = $mysql->prepare('SELECT GET_LOCK(?, -1)');
$query->execute([md5($command)]);
if (!$query->fetch(PDO::FETCH_NUM)[0]) {
throw new Exception('Cannot get the lock.');
}
// Executes the command
passthru($command, $exitCode);
// Releases the lock
$query = $mysql->prepare('SELECT RELEASE_LOCK(?)');
$query->execute([md5($command)]);
if (!$query->fetch(PDO::FETCH_NUM)[0]) {
throw new Exception('Cannot release the lock.');
}
exit($exitCode);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment