1
1
#!/usr/bin/env php
2
2
<?php
3
3
/**
4
- * Запуск команды с сетевой синхронизацией через MySQL.
4
+ * Runs a command with network sync using MySQL.
5
5
*
6
- * Когда запускается сеть из docker-контейнеров каждый php-контейнер в числе
7
- * прочих запускает команду миграции БД. И, чтобы исключить высокую вероятность,
8
- * запуска нескольких таких процессов одновременно, используется синхронизация
9
- * на уровне блокировок MySQL. Это гарантирует, что одновременно будет работать
10
- * только одна из запущенных команд, а остальные будут ждать завершения.
6
+ * When network of docker containers is starting, each php container executes
7
+ * DB migration command. To except chance to execute many commands at the same time,
8
+ * network sync is used. It uses `GET_LOCK()` and `RELEASE_LOCK()` MySQL functions.
9
+ * This ensures monopoly execution. One of the commands will be run, and others will wait.
11
10
*
12
11
* @author Roman Zhuravlev <zhuravljov@gmail.com>
13
12
*/
14
13
15
14
$ params = $ _SERVER ['argv ' ];
16
15
array_shift ($ params );
17
16
$ command = implode (' ' , $ params );
17
+ $ lockName = md5 ($ command );
18
18
19
19
$ mysql = new PDO (
20
20
sprintf (
29
29
30
30
// Waiting a lock for the command
31
31
$ query = $ mysql ->prepare ('SELECT GET_LOCK(?, -1) ' );
32
- $ query ->execute ([md5 ( $ command ) ]);
32
+ $ query ->execute ([$ lockName ]);
33
33
if (!$ query ->fetch (PDO ::FETCH_NUM )[0 ]) {
34
- throw new Exception ('Cannot get the lock. ' );
34
+ echo basename (__FILE__ ) . ': cannot get the lock. ' . PHP_EOL ;
35
+ exit (1 );
35
36
}
36
37
37
38
// Executes the command
38
39
passthru ($ command , $ exitCode );
39
40
40
41
// Releases the lock
41
42
$ query = $ mysql ->prepare ('SELECT RELEASE_LOCK(?) ' );
42
- $ query ->execute ([md5 ( $ command ) ]);
43
+ $ query ->execute ([$ lockName ]);
43
44
if (!$ query ->fetch (PDO ::FETCH_NUM )[0 ]) {
44
- throw new Exception ('Cannot release the lock. ' );
45
+ echo basename (__FILE__ ) . ': release the lock. ' . PHP_EOL ;
46
+ exit (1 );
45
47
}
46
48
47
49
exit ($ exitCode );
0 commit comments