mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-28 18:43:49 +00:00
Feature: [docgen] generate documents in an async queue
The documents are now generated in a queue, using symfony messenger. This queue should be configured: ```yaml # app/config/messenger.yaml framework: messenger: # reset services after consuming messages # reset_on_message: true failure_transport: failed transports: # https://symfony.com/doc/current/messenger.html#transport-configuration async: '%env(MESSENGER_TRANSPORT_DSN)%' priority: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' failed: 'doctrine://default?queue_name=failed' routing: # ... other messages 'Chill\DocGeneratorBundle\Service\Messenger\RequestGenerationMessage': priority ``` `StoredObject`s now have additionnal properties: * status (pending, failure, ready (by default) ), which explain if the document is generated; * a generationTrialCounter, which is incremented on each generation trial, which prevent each generation more than 5 times; The generator computation is moved from the `DocGenTemplateController` to a `Generator` (implementing `GeneratorInterface`. There are new methods to `Context` which allow to normalize/denormalize context data to/from a messenger's `Message`.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
// this file loads all assets from the Chill person bundle
|
||||
module.exports = function(encore, entries)
|
||||
{
|
||||
module.exports = function(encore, entries) {
|
||||
encore.addEntry('page_wopi_editor', __dirname + '/src/Resources/public/page/editor/index.js');
|
||||
//home/julien/dev/département-vendee/chill/vendor/chill-project/chill-bundles/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js
|
||||
encore.addEntry('mod_reload_page', __dirname + '/src/Resources/public/module/pending/index');
|
||||
};
|
||||
|
@@ -26,6 +26,10 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
use Twig\Environment;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -35,6 +39,8 @@ final class Editor
|
||||
{
|
||||
private DocumentManagerInterface $documentManager;
|
||||
|
||||
private EngineInterface $engine;
|
||||
|
||||
private JWTTokenManagerInterface $JWTTokenManager;
|
||||
|
||||
private Psr17Interface $psr17;
|
||||
@@ -49,18 +55,24 @@ final class Editor
|
||||
|
||||
private DiscoveryInterface $wopiDiscovery;
|
||||
|
||||
private NormalizerInterface $normalizer;
|
||||
|
||||
public function __construct(
|
||||
ConfigurationInterface $wopiConfiguration,
|
||||
DiscoveryInterface $wopiDiscovery,
|
||||
DocumentManagerInterface $documentManager,
|
||||
EngineInterface $engine,
|
||||
JWTTokenManagerInterface $JWTTokenManager,
|
||||
NormalizerInterface $normalizer,
|
||||
ResponderInterface $responder,
|
||||
Security $security,
|
||||
Psr17Interface $psr17,
|
||||
RouterInterface $router
|
||||
) {
|
||||
$this->documentManager = $documentManager;
|
||||
$this->engine = $engine;
|
||||
$this->JWTTokenManager = $JWTTokenManager;
|
||||
$this->normalizer = $normalizer;
|
||||
$this->wopiConfiguration = $wopiConfiguration;
|
||||
$this->wopiDiscovery = $wopiDiscovery;
|
||||
$this->responder = $responder;
|
||||
@@ -87,6 +99,22 @@ final class Editor
|
||||
throw new NotFoundHttpException(sprintf('Unable to find object %s', $fileId));
|
||||
}
|
||||
|
||||
if (StoredObject::STATUS_FAILURE === $storedObject->getStatus()) {
|
||||
return new Response(
|
||||
$this->engine
|
||||
->render('@ChillWopi/Editor/stored_object_failure.html.twig')
|
||||
);
|
||||
} elseif (StoredObject::STATUS_PENDING === $storedObject->getStatus()) {
|
||||
return new Response(
|
||||
$this->engine
|
||||
->render('@ChillWopi/Editor/stored_object_pending.html.twig', [
|
||||
'storedObject' => $this->normalizer->normalize($storedObject, 'json', [
|
||||
AbstractNormalizer::GROUPS => ['read']
|
||||
])
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
if ([] === $discoverExtension = $this->wopiDiscovery->discoverMimeType($storedObject->getType())) {
|
||||
throw new Exception(sprintf('Unable to find mime type %s', $storedObject->getType()));
|
||||
}
|
||||
|
@@ -0,0 +1,40 @@
|
||||
import {is_object_ready} from "../../../../../../ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers";
|
||||
import {
|
||||
StoredObject,
|
||||
StoredObjectStatus,
|
||||
StoredObjectStatusChange
|
||||
} from "../../../../../../ChillDocStoreBundle/Resources/public/types";
|
||||
|
||||
async function reload_if_needed(stored_object: StoredObject, i: number): Promise<void> {
|
||||
let current_status = await is_object_ready(stored_object);
|
||||
|
||||
if (stored_object.status !== current_status.status) {
|
||||
window.location.reload();
|
||||
}
|
||||
wait_before_reload(stored_object, i + 1);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
function wait_before_reload(stored_object: StoredObject, i: number): void {
|
||||
/**
|
||||
* value of the timeout. Set to 5 sec during the first 10 minutes, then every 1 minute
|
||||
*/
|
||||
let timeout = i < 1200 ? 5000 : 60000;
|
||||
|
||||
setTimeout(
|
||||
reload_if_needed,
|
||||
timeout,
|
||||
stored_object,
|
||||
i
|
||||
);
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', async function (e) {
|
||||
if (undefined === (<any>window).stored_object) {
|
||||
console.error('window.stored_object is undefined');
|
||||
throw Error('window.stored_object is undefined');
|
||||
}
|
||||
|
||||
let stored_object = JSON.parse((<any>window).stored_object) as StoredObject;
|
||||
reload_if_needed(stored_object, 0);
|
||||
});
|
@@ -0,0 +1,15 @@
|
||||
{% extends 'ChillMainBundle::layout.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="alert alert-danger">
|
||||
{{ 'docgen.Doc generation failed'|trans }}
|
||||
</div>
|
||||
|
||||
<ul class="sticky-form-buttons record_actions">
|
||||
<li class="cancel">
|
||||
<a href="{{ chill_return_path_or('chill_main_homepage') }}" class="btn btn-cancel">
|
||||
{{ 'Cancel'|trans|chill_return_path_label }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endblock %}
|
@@ -0,0 +1,36 @@
|
||||
{% extends '@ChillMain/layout.html.twig' %}
|
||||
|
||||
{% block js %}
|
||||
<script type="application/javascript">
|
||||
window.stored_object = '{{ storedObject|json_encode|escape('js') }}'
|
||||
</script>
|
||||
{{ encore_entry_script_tags('mod_reload_page') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('mod_reload_page') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="alert alert-danger text-center">
|
||||
<div>
|
||||
<p>
|
||||
{{ 'docgen.Doc generation is pending'|trans }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<i class="fa fa-cog fa-spin fa-3x fa-fw"></i>
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<ul class="sticky-form-buttons record_actions">
|
||||
<li class="cancel">
|
||||
<a href="{{ chill_return_path_or('chill_main_homepage') }}" class="btn btn-cancel">
|
||||
{{ 'docgen.Come back later'|trans|chill_return_path_label }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endblock content %}
|
Reference in New Issue
Block a user