PHRAS-3519_upload-tmp-then-move

implement atomic (?) "tmp+move" method on uploaded file
add traces of document filesize
This commit is contained in:
jygaulier
2021-09-07 15:48:49 +02:00
parent 88a6506ded
commit d225b381e4
5 changed files with 106 additions and 12 deletions

View File

@@ -34,6 +34,8 @@ use Alchemy\Phrasea\Model\Entities\LazaretSession;
use PHPExiftool\Driver\Metadata\Metadata; use PHPExiftool\Driver\Metadata\Metadata;
use PHPExiftool\Driver\Value\Mono as MonoValue; use PHPExiftool\Driver\Value\Mono as MonoValue;
use PHPExiftool\Driver\Value\Multi; use PHPExiftool\Driver\Value\Multi;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/** /**
* Phraseanet Border Manager * Phraseanet Border Manager
@@ -381,12 +383,27 @@ class Manager
sprintf("calling replaceMetadata") sprintf("calling replaceMetadata")
), FILE_APPEND | LOCK_EX); ), FILE_APPEND | LOCK_EX);
/** @var EventDispatcherInterface $dispatcher */
$dispatcher = $this->app['dispatcher'];
$dispatcher->addListener(
RecordEvents::METADATA_CHANGED,
function (Event $event) {
// we do not want replaceMetadata() to send a writemeta
// file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
// sprintf("---------- event METADATA_CHANGED catched !!! Propagation stopped !!!")
// ), FILE_APPEND | LOCK_EX);
// $event->stopPropagation();
},
10
);
/** @var PhraseanetMetadataSetter $phraseanetMetadataSetter */ /** @var PhraseanetMetadataSetter $phraseanetMetadataSetter */
$phraseanetMetadataSetter = $this->app['phraseanet.metadata-setter']; $phraseanetMetadataSetter = $this->app['phraseanet.metadata-setter'];
$phraseanetMetadataSetter->replaceMetadata($newMetadata, $element); $phraseanetMetadataSetter->replaceMetadata($newMetadata, $element);
if(!$nosubdef) { if(!$nosubdef) {
$this->app['dispatcher']->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($element, true)); $dispatcher->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($element, true));
} }
return $element; return $element;

View File

