Skip to content

Commit

Permalink
more changes to support multi-user sync
Browse files Browse the repository at this point in the history
  • Loading branch information
arabcoders committed Jan 21, 2025
1 parent 3caa5dc commit 624ebb1
Show file tree
Hide file tree
Showing 11 changed files with 349 additions and 52 deletions.
1 change: 1 addition & 0 deletions config/directories.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
'{path}/db/archive',
'{path}/config',
'{path}/backup',
'{path}/users',
'{tmp_dir}/logs',
'{tmp_dir}/cache',
'{tmp_dir}/profiler',
Expand Down
17 changes: 17 additions & 0 deletions src/Backends/Common/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ public function __construct(private iLogger $logger, private iCache $cache)
{
}

/**
* Clone the object with the given logger and cache adapter.
*
* @param iLogger|null $logger The logger to use. If not provided, the current logger is used.
* @param iCache|null $adapter The cache adapter to use. If not provided, the current cache adapter is used.
*
* @return Cache return new instance of Cache class.
*/
public function with(iLogger|null $logger = null, iCache|null $adapter = null): self
{
$cloned = clone $this;
$cloned->logger = $logger ?? $this->logger;
$cloned->cache = $adapter ?? $this->cache;

return $cloned;
}

/**
* Clone the object with the data retrieved from the cache based on the key.
*
Expand Down
31 changes: 22 additions & 9 deletions src/Commands/State/SyncCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@

namespace App\Commands\State;

use App\Backends\Common\Cache as BackendCache;
use App\Backends\Common\ClientInterface as iClient;
use App\Command;
use App\Libs\Attributes\Route\Cli;
use App\Libs\Config;
use App\Libs\ConfigFile;
use App\Libs\Container;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Extends\StreamLogHandler;
use App\Libs\LogSuppressor;
use App\Libs\Mappers\Import\NullMapper;
use App\Libs\Mappers\ExtendedImportInterface as iEImport;
use App\Libs\Mappers\Import\MemoryMapper;
use App\Libs\Message;
use App\Libs\Options;
use App\Libs\QueueRequests;
Expand Down Expand Up @@ -45,12 +48,12 @@ class SyncCommand extends Command
/**
* Class Constructor.
*
* @param NullMapper $mapper The instance of the DirectMapper class.
* @param MemoryMapper $mapper The instance of the DirectMapper class.
* @param QueueRequests $queue The instance of the QueueRequests class.
* @param iLogger $logger The instance of the iLogger class.
*/
public function __construct(
private readonly NullMapper $mapper,
private readonly MemoryMapper $mapper,
private readonly QueueRequests $queue,
private readonly iLogger $logger,
private readonly LogSuppressor $suppressor,
Expand Down Expand Up @@ -323,8 +326,13 @@ protected function process(iInput $input, iOutput $output): int
]);

foreach (array_reverse($users) as $user) {
$userName = ag($user, 'name', 'Unknown');
$perUserCache = perUserCacheAdapter($userName);
$perUserMapper = perUserMapper($this->mapper, $userName)
->withCache($perUserCache)
->withLogger($this->logger)->loadData();

$this->queue->reset();
$this->mapper->reset();

$list = [];
$displayName = null;
Expand All @@ -333,7 +341,9 @@ protected function process(iInput $input, iOutput $output): int
$name = ag($backend, 'client_data.backendName');
$clientData = ag($backend, 'client_data');
$clientData['name'] = $name;
$clientData['class'] = makeBackend($clientData, $name)->setLogger($this->logger);
$clientData['class'] = makeBackend($clientData, $name, [
BackendCache::class => Container::get(BackendCache::class)->with(adapter: $perUserCache)
])->setLogger($this->logger);
$list[$name] = $clientData;
$displayName = ag($backend, 'client_data.displayName', '??');
}
Expand All @@ -345,9 +355,12 @@ protected function process(iInput $input, iOutput $output): int
'started' => $start,
]);

$this->handleImport($displayName, $list);
assert($perUserMapper instanceof iEImport);
$this->handleImport($perUserMapper, $displayName, $list);

$changes = $this->mapper->computeChanges(array_keys($list));
assert($perUserMapper instanceof MemoryMapper);
/** @var MemoryMapper $changes */
$changes = $perUserMapper->computeChanges(array_keys($list));

foreach ($changes as $b => $changed) {
$count = count($changed);
Expand Down Expand Up @@ -394,15 +407,15 @@ protected function process(iInput $input, iOutput $output): int
return self::SUCCESS;
}

