Docker-S3DB/syncer/AbstractSyncer.php

138 lines
4.4 KiB
PHP

<?php
namespace S3DB\Sync;
use League\Flysystem\FileAttributes;
use Monolog\Logger;
use Rych\ByteSize\ByteSize;
use S3DB\Sync\Filesystems\LocalFilesystem;
use S3DB\Sync\Filesystems\StorageFilesystem;
use Spatie\Emoji\Emoji;
use Westsworld\TimeAgo;
abstract class AbstractSyncer
{
public function __construct(
protected Logger $logger,
protected StorageFilesystem $storageFilesystem,
protected LocalFilesystem $localFilesystem
) {
}
abstract public function push();
abstract public function pull();
protected function download(): string
{
$filesInS3 = $this->storageFilesystem->listContents('/')->toArray();
usort($filesInS3, function (FileAttributes $a, FileAttributes $b) {
return $a->lastModified() < $b->lastModified();
});
/** @var FileAttributes $file */
foreach ($filesInS3 as $file) {
$this->logger->debug(sprintf(
'%s Found %s. It is %s and was created %s',
Emoji::magnifyingGlassTiltedLeft(),
$file->path(),
ByteSize::formatMetric(
$file->fileSize()
),
(new TimeAgo())->inWords((new \DateTime())->setTimestamp($file->lastModified()))
));
}
// Choose which we're downloadin'
$latest = $filesInS3[0];
$this->logger->debug(sprintf(
'%s Selecting %s... Downloading %s...',
Emoji::downArrow(),
$latest->path(),
ByteSize::formatMetric($latest->fileSize())
));
$localDownloadedFile = basename($latest->path());
$this->localFilesystem->writeStream(
$localDownloadedFile,
$this->storageFilesystem->readStream(
$latest->path()
)
);
return $localDownloadedFile;
}
protected function upload(string $remoteStorageFile, string $localCompressedDumpFile): void
{
$startUpload = microtime(true);
$this->storageFilesystem->writeStream(
$remoteStorageFile,
$this->localFilesystem->readStream($localCompressedDumpFile)
);
$this->logger->debug(sprintf(
'Uploaded %s as %s to S3 in %s seconds',
$localCompressedDumpFile,
$remoteStorageFile,
number_format(microtime(true) - $startUpload, 3)
));
}
protected function cleanup(array $files): void
{
$cumulativeBytes = 0;
foreach ($files as $file) {
$cumulativeBytes += $this->localFilesystem->fileSize($file);
$this->localFilesystem->delete($file);
}
$this->logger->debug(sprintf(
'%s Cleanup: Deleted %d files, freed %s',
Emoji::wastebasket(),
count($files),
ByteSize::formatMetric($cumulativeBytes)
));
}
protected function compress(string $file): string
{
$startCompression = microtime(true);
passthru(sprintf('xz -f -T0 -6 /dumps/%s', $file));
$compressedFile = "{$file}.xz";
$this->logger->debug(sprintf(
'%s Dump file was made, and is %s compressed in %s seconds',
Emoji::computerDisk(),
ByteSize::formatMetric(
$this->localFilesystem->fileSize($compressedFile)
),
number_format(microtime(true) - $startCompression, 3)
));
return $compressedFile;
}
protected function decompress(string $compressedFile): string
{
$startDecompression = microtime(true);
if (!substr($compressedFile, -3, 3) == '.xz') {
$this->logger->critical(sprintf(
'%s Compressed file %s does not end in .xz',
Emoji::explodingHead(),
$compressedFile
));
exit;
}
$uncompressedFile = substr($compressedFile, 0, -3);
passthru(sprintf('xz -d -f /dumps/%s', $compressedFile));
$this->logger->debug(sprintf(
'%s Dump file %s was uncompressed from %s to %s in %s seconds',
Emoji::computerDisk(),
$uncompressedFile,
ByteSize::formatMetric($this->storageFilesystem->fileSize($compressedFile)),
ByteSize::formatMetric($this->localFilesystem->fileSize($uncompressedFile)),
number_format(microtime(true) - $startDecompression, 3)
));
return $uncompressedFile;
}
}