]> git.mxchange.org Git - friendica.git/commitdiff
Add `hostname` to `Process` entity
authorPhilipp <admin@philipp.info>
Sat, 6 Nov 2021 19:21:01 +0000 (20:21 +0100)
committerPhilipp <admin@philipp.info>
Sat, 6 Nov 2021 19:21:01 +0000 (20:21 +0100)
database.sql
src/Core/Worker/Entity/Process.php
src/Core/Worker/Exception/ProcessPersistenceException.php
src/Core/Worker/Factory/Process.php
src/Core/Worker/Repository/Process.php
src/Database/DBStructure.php
src/Model/Host.php [deleted file]
static/dbstructure.config.php
static/dependencies.config.php
tests/src/Core/Worker/Repository/ProcessTest.php [new file with mode: 0644]

index fcbcbb3941855e8bded0f03c7b6f500f20364232..9b19517bb90d12115160515dc55d8488d0bb114a 100644 (file)
@@ -1,6 +1,6 @@
 -- ------------------------------------------
 -- Friendica 2021.12-dev (Siberian Iris)
--- DB_UPDATE_VERSION 1442
+-- DB_UPDATE_VERSION 1443
 -- ------------------------------------------
 
 
@@ -681,16 +681,6 @@ CREATE TABLE IF NOT EXISTS `hook` (
         UNIQUE INDEX `hook_file_function` (`hook`,`file`,`function`)
 ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='addon hook registry';
 
---
--- TABLE host
---
-CREATE TABLE IF NOT EXISTS `host` (
-       `id` tinyint unsigned NOT NULL auto_increment COMMENT 'sequential ID',
-       `name` varchar(128) NOT NULL DEFAULT '' COMMENT 'The hostname',
-        PRIMARY KEY(`id`),
-        UNIQUE INDEX `name` (`name`)
-) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Hostname';
-
 --
 -- TABLE inbox-status
 --
@@ -1325,10 +1315,11 @@ CREATE TABLE IF NOT EXISTS `post-user-notification` (
 -- TABLE process
 --
 CREATE TABLE IF NOT EXISTS `process` (
-       `pid` int unsigned NOT NULL COMMENT '',
+       `pid` int unsigned NOT NULL COMMENT 'The process ID of the current node',
+       `hostname` varchar(32) NOT NULL COMMENT 'The hostname of the node',
        `command` varbinary(32) NOT NULL DEFAULT '' COMMENT '',
        `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
-        PRIMARY KEY(`pid`),
+        PRIMARY KEY(`pid`, `hostname`),
         INDEX `command` (`command`)
 ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Currently running system processes';
 
index 7161f9ca46556b076f3230e80a63bd80d8d55709..1353e2635e4113aaece3dc4c21cabdb05d988117 100644 (file)
@@ -1,4 +1,23 @@
 <?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
 
 namespace Friendica\Core\Worker\Entity;
 
@@ -8,6 +27,7 @@ use Friendica\BaseEntity;
 /**
  * @property-read int $pid
  * @property-read string $command
+ * @property-read string $hostname
  * @property-read DateTime $created
  */
 class Process extends BaseEntity
@@ -16,18 +36,22 @@ class Process extends BaseEntity
        protected $pid;
        /** @var string */
        protected $command;
+       /** @var string */
+       protected $hostname;
        /** @var DateTime */
        protected $created;
 
        /**
-        * @param int       $pid
-        * @param string    $command
+        * @param int      $pid
+        * @param string   $command
+        * @param string   $hostname
         * @param DateTime $created
         */
-       public function __construct(int $pid, string $command, DateTime $created)
+       public function __construct(int $pid, string $command, string $hostname, DateTime $created)
        {
-               $this->pid     = $pid;
-               $this->command = $command;
-               $this->created = $created;
+               $this->pid      = $pid;
+               $this->command  = $command;
+               $this->hostname = $hostname;
+               $this->created  = $created;
        }
 }
index c1c34453af6217eb646223576165c8b2aaa7380d..034a21cb526763de99a1825cc8f25bb96aa63343 100644 (file)
@@ -1,4 +1,23 @@
 <?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
 
 namespace Friendica\Core\Worker\Exception;
 
index 1b66906899673b8fa4a07171e5ee8ed67ab7f71a..7e9c2606fb94e145e6c51cd58814a4a273074448 100644 (file)
@@ -1,4 +1,23 @@
 <?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
 
 namespace Friendica\Core\Worker\Factory;
 
@@ -8,28 +27,22 @@ use Friendica\Core\Worker\Entity;
 
 class Process extends BaseFactory implements ICanCreateFromTableRow
 {
+       public function determineHost(?string $hostname = null): string
+       {
+               if (empty($hostname)) {
+                       $hostname = php_uname('n');
+               }
+
+               return strtolower($hostname);
+       }
+
        public function createFromTableRow(array $row): Entity\Process
        {
                return new Entity\Process(
                        $row['pid'],
                        $row['command'],
+                       $this->determineHost($row['hostname'] ?? null),
                        new \DateTime($row['created'] ?? 'now', new \DateTimeZone('UTC'))
                );
        }
-
-       /**
-        * Creates a new process entry for a given PID
-        *
-        * @param int    $pid
-        * @param string $command
-        *
-        * @return Entity\Process
-        */
-       public function create(int $pid, string $command): Entity\Process
-       {
-               return $this->createFromTableRow([
-                       'pid'     => $pid,
-                       'command' => $command,
-               ]);
-       }
 }
index 1e91d867fb3e1e8b2a3106f2c3863c47e8c854ac..3faa7627ea26bcd33b473022dd2f7d7f0fb8deba 100644 (file)
@@ -34,18 +34,25 @@ use Psr\Log\LoggerInterface;
  */
 class Process extends BaseRepository
 {
+       const NODE_ENV = 'NODE_ENV';
+
        protected static $table_name = 'process';
 
        /** @var Factory\Process */
        protected $factory;
 
-       public function __construct(Database $database, LoggerInterface $logger, Factory\Process $factory)
+       /** @var string */
+       private $currentHost;
+
+       public function __construct(Database $database, LoggerInterface $logger, Factory\Process $factory, array $server)
        {
                parent::__construct($database, $logger, $factory);
+
+               $this->currentHost = $factory->determineHost($server[self::NODE_ENV] ?? '');
        }
 
        /**
-        * Starts and Returns the process for a given PID
+        * Starts and Returns the process for a given PID at the current host
         *
         * @param int    $pid
         * @param string $command
@@ -60,19 +67,18 @@ class Process extends BaseRepository
                try {
                        $this->db->transaction();
 
-                       $newProcess = $this->factory->create($pid, $command);
-
-                       if (!$this->db->exists('process', ['pid' => $pid])) {
+                       if (!$this->db->exists('process', ['pid' => $pid, 'hostname' => $this->currentHost])) {
                                if (!$this->db->insert(static::$table_name, [
-                                       'pid'     => $newProcess->pid,
-                                       'command' => $newProcess->command,
-                                       'created' => $newProcess->created->format(DateTimeFormat::MYSQL)
+                                       'pid'      => $pid,
+                                       'command'  => $command,
+                                       'hostname' => $this->currentHost,
+                                       'created'  => DateTimeFormat::utcNow()
                                ])) {
                                        throw new ProcessPersistenceException(sprintf('The process with PID %s already exists.', $pid));
                                }
                        }
 
-                       $result = $this->_selectOne(['pid' => $pid]);
+                       $result = $this->_selectOne(['pid' => $pid, 'hostname' => $this->currentHost]);
 
                        $this->db->commit();
 
@@ -86,7 +92,8 @@ class Process extends BaseRepository
        {
                try {
                        if (!$this->db->delete(static::$table_name, [
-                               'pid' => $process->pid
+                               'pid'      => $process->pid,
+                               'hostname' => $this->currentHost,
                        ])) {
                                throw new ProcessPersistenceException(sprintf('The process with PID %s doesn\'t exists.', $process->pi));
                        }
@@ -103,7 +110,7 @@ class Process extends BaseRepository
                $this->db->transaction();
 
                try {
-                       $processes = $this->db->select('process', ['pid']);
+                       $processes = $this->db->select('process', ['pid'], ['hostname' => $this->currentHost]);
                        while ($process = $this->db->fetch($processes)) {
                                if (!posix_kill($process['pid'], 0)) {
                                        $this->db->delete('process', ['pid' => $process['pid']]);
index 4a1588dd12856ca90ab65f1f038da4f287b481a5..2b0e3d1e358966d3768cdfa418b08eb764fb57fd 100644 (file)
@@ -82,7 +82,7 @@ class DBStructure
                $old_tables = ['fserver', 'gcign', 'gcontact', 'gcontact-relation', 'gfollower' ,'glink', 'item-delivery-data',
                        'item-activity', 'item-content', 'item_id', 'participation', 'poll', 'poll_result', 'queue', 'retriever_rule',
                        'deliverq', 'dsprphotoq', 'ffinder', 'sign', 'spam', 'term', 'user-item', 'thread', 'item', 'challenge',
-                       'auth_codes', 'clients', 'tokens', 'profile_check'];
+                       'auth_codes', 'clients', 'tokens', 'profile_check', 'host'];
 
                $tables = DBA::selectToArray(['INFORMATION_SCHEMA' => 'TABLES'], ['TABLE_NAME'],
                        ['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_TYPE' => 'BASE TABLE']);
diff --git a/src/Model/Host.php b/src/Model/Host.php
deleted file mode 100644 (file)
index 078c2f9..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Model;
-
-use Friendica\Core\Logger;
-use Friendica\Database\DBA;
-
-class Host
-{
-       /**
-        * Get the id for a given hostname
-        * When empty, the current hostname is used
-        *
-        * @param string $hostname
-        *
-        * @return integer host name id
-        * @throws \Exception
-        */
-       public static function getId(string $hostname = '')
-       {
-               if (empty($hostname)) {
-                       $hostname = php_uname('n');
-               }
-
-               $hostname = strtolower($hostname);
-
-               $host = DBA::selectFirst('host', ['id'], ['name' => $hostname]);
-               if (!empty($host['id'])) {
-                       return $host['id'];
-               }
-
-               DBA::replace('host', ['name' => $hostname]);
-
-               $host = DBA::selectFirst('host', ['id'], ['name' => $hostname]);
-               if (empty($host['id'])) {
-                       Logger::warning('Host name could not be inserted', ['name' => $hostname]);
-                       return 0;
-               }
-
-               return $host['id'];
-       }
-
-       /**
-        * Get the hostname for a given id
-        *
-        * @param int $id
-        *
-        * @return string host name
-        * @throws \Exception
-        */
-       public static function getName(int $id)
-       {
-               $host = DBA::selectFirst('host', ['name'], ['id' => $id]);
-               if (!empty($host['name'])) {
-                       return $host['name'];
-               }
-
-               return '';
-       }
-}
index 0019fdf7bf5a2567466545fa6673158cf01b3494..409829acd3914ac384b4047c7727ae8d1e3c3f9c 100644 (file)
@@ -55,7 +55,7 @@
 use Friendica\Database\DBA;
 
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1442);
+       define('DB_UPDATE_VERSION', 1443);
 }
 
 return [
@@ -743,17 +743,6 @@ return [
                        "hook_file_function" => ["UNIQUE", "hook", "file", "function"],
                ]
        ],
-       "host" => [
-               "comment" => "Hostname",
-               "fields" => [
-                       "id" => ["type" => "tinyint unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
-                       "name" => ["type" => "varchar(128)", "not null" => "1", "default" => "", "comment" => "The hostname"],
-               ],
-               "indexes" => [
-                       "PRIMARY" => ["id"],
-                       "name" => ["UNIQUE", "name"],
-               ]
-       ],
        "inbox-status" => [
                "comment" => "Status of ActivityPub inboxes",
                "fields" => [
@@ -1343,12 +1332,13 @@ return [
        "process" => [
                "comment" => "Currently running system processes",
                "fields" => [
-                       "pid" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "comment" => ""],
+                       "pid" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "comment" => "The process ID of the current node"],
+                       "hostname" => ["type" => "varchar(32)", "not null" => "1", "primary" => "1", "comment" => "The hostname of the current node"],
                        "command" => ["type" => "varbinary(32)", "not null" => "1", "default" => "", "comment" => ""],
                        "created" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
                ],
                "indexes" => [
-                       "PRIMARY" => ["pid"],
+                       "PRIMARY" => ["pid", "hostname"],
                        "command" => ["command"],
                ]
        ],
index d3034a2ba59a8bdc91dd402213205357bbcbd95b..57ef629bb255aa04f74365774d0471d3e3b247bb 100644 (file)
@@ -238,4 +238,9 @@ return [
                        [Dice::INSTANCE => Util\ReversedFileReader::class],
                ]
        ],
+       \Friendica\Core\Worker\Repository\Process::class => [
+               'constructParams' => [
+                       $_SERVER
+               ],
+       ],
 ];
diff --git a/tests/src/Core/Worker/Repository/ProcessTest.php b/tests/src/Core/Worker/Repository/ProcessTest.php
new file mode 100644 (file)
index 0000000..be7b87a
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+namespace Friendica\Test\src\Core\Worker\Repository;
+
+use Friendica\Core\Worker\Factory;
+use Friendica\Core\Worker\Repository;
+use Friendica\DI;
+use Friendica\Test\FixtureTest;
+use Psr\Log\NullLogger;
+
+class ProcessTest extends FixtureTest
+{
+       public function testStandardProcess()
+       {
+               $factory    = new Factory\Process(new NullLogger());
+               $repository = new Repository\Process(DI::dba(), new NullLogger(), $factory, []);
+
+               $entityNew = $repository->create(getmypid(), 'test');
+
+               self::assertEquals(getmypid(), $entityNew->pid);
+               self::assertEquals('test', $entityNew->command);
+               self::assertLessThanOrEqual(new \DateTime('now', new \DateTimeZone('UTC')), $entityNew->created);
+               self::assertEquals(php_uname('n'), $entityNew->hostname);
+       }
+
+       public function testHostnameEnv()
+       {
+               $factory    = new Factory\Process(new NullLogger());
+               $repository = new Repository\Process(DI::dba(), new NullLogger(), $factory, [Repository\Process::NODE_ENV => 'test_node']);
+
+               $entityNew = $repository->create(getmypid(), 'test');
+
+               self::assertEquals(getmypid(), $entityNew->pid);
+               self::assertEquals('test', $entityNew->command);
+               self::assertLessThanOrEqual(new \DateTime('now', new \DateTimeZone('UTC')), $entityNew->created);
+               self::assertEquals('test_node', $entityNew->hostname);
+       }
+}