protected function handleImport(string $name, array $backends): void
protected function handleImport(iEImport $mapper, string $name, array $backends): void
{
/** @var array<array-key,ResponseInterface> $queue */
$queue = [];

foreach ($backends as $backend) {
/** @var iClient $client */
$client = ag($backend, 'class');
array_push($queue, ...$client->pull($this->mapper));
array_push($queue, ...$client->pull($mapper));
}

$start = makeDate();
Expand Down
15 changes: 14 additions & 1 deletion src/Libs/Database/DBLayer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class DBLayer implements LoggerAwareInterface

private int $count = 0;

private string $driver;
private string $driver = '';

private array $last = [
'sql' => '',
Expand Down Expand Up @@ -66,6 +66,19 @@ public function __construct(private readonly PDO $pdo, private array $options =
$this->retry = ag($this->options, 'retry', self::LOCK_RETRY);
}

/**
* Create a new instance with the given PDO object and options.
*
* @param PDO $pdo The PDO object.
* @param array|null $options The options to be passed to the new instance, or null to use the current options.
*
* @return self The new instance.
*/
public function withPDO(PDO $pdo, array|null $options = null): self
{
return new self($pdo, $options ?? $this->options);
}

/**
* Execute a SQL statement and return the number of affected rows.
* The execution will be wrapped into {@link DBLayer::wrap()} method. to handle database locks.
Expand Down
29 changes: 24 additions & 5 deletions src/Libs/Database/DatabaseInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,33 @@
use Closure;
use DateTimeInterface;
use PDOException;
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerInterface as iLogger;

interface DatabaseInterface
{
public const string MIGRATE_UP = 'up';

public const string MIGRATE_DOWN = 'down';

/**
* Create new instance.
* @param iLogger|null $logger Logger to use, if null use default.
* @param DBLayer|null $db Database layer to use, if null use default.
* @param array|null $options PDO options.
*
* @return self Return new instance.
*/
public function with(iLogger|null $logger = null, DBLayer|null $db = null, array|null $options = null): self;

/**
* Set options
*
* @param array $options PDO options
*
* @return self return new instance with options.
*/
public function withOptions(array $options): self;

/**
* Set options
*
Expand Down Expand Up @@ -124,11 +143,11 @@ public function ensureIndex(array $opts = []): mixed;
* Migrate data from old database schema to new one.
*
* @param string $version Version to migrate to.
* @param LoggerInterface|null $logger Logger to use.
* @param iLogger|null $logger Logger to use.
*
* @return mixed Return value depends on the driver.
*/
public function migrateData(string $version, LoggerInterface|null $logger = null): mixed;
public function migrateData(string $version, iLogger|null $logger = null): mixed;

/**
* Is the database up to date with migrations?
Expand Down Expand Up @@ -166,11 +185,11 @@ public function reset(): bool;
/**
* Inject Logger.
*
* @param LoggerInterface $logger
* @param iLogger $logger
*
* @return $this
*/
public function setLogger(LoggerInterface $logger): self;
public function setLogger(iLogger $logger): self;

/**
* Get DBLayer instance.
Expand Down
20 changes: 14 additions & 6 deletions src/Libs/Database/PDO/PDOAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ final class PDOAdapter implements iDB
*/
private bool $viaTransaction = false;

/**
* @var array Adapter options.
*/
private array $options = [];

/**
* @var array<array-key, PDOStatement> Prepared statements.
*/
Expand All @@ -49,8 +44,21 @@ final class PDOAdapter implements iDB
* @param iLogger $logger The logger object used for logging.
* @param DBLayer $db The PDO object used for database connections.
*/
public function __construct(private iLogger $logger, private readonly DBLayer $db)
public function __construct(private iLogger $logger, private readonly DBLayer $db, private array $options = [])
{
}

public function with(iLogger|null $logger = null, DBLayer|null $db = null, array|null $options = null): self
{
if (null === $logger && null === $db && null === $options) {
return $this;
}
return new self($logger ?? $this->logger, $db ?? $this->db, $options ?? $this->options);
}

public function withOptions(array $options): self
{
return $this->with(options: $options);
}

/**
Expand Down
45 changes: 45 additions & 0 deletions src/Libs/Mappers/ExtendedImportInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace App\Libs\Mappers;

use App\Libs\Database\DatabaseInterface as iDB;
use Psr\Log\LoggerInterface as iLogger;
use Psr\SimpleCache\CacheInterface as iCache;

interface ExtendedImportInterface extends ImportInterface
{
/**
* Set the database connection. and return the instance
*
* @param iDB $db Database connection
* @return self Instance of the class
*/
public function withDB(iDB $db): self;

/**
* Set the cache connection. and return the instance
*
* @param iCache $cache Cache connection
* @return self Instance of the class
*/
public function withCache(iCache $cache): self;

/**
* Set the logger connection. and return the instance
*
* @param iLogger $logger Logger connection
* @return self Instance of the class
*/
public function withLogger(iLogger $logger): self;

/**
* Compute the play state for each backend.
*
* @param array $backends List of backends to check.
*
* @return array List of changes for each backend.
*/
public function computeChanges(array $backends): array;
}
40 changes: 39 additions & 1 deletion src/Libs/Mappers/Import/DirectMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use App\Libs\Container;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Mappers\ImportInterface as iImport;
use App\Libs\Mappers\ExtendedImportInterface as iImport;
use App\Libs\Message;
use App\Libs\Options;
use App\Listeners\ProcessProgressEvent;
Expand Down Expand Up @@ -80,6 +80,36 @@ public function __construct(protected iLogger $logger, protected iDB $db, protec
{
}

/**
* @inheritdoc
*/
public function withDB(iDB $db): self
{
$instance = clone $this;
$instance->db = $db;
return $instance;
}

/**
* @inheritdoc
*/
public function withCache(iCache $cache): self
{
$instance = clone $this;
$instance->cache = $cache;
return $instance;
}

/**
* @inheritdoc
*/
public function withLogger(iLogger $logger): self
{
$instance = clone $this;
$instance->logger = $logger;
return $instance;
}

/**
* @inheritdoc
*/
Expand Down Expand Up @@ -958,6 +988,14 @@ public function getChangedList(): array
return $this->changed;
}

/**
* @inheritdoc
*/
public function computeChanges(array $backends): array
{
return [];
}

/**
* Adds pointers to the entity.
*
Expand Down
Loading

0 comments on commit 624ebb1

Please sign in to comment.