@@ -142,6 +142,17 @@ class FilesystemService
return $realPath; return $realPath;
} }
/**
* rename file from source to target
*
* @param string $source
* @param string $target
*/
public function rename($source, $target)
{
$this->filesystem->rename($source, $target, true);
}
/** /**
* Copy file from source to target * Copy file from source to target
* *

View File

@@ -12,27 +12,27 @@ namespace Alchemy\Phrasea\Media;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Application\Helper\DispatcherAware; use Alchemy\Phrasea\Application\Helper\DispatcherAware;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreatedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreatedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreationEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationFailedEvent;
use Alchemy\Phrasea\Core\Event\Record\RecordEvents; use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreatedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationFailedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreatedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreationEvent;
use Alchemy\Phrasea\Databox\Subdef\MediaSubdefRepository; use Alchemy\Phrasea\Databox\Subdef\MediaSubdefRepository;
use Alchemy\Phrasea\Filesystem\FilesystemService; use Alchemy\Phrasea\Filesystem\FilesystemService;
use Alchemy\Phrasea\Media\Subdef\Specification\PdfSpecification; use Alchemy\Phrasea\Media\Subdef\Specification\PdfSpecification;
use MediaAlchemyst\Alchemyst; use MediaAlchemyst\Alchemyst;
use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException;
use MediaAlchemyst\Exception\FileNotFoundException;
use MediaAlchemyst\Specification\Image; use MediaAlchemyst\Specification\Image;
use MediaAlchemyst\Specification\Video; use MediaAlchemyst\Specification\Video;
use MediaVorus\Exception\FileNotFoundException as MediaVorusFileNotFoundException;
use MediaVorus\MediaVorus; use MediaVorus\MediaVorus;
use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException;
use Neutron\TemporaryFilesystem\Manager; use Neutron\TemporaryFilesystem\Manager;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Unoconv\Exception\ExceptionInterface as UnoconvException; use Unoconv\Exception\ExceptionInterface as UnoconvException;
use Unoconv\Exception\RuntimeException; use Unoconv\Exception\RuntimeException;
use Unoconv\Unoconv; use Unoconv\Unoconv;
use MediaVorus\Exception\FileNotFoundException as MediaVorusFileNotFoundException;
use MediaAlchemyst\Exception\FileNotFoundException;
class SubdefGenerator class SubdefGenerator
{ {
@@ -107,6 +107,15 @@ class SubdefGenerator
) )
); );
if(!is_null($hd = $record->get_hd_file())) {
$hd = $hd->getRealPath();
clearstatcache(true, $hd);
file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("creating subdefs for %s.%s from document \"%s\" (size=%s)", $record->getDataboxId(), $record->getRecordId(), $hd, filesize($hd))
), FILE_APPEND | LOCK_EX);
}
$mediaCreated = []; $mediaCreated = [];
foreach ($subdefs as $subdef) { foreach ($subdefs as $subdef) {
$subdefname = $subdef->get_name(); $subdefname = $subdef->get_name();
@@ -118,7 +127,13 @@ class SubdefGenerator
$pathdest = null; $pathdest = null;
if ($record->has_subdef($subdefname) && $record->get_subdef($subdefname)->is_physically_present()) { if ($record->has_subdef($subdefname) && $record->get_subdef($subdefname)->is_physically_present()) {
$pathdest = $record->get_subdef($subdefname)->getRealPath(); $pathdest = $record->get_subdef($subdefname)->getRealPath();
file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("deleting previous subdef \"%s\" (file=\"%s\") for %s.%s", $subdefname, $pathdest, $record->getDataboxId(), $record->getRecordId())
), FILE_APPEND | LOCK_EX);
$record->get_subdef($subdefname)->remove_file(); $record->get_subdef($subdefname)->remove_file();
$this->logger->info(sprintf('Removed old file for %s', $subdefname)); $this->logger->info(sprintf('Removed old file for %s', $subdefname));
$record->clearSubdefCache($subdefname); $record->clearSubdefCache($subdefname);

View File

@@ -96,8 +96,37 @@ class PhraseanetMetadataSetter
sprintf("calling set_metadatas for %s.%s", $record->getDataboxId(), $record->getRecordId()) sprintf("calling set_metadatas for %s.%s", $record->getDataboxId(), $record->getRecordId())
), FILE_APPEND | LOCK_EX); ), FILE_APPEND | LOCK_EX);
$record->set_metadatas($metadataInRecordFormat, true); /*
* todo : tryout to write meta AFTER meta was written in db by set_metadatas()
* how : uncomment section
*
*/
/*
$this->dispatcher->addListener(
RecordEvents::METADATA_CHANGED,
function () use ($record) {
// order to write meta in file
file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("dispatch WorkerEvents::RECORDS_WRITE_META for %s.%s", $record->getDataboxId(), $record->getRecordId())
), FILE_APPEND | LOCK_EX);
// this event will add a msg to the writemeta q
$this->dispatcher->dispatch(WorkerEvents::RECORDS_WRITE_META,
new RecordsWriteMetaEvent([$record->getRecordId()], $record->getDataboxId()));
},
0
);
*/
/*
* end of section to uncomment
*/
$record->set_metadatas($metadataInRecordFormat, true); // will send METADATA_CHANGED when done
/*
* todo : tryout to write meta AFTER meta was written in db by set_metadatas()
* how : comment section
*
*/
// order to write meta in file // order to write meta in file
file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__, file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("dispatch WorkerEvents::RECORDS_WRITE_META for %s.%s", $record->getDataboxId(), $record->getRecordId()) sprintf("dispatch WorkerEvents::RECORDS_WRITE_META for %s.%s", $record->getDataboxId(), $record->getRecordId())
@@ -105,6 +134,9 @@ class PhraseanetMetadataSetter
$this->dispatcher->dispatch(WorkerEvents::RECORDS_WRITE_META, $this->dispatcher->dispatch(WorkerEvents::RECORDS_WRITE_META,
new RecordsWriteMetaEvent([$record->getRecordId()], $record->getDataboxId())); new RecordsWriteMetaEvent([$record->getRecordId()], $record->getDataboxId()));
/*
* end of section to comment
*/
} }
else { else {

View File

@@ -1700,12 +1700,31 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$pathhd = $filesystem->generateDataboxDocumentBasePath($databox); $pathhd = $filesystem->generateDataboxDocumentBasePath($databox);
$newname = $filesystem->generateDocumentFilename($record, $file->getFile()); $newname = $filesystem->generateDocumentFilename($record, $file->getFile());
$newname_tmp = $newname.".tmp";
clearstatcache(true, $file->getFile()->getRealPath());
file_put_contents(dirname(__FILE__).'/../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__, file_put_contents(dirname(__FILE__).'/../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("copy \"%s\" to \"%s\"", $file->getFile()->getRealPath(), $pathhd . $newname) sprintf("copying \"%s\" (size=%s) to \"%s\"", $file->getFile()->getRealPath(), filesize($file->getFile()->getRealPath()), $pathhd . $newname_tmp)
), FILE_APPEND | LOCK_EX);
$filesystem->copy($file->getFile()->getRealPath(), $pathhd . $newname_tmp);
clearstatcache(true, $pathhd . $newname_tmp);
file_put_contents(dirname(__FILE__).'/../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("copied \"%s\" to \"%s\" (size=%s)", $file->getFile()->getRealPath(), $pathhd . $newname_tmp, filesize($pathhd . $newname_tmp))
), FILE_APPEND | LOCK_EX);
file_put_contents(dirname(__FILE__).'/../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("moving \"%s\" (size=%s) to \"%s\"", $pathhd . $newname_tmp, filesize($pathhd . $newname_tmp), $pathhd . $newname)
), FILE_APPEND | LOCK_EX);
$filesystem->rename($pathhd . $newname_tmp, $pathhd . $newname);
clearstatcache(true, $pathhd . $newname);
file_put_contents(dirname(__FILE__).'/../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("moved \"%s\"to \"%s\" (size=%s) ", $pathhd . $newname_tmp, $pathhd . $newname, filesize($pathhd . $newname))
), FILE_APPEND | LOCK_EX); ), FILE_APPEND | LOCK_EX);
$filesystem->copy($file->getFile()->getRealPath(), $pathhd . $newname);
$media = $app->getMediaFromUri($pathhd . $newname); $media = $app->getMediaFromUri($pathhd . $newname);
media_subdef::create($app, $record, 'document', $media); media_subdef::create($app, $record, 'document', $